awa
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# coding: utf-8
|
||||
|
||||
import re
|
||||
from loguru import logger
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
from PyQt6.QtGui import QPixmap
|
||||
@@ -8,7 +9,7 @@ from qfluentwidgets import Action, BodyLabel, CardWidget, ImageLabel, InfoBar, I
|
||||
MessageBox, PushButton, RoundMenu, StrongBodyLabel
|
||||
from qfluentwidgets import FluentIcon as FIF
|
||||
|
||||
from app.core import (DeleteFileThread, formatDate, formatSize, getFileIcon, lang, signalBus)
|
||||
from app.core import (DeleteFileThread, RenameFileThread, formatDate, formatSize, getFileIcon, lang, signalBus)
|
||||
from app.view.widgets.share_file_messageBox import ShareFileMessageBox
|
||||
|
||||
|
||||
@@ -132,6 +133,9 @@ class FileCard(CardWidget):
|
||||
Action(
|
||||
FIF.PROJECTOR, lang("预览"), triggered=lambda: self.selfPreview()
|
||||
),
|
||||
Action(
|
||||
FIF.EDIT, lang("重命名"), triggered=lambda: self.renameSelf()
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -151,6 +155,9 @@ class FileCard(CardWidget):
|
||||
menu.addActions(
|
||||
[
|
||||
Action(FIF.DOWNLOAD, lang("进入"), triggered=lambda: self.dirClicked()),
|
||||
Action(
|
||||
FIF.EDIT, lang("重命名"), triggered=lambda: self.renameSelf()
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -171,31 +178,47 @@ class FileCard(CardWidget):
|
||||
)
|
||||
if w.exec():
|
||||
# 构建Cloudreve V4 API所需的正确路径格式
|
||||
if self.filePath == "/":
|
||||
# 确保路径格式规范,避免Path not exist错误
|
||||
# 只使用路径中的目录部分,不包含文件名,确保不会重复
|
||||
dir_path = self.filePath
|
||||
if dir_path == "/":
|
||||
# 根目录情况
|
||||
full_path = f"cloudreve://my/{self.fileName}"
|
||||
else:
|
||||
# 子目录情况,确保正确拼接路径
|
||||
# 清理路径,避免重复的斜杠和前缀
|
||||
clean_path = self.filePath.lstrip("/")
|
||||
# 确保路径中不包含cloudreve://my前缀
|
||||
clean_path = clean_path.replace("cloudreve://my/", "")
|
||||
full_path = f"cloudreve://my/{clean_path}/{self.fileName}"
|
||||
# 子目录情况,确保只使用目录路径
|
||||
# 清理路径,移除协议前缀
|
||||
clean_dir = dir_path
|
||||
if clean_dir.startswith("cloudreve://my/"):
|
||||
clean_dir = clean_dir[15:] # 移除 "cloudreve://my/"
|
||||
elif clean_dir.startswith("/"):
|
||||
clean_dir = clean_dir[1:] # 移除前导斜杠
|
||||
|
||||
# 确保路径格式正确,移除重复的前缀
|
||||
full_path = full_path.replace("cloudreve://my/cloudreve://my", "cloudreve://my")
|
||||
# 确保路径中间没有多余的斜杠
|
||||
clean_dir = '/'.join([part for part in clean_dir.split('/') if part])
|
||||
|
||||
# 更健壮地处理重复文件名的情况
|
||||
# 分割路径并去重
|
||||
# 构建完整URI,只包含目录路径和文件名一次
|
||||
full_path = f"cloudreve://my/{clean_dir}/{self.fileName}"
|
||||
|
||||
# 检查并移除可能的重复文件名部分
|
||||
# 避免同时包含编码形式和原始形式的文件名
|
||||
import re
|
||||
# 查找可能的编码形式+原始形式的重复模式
|
||||
path_parts = full_path.split('/')
|
||||
if len(path_parts) > 1:
|
||||
# 检查最后一个部分是否是文件名
|
||||
if path_parts[-1] == self.fileName:
|
||||
# 检查倒数第二个部分是否也是文件名
|
||||
if len(path_parts) > 2 and path_parts[-2] == self.fileName:
|
||||
# 移除重复的文件名部分
|
||||
path_parts.pop(-2)
|
||||
full_path = '/'.join(path_parts)
|
||||
if len(path_parts) > 3:
|
||||
# 检查最后两个部分是否可能是编码和原始形式的关系
|
||||
potential_encoding = path_parts[-2]
|
||||
original = path_parts[-1]
|
||||
# 如果倒数第二个部分看起来像URL编码且最后一个部分是中文
|
||||
if re.match(r'^%[0-9A-Fa-f]{2}%[0-9A-Fa-f]{2}%[0-9A-Fa-f]{2}%[0-9A-Fa-f]{2}$', potential_encoding) and any('\u4e00'-'\u9fff' in c for c in original):
|
||||
# 移除倒数第二个部分,避免重复
|
||||
path_parts.pop(-2)
|
||||
full_path = '/'.join(path_parts)
|
||||
|
||||
# 最终清理
|
||||
full_path = full_path.replace("//", "/") # 移除多余的斜杠
|
||||
|
||||
# 记录构建的路径用于调试
|
||||
print(f"[DEBUG] 重命名路径: {full_path}")
|
||||
|
||||
self.deleteThread = DeleteFileThread(full_path, self.fileType)
|
||||
self.deleteThread.successDelete.connect(self.deleteSuccess)
|
||||
@@ -235,6 +258,162 @@ class FileCard(CardWidget):
|
||||
self.window(),
|
||||
)
|
||||
logger.error(f"删除文件失败:{error_msg}")
|
||||
|
||||
def renameSelf(self):
|
||||
"""重命名文件或文件夹"""
|
||||
# 使用输入对话框获取新名称
|
||||
from qfluentwidgets import LineEdit, MessageBoxBase, SubtitleLabel
|
||||
from PyQt6.QtCore import Qt
|
||||
import re
|
||||
|
||||
# 创建自定义对话框
|
||||
class RenameMessageBox(MessageBoxBase):
|
||||
"""自定义重命名对话框"""
|
||||
|
||||
def __init__(self, parent=None, initial_name=""):
|
||||
super().__init__(parent)
|
||||
self.titleLabel = SubtitleLabel(f"{lang("请输入新名称")}:")
|
||||
self.lineEdit = LineEdit()
|
||||
self.lineEdit.setText(initial_name)
|
||||
|
||||
# 选择文件名部分(不包括扩展名)
|
||||
if "." in initial_name:
|
||||
name_part = initial_name.rsplit(".", 1)[0]
|
||||
self.lineEdit.setSelection(0, len(name_part))
|
||||
else:
|
||||
self.lineEdit.selectAll()
|
||||
|
||||
# 将组件添加到布局中
|
||||
self.viewLayout.addWidget(self.titleLabel)
|
||||
self.viewLayout.addWidget(self.lineEdit)
|
||||
|
||||
# 设置对话框的最小宽度
|
||||
self.widget.setMinimumWidth(400)
|
||||
|
||||
# 设置窗口标题
|
||||
self.setWindowTitle(lang("重命名"))
|
||||
|
||||
# 创建并显示对话框
|
||||
dlg = RenameMessageBox(self.window(), self.fileName)
|
||||
if dlg.exec():
|
||||
new_name = dlg.lineEdit.text().strip()
|
||||
|
||||
# 验证文件名
|
||||
if not new_name:
|
||||
InfoBar.warning(
|
||||
lang("警告"),
|
||||
lang("文件名不能为空"),
|
||||
Qt.Orientation.Horizontal,
|
||||
True,
|
||||
1000,
|
||||
InfoBarPosition.TOP_RIGHT,
|
||||
self.window(),
|
||||
)
|
||||
return
|
||||
|
||||
# 检查文件名是否包含无效字符
|
||||
if re.search(r'[<>"/\\|?*]', new_name):
|
||||
InfoBar.warning(
|
||||
lang("警告"),
|
||||
lang("文件名包含无效字符"),
|
||||
Qt.Orientation.Horizontal,
|
||||
True,
|
||||
1000,
|
||||
InfoBarPosition.TOP_RIGHT,
|
||||
self.window(),
|
||||
)
|
||||
return
|
||||
|
||||
# 检查文件名是否与当前目录中的其他文件重复
|
||||
# 获取当前目录下的所有文件名称
|
||||
current_folder = self.filePath
|
||||
# 从父窗口获取文件列表(假设父窗口有fileList属性)
|
||||
parent_window = self.window()
|
||||
if hasattr(parent_window, 'fileList'):
|
||||
# 遍历文件列表,检查是否有相同名称的文件(排除当前正在重命名的文件)
|
||||
for file_item in parent_window.fileList:
|
||||
# 跳过当前正在重命名的文件
|
||||
if hasattr(file_item, 'fileName') and file_item.fileName == self.fileName:
|
||||
continue
|
||||
# 检查是否有同名文件
|
||||
if hasattr(file_item, 'fileName') and file_item.fileName == new_name:
|
||||
InfoBar.warning(
|
||||
lang("警告"),
|
||||
lang("文件名已存在"),
|
||||
Qt.Orientation.Horizontal,
|
||||
True,
|
||||
1000,
|
||||
InfoBarPosition.TOP_RIGHT,
|
||||
self.window(),
|
||||
)
|
||||
return
|
||||
|
||||
# 构建Cloudreve V4 API所需的正确路径格式
|
||||
# 确保路径格式规范,避免Path not exist错误
|
||||
# 只使用路径中的目录部分,不包含文件名
|
||||
if self.filePath == "/":
|
||||
# 根目录情况,URI只包含根目录路径
|
||||
full_path = "cloudreve://my" # 直接使用正确的双斜杠格式
|
||||
else:
|
||||
# 子目录情况,确保只使用目录路径,不包含文件名
|
||||
# 清理路径,移除协议前缀
|
||||
clean_path = self.filePath
|
||||
if clean_path.startswith("cloudreve://my/"):
|
||||
clean_path = clean_path[15:] # 移除 "cloudreve://my/"
|
||||
elif clean_path.startswith("/"):
|
||||
clean_path = clean_path[1:] # 移除前导斜杠
|
||||
|
||||
# 构建完整URI,只包含目录路径
|
||||
full_path = f"cloudreve://my/{clean_path}" # 直接使用正确的双斜杠格式
|
||||
|
||||
# 强制确保协议前缀格式正确,使用双斜杠
|
||||
# 直接替换所有可能的单斜杠格式
|
||||
full_path = full_path.replace("cloudreve:/my", "cloudreve://my")
|
||||
full_path = full_path.replace("cloudreve:/", "cloudreve://")
|
||||
# 再次确认格式完全正确
|
||||
if not full_path.startswith("cloudreve://"):
|
||||
# 如果格式仍然不正确,重新构建整个URI
|
||||
path_part = full_path.replace("cloudreve:", "").lstrip("/")
|
||||
full_path = f"cloudreve://{path_part}"
|
||||
|
||||
# 不再需要处理文件名重复,因为URI中只包含目录路径
|
||||
|
||||
# 最终清理
|
||||
full_path = full_path.replace("//", "/") # 移除多余的斜杠
|
||||
|
||||
# 记录构建的路径用于调试
|
||||
print(f"[DEBUG] 重命名路径: {full_path}")
|
||||
|
||||
# 调用重命名线程
|
||||
self.renameThread = RenameFileThread(full_path, new_name, self.fileType)
|
||||
self.renameThread.successRename.connect(self.renameSuccess)
|
||||
self.renameThread.errorRename.connect(self.renameError)
|
||||
self.renameThread.start()
|
||||
|
||||
def renameSuccess(self):
|
||||
InfoBar.success(
|
||||
lang("成功"),
|
||||
lang("重命名成功"),
|
||||
Qt.Orientation.Horizontal,
|
||||
True,
|
||||
1000,
|
||||
InfoBarPosition.TOP_RIGHT,
|
||||
self.window(),
|
||||
)
|
||||
# 刷新文件夹列表
|
||||
signalBus.refreshFolderListSignal.emit()
|
||||
|
||||
def renameError(self, error_msg):
|
||||
InfoBar.error(
|
||||
lang("失败"),
|
||||
f"{lang("重命名失败")}: {error_msg}",
|
||||
Qt.Orientation.Horizontal,
|
||||
True,
|
||||
1000,
|
||||
InfoBarPosition.TOP_RIGHT,
|
||||
self.window(),
|
||||
)
|
||||
logger.error(f"重命名文件失败:{error_msg}")
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
"""重写上下文菜单事件,确保只有右键点击才会触发"""
|
||||
|
||||
Reference in New Issue
Block a user