Rename send as a file with extension.

This commit is contained in:
John Preston
2026-04-28 20:50:59 +07:00
parent 6aa406901c
commit 2cfdf1b32e
6 changed files with 290 additions and 98 deletions
+85 -28
View File
@@ -113,9 +113,12 @@ void FileDialogCallback(
callback(std::move(*list));
}
} // namespace
void RenameFileBox(
not_null<Ui::GenericBox*> box,
const QString &currentName,
bool allowExtensionEdit,
Fn<void(QString)> apply) {
box->setTitle(tr::lng_rename_file());
const auto field = box->addRow(object_ptr<Ui::InputField>(
@@ -123,19 +126,25 @@ void RenameFileBox(
st::settingsDeviceName,
rpl::single(QString()),
currentName));
const auto extension = [&] {
if (currentName.isEmpty()) {
return u".png"_q;
}
const auto dot = currentName.lastIndexOf('.');
return (dot >= 0) ? currentName.mid(dot) : QString();
}();
const auto nameWithoutExt = extension.isEmpty()
? currentName
: currentName.left(currentName.size() - extension.size());
const auto maxNameLength = kMaxDisplayNameLength - extension.size();
field->setMaxLength((maxNameLength > 0) ? maxNameLength : 0);
field->setText(nameWithoutExt);
QString extension;
if (allowExtensionEdit) {
field->setMaxLength(kMaxDisplayNameLength);
field->setText(currentName);
} else {
extension = [&] {
if (currentName.isEmpty()) {
return u".png"_q;
}
const auto dot = currentName.lastIndexOf('.');
return (dot >= 0) ? currentName.mid(dot) : QString();
}();
const auto nameWithoutExt = extension.isEmpty()
? currentName
: currentName.left(currentName.size() - extension.size());
const auto maxNameLength = kMaxDisplayNameLength - extension.size();
field->setMaxLength((maxNameLength > 0) ? maxNameLength : 0);
field->setText(nameWithoutExt);
}
field->selectAll();
box->setFocusCallback([=] {
field->setFocusFast();
@@ -146,12 +155,18 @@ void RenameFileBox(
field->showError();
return;
}
if ((newName.size() + extension.size()) > kMaxDisplayNameLength) {
if (allowExtensionEdit) {
if (newName.size() > kMaxDisplayNameLength) {
field->showError();
return;
}
} else if ((newName.size() + extension.size())
> kMaxDisplayNameLength) {
field->showError();
return;
}
const auto weak = base::make_weak(box);
apply(newName + extension);
apply(allowExtensionEdit ? newName : (newName + extension));
if (const auto strong = weak.get()) {
strong->closeBox();
}
@@ -165,6 +180,8 @@ void RenameFileBox(
});
}
namespace {
void EditFileCaptionBox(
not_null<Ui::GenericBox*> box,
const style::ComposeControls &st,
@@ -416,11 +433,13 @@ SendFilesBox::Block::Block(
media->setCanShowHighQualityBadge(first.canUseHighQualityPhoto());
_preview.reset(media);
} else {
_preview.reset(Ui::CreateChild<Ui::SingleFilePreview>(
const auto single = Ui::CreateChild<Ui::SingleFilePreview>(
parent.get(),
st,
first,
captionContext));
captionContext);
single->setRenameEnabled(!SkipCaption(first, way));
_preview.reset(single);
}
}
_preview->show();
@@ -492,6 +511,19 @@ rpl::producer<int> SendFilesBox::Block::itemModifyRequest() const {
}
}
rpl::producer<int> SendFilesBox::Block::itemRenameRequest() const {
using namespace rpl::mappers;
const auto preview = _preview.get();
const auto from = _from;
if (_isAlbum || _isSingleMedia) {
return rpl::never<int>();
} else {
const auto single = static_cast<Ui::SingleFilePreview*>(preview);
return single->renameRequests() | rpl::map_to(from);
}
}
rpl::producer<> SendFilesBox::Block::orderUpdated() const {
if (_isAlbum) {
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
@@ -506,6 +538,10 @@ void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) {
const auto media = static_cast<Ui::SingleMediaPreview*>(
_preview.get());
media->setSendWay(way);
} else {
const auto single = static_cast<Ui::SingleFilePreview*>(
_preview.get());
single->setRenameEnabled(!SkipCaption((*_items)[_from], way));
}
return;
}
@@ -1467,6 +1503,32 @@ void SendFilesBox::pushBlock(int from, int till) {
entry.videoCover = nullptr;
});
};
const auto renameFile = [=](int fileIndex) {
if (fileIndex < 0 || fileIndex >= _list.files.size()) {
return;
}
const auto &file = _list.files[fileIndex];
const auto canEditFileData = !SkipCaption(
file,
_sendWay.current());
if (!canEditFileData) {
return;
}
const auto allowExtensionEdit = file.path.isEmpty();
_show->show(Box(
RenameFileBox,
file.displayName,
allowExtensionEdit,
[=](QString newName) {
const auto displayName = std::move(newName);
_list.files[fileIndex].displayName = displayName;
if (!setDisplayNameInSingleFilePreview(
fileIndex,
displayName)) {
refreshAllAfterChanges(from);
}
}));
};
const auto showContextMenu = [=](
int fileIndex,
QPoint globalPosition,
@@ -1501,17 +1563,7 @@ void SendFilesBox::pushBlock(int from, int till) {
_sendWay.current());
if (canEditFileData) {
state->menu->addAction(tr::lng_rename_file(tr::now), [=] {
auto &file = _list.files[fileIndex];
_show->show(Box(RenameFileBox, file.displayName, [=](
QString newName) {
const auto displayName = std::move(newName);
_list.files[fileIndex].displayName = displayName;
if (!setDisplayNameInSingleFilePreview(
fileIndex,
displayName)) {
refreshAllAfterChanges(from);
}
}));
renameFile(fileIndex);
}, &st::menuIconEdit);
state->menu->addAction(
tr::lng_context_upload_edit_caption(tr::now),
@@ -1626,6 +1678,11 @@ void SendFilesBox::pushBlock(int from, int till) {
openInPhotoEditor(index);
}, widget->lifetime());
block.itemRenameRequest(
) | rpl::on_next([=](int index) {
renameFile(index);
}, widget->lifetime());
block.orderUpdated() | rpl::on_next([=]{
if (_priceTag) {
_priceTagBg = QImage();