Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2006-2010 Peter Penz <peter.penz@gmx.at>
|
||||
SPDX-FileCopyrightText: 2020 Méven Car <meven.car@kdemail.net>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "renamefiledialog.h"
|
||||
|
||||
#include <KGuiItem>
|
||||
#include <KIO/BatchRenameJob>
|
||||
#include <KIO/CopyJob>
|
||||
#include <KIO/FileUndoManager>
|
||||
#include <KJobUiDelegate>
|
||||
#include <KJobWidgets>
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMimeDatabase>
|
||||
#include <QPushButton>
|
||||
#include <QShowEvent>
|
||||
#include <QSpinBox>
|
||||
|
||||
namespace KIO
|
||||
{
|
||||
class Q_DECL_HIDDEN RenameFileDialog::RenameFileDialogPrivate
|
||||
{
|
||||
public:
|
||||
RenameFileDialogPrivate(const KFileItemList &items)
|
||||
: lineEdit(nullptr)
|
||||
, items(items)
|
||||
, spinBox(nullptr)
|
||||
, renameOneItem(false)
|
||||
, allExtensionsDifferent(true)
|
||||
{
|
||||
}
|
||||
|
||||
QList<QUrl> renamedItems;
|
||||
QLineEdit *lineEdit;
|
||||
KFileItemList items;
|
||||
QSpinBox *spinBox;
|
||||
QPushButton *okButton;
|
||||
bool renameOneItem;
|
||||
bool allExtensionsDifferent;
|
||||
};
|
||||
|
||||
RenameFileDialog::RenameFileDialog(const KFileItemList &items, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, d(new RenameFileDialogPrivate(items))
|
||||
{
|
||||
setMinimumWidth(320);
|
||||
|
||||
const int itemCount = items.count();
|
||||
Q_ASSERT(itemCount >= 1);
|
||||
d->renameOneItem = (itemCount == 1);
|
||||
|
||||
setWindowTitle(d->renameOneItem ? i18nc("@title:window", "Rename Item") : i18nc("@title:window", "Rename Items"));
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
d->okButton = buttonBox->button(QDialogButtonBox::Ok);
|
||||
d->okButton->setDefault(true);
|
||||
d->okButton->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Return));
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &RenameFileDialog::slotAccepted);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &RenameFileDialog::reject);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QObject::deleteLater);
|
||||
d->okButton->setDefault(true);
|
||||
|
||||
KGuiItem::assign(d->okButton, KGuiItem(i18nc("@action:button", "&Rename"), QStringLiteral("dialog-ok-apply")));
|
||||
|
||||
QWidget *page = new QWidget(this);
|
||||
mainLayout->addWidget(page);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
QVBoxLayout *topLayout = new QVBoxLayout(page);
|
||||
|
||||
QLabel *editLabel = nullptr;
|
||||
QString newName;
|
||||
if (d->renameOneItem) {
|
||||
newName = items.first().name();
|
||||
editLabel = new QLabel(xi18nc("@label:textbox", "Rename the item <filename>%1</filename> to:", newName), page);
|
||||
editLabel->setTextFormat(Qt::PlainText);
|
||||
} else {
|
||||
newName = i18nc("This a template for new filenames, # is replaced by a number later, must be the end character", "New name #");
|
||||
editLabel = new QLabel(i18ncp("@label:textbox", "Rename the %1 selected item to:", "Rename the %1 selected items to:", itemCount), page);
|
||||
}
|
||||
|
||||
d->lineEdit = new QLineEdit(page);
|
||||
mainLayout->addWidget(d->lineEdit);
|
||||
connect(d->lineEdit, &QLineEdit::textChanged, this, &RenameFileDialog::slotTextChanged);
|
||||
|
||||
int selectionLength = newName.length();
|
||||
if (d->renameOneItem) {
|
||||
// If the current item is a directory, select the whole file name.
|
||||
if (!items.first().isDir()) {
|
||||
QMimeDatabase db;
|
||||
const QString extension = db.suffixForFileName(items.first().name());
|
||||
if (extension.length() > 0) {
|
||||
// Don't select the extension
|
||||
selectionLength -= extension.length() + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Don't select the # character
|
||||
--selectionLength;
|
||||
}
|
||||
|
||||
d->lineEdit->setText(newName);
|
||||
d->lineEdit->setSelection(0, selectionLength);
|
||||
|
||||
topLayout->addWidget(editLabel);
|
||||
topLayout->addWidget(d->lineEdit);
|
||||
|
||||
if (!d->renameOneItem) {
|
||||
QMimeDatabase db;
|
||||
QSet<QString> extensions;
|
||||
for (const KFileItem &item : std::as_const(d->items)) {
|
||||
const QString extension = db.suffixForFileName(item.name());
|
||||
|
||||
if (extensions.contains(extension)) {
|
||||
d->allExtensionsDifferent = false;
|
||||
break;
|
||||
}
|
||||
|
||||
extensions.insert(extension);
|
||||
}
|
||||
|
||||
QLabel *infoLabel = new QLabel(i18nc("@info", "# will be replaced by ascending numbers starting with:"), page);
|
||||
mainLayout->addWidget(infoLabel);
|
||||
d->spinBox = new QSpinBox(page);
|
||||
d->spinBox->setMinimum(0);
|
||||
d->spinBox->setMaximum(1'000'000'000);
|
||||
d->spinBox->setSingleStep(1);
|
||||
d->spinBox->setValue(1);
|
||||
d->spinBox->setDisplayIntegerBase(10);
|
||||
|
||||
QHBoxLayout *horizontalLayout = new QHBoxLayout;
|
||||
horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
horizontalLayout->addWidget(infoLabel);
|
||||
horizontalLayout->addWidget(d->spinBox);
|
||||
|
||||
topLayout->addLayout(horizontalLayout);
|
||||
}
|
||||
|
||||
d->lineEdit->setFocus();
|
||||
}
|
||||
|
||||
RenameFileDialog::~RenameFileDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void RenameFileDialog::slotAccepted()
|
||||
{
|
||||
QWidget *widget = parentWidget();
|
||||
if (!widget) {
|
||||
widget = this;
|
||||
}
|
||||
|
||||
const QList<QUrl> srcList = d->items.urlList();
|
||||
const QString newName = d->lineEdit->text();
|
||||
KIO::FileUndoManager::CommandType cmdType;
|
||||
KIO::Job *job = nullptr;
|
||||
if (d->renameOneItem) {
|
||||
Q_ASSERT(d->items.count() == 1);
|
||||
cmdType = KIO::FileUndoManager::Rename;
|
||||
const QUrl oldUrl = d->items.constFirst().url();
|
||||
QUrl newUrl = oldUrl.adjusted(QUrl::RemoveFilename);
|
||||
newUrl.setPath(newUrl.path() + KIO::encodeFileName(newName));
|
||||
d->renamedItems << newUrl;
|
||||
job = KIO::moveAs(oldUrl, newUrl, KIO::HideProgressInfo);
|
||||
} else {
|
||||
d->renamedItems.reserve(d->items.count());
|
||||
cmdType = KIO::FileUndoManager::BatchRename;
|
||||
job = KIO::batchRename(srcList, newName, d->spinBox->value(), QLatin1Char('#'));
|
||||
connect(qobject_cast<KIO::BatchRenameJob *>(job), &KIO::BatchRenameJob::fileRenamed, this, &RenameFileDialog::slotFileRenamed);
|
||||
}
|
||||
|
||||
KJobWidgets::setWindow(job, widget);
|
||||
const QUrl parentUrl = srcList.first().adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash);
|
||||
KIO::FileUndoManager::self()->recordJob(cmdType, srcList, parentUrl, job);
|
||||
|
||||
connect(job, &KJob::result, this, &RenameFileDialog::slotResult);
|
||||
connect(job, &KJob::result, this, &QObject::deleteLater);
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
void RenameFileDialog::slotTextChanged(const QString &newName)
|
||||
{
|
||||
bool enable = !newName.isEmpty() && (newName != QLatin1String("..")) && (newName != QLatin1String("."));
|
||||
if (enable && !d->renameOneItem) {
|
||||
const int count = newName.count(QLatin1Char('#'));
|
||||
if (count == 0) {
|
||||
// Renaming multiple files without '#' will only work if all extensions are different.
|
||||
enable = d->allExtensionsDifferent;
|
||||
} else {
|
||||
// Ensure that the new name contains exactly one # (or a connected sequence of #'s)
|
||||
const int first = newName.indexOf(QLatin1Char('#'));
|
||||
const int last = newName.lastIndexOf(QLatin1Char('#'));
|
||||
enable = (last - first + 1 == count);
|
||||
}
|
||||
}
|
||||
d->okButton->setEnabled(enable);
|
||||
}
|
||||
|
||||
void RenameFileDialog::slotFileRenamed(const QUrl &oldUrl, const QUrl &newUrl)
|
||||
{
|
||||
Q_UNUSED(oldUrl)
|
||||
d->renamedItems << newUrl;
|
||||
}
|
||||
|
||||
void RenameFileDialog::slotResult(KJob *job)
|
||||
{
|
||||
if (!job->error()) {
|
||||
Q_EMIT renamingFinished(d->renamedItems);
|
||||
} else {
|
||||
Q_EMIT error(job);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KIO
|
||||
|
||||
#include "moc_renamefiledialog.cpp"
|
||||
Reference in New Issue
Block a user