26#include <QtCore/QDate>
27#include <QtCore/QFileInfo>
28#include <QtGui/QCheckBox>
29#include <QtGui/QLabel>
30#include <QtGui/QLayout>
31#include <QtGui/QPixmap>
32#include <QtGui/QScrollArea>
33#include <QtGui/QScrollBar>
34#include <QtGui/QApplication>
35#include <QtGui/QDesktopWidget>
61class RenameDialog::RenameDialogPrivate
64 RenameDialogPrivate() {
66 bRename = bSkip = bOverwrite = 0;
67 bResume = bSuggestNewName = 0;
70 m_srcPendingPreview =
false;
71 m_destPendingPreview =
false;
76 void setRenameBoxText(
const QString& fileName) {
79 m_pLineEdit->setText(fileName);
81 if (!extension.isEmpty()) {
82 const int selectionLength = fileName.length() - extension.length() - 1;
83 m_pLineEdit->setSelection(0, selectionLength);
85 m_pLineEdit->selectAll();
99 bool m_srcPendingPreview;
100 bool m_destPendingPreview;
103 QScrollArea* m_srcArea;
104 QScrollArea* m_destArea;
110 const KUrl &_src,
const KUrl &_dest,
118 :
QDialog(parent), d(new RenameDialogPrivate)
120 setObjectName(
"KIO::RenameDialog");
125 setWindowTitle(_caption);
128 connect(d->bCancel, SIGNAL(clicked()),
this, SLOT(
cancelPressed()));
131 d->bApplyAll =
new QCheckBox(
i18n(
"Appl&y to All"),
this);
132 d->bApplyAll->setToolTip((_mode &
M_ISDIR) ?
i18n(
"When this is checked the button pressed will be applied to all subsequent folder conflicts for the remainder of the current job.\nUnless you press Skip you will still be prompted in case of a conflict with an existing file in the directory.")
133 :
i18n(
"When this is checked the button pressed will be applied to all subsequent conflicts for the remainder of the current job."));
134 connect(d->bApplyAll, SIGNAL(clicked()),
this, SLOT(applyAllPressed()));
139 d->bRename->setEnabled(
false);
142 connect(d->bRename, SIGNAL(clicked()),
this, SLOT(
renamePressed()));
147 d->bSkip->setToolTip((_mode &
M_ISDIR) ?
i18n(
"Do not copy or move this folder, skip to the next item instead")
148 :
i18n(
"Do not copy or move this file, skip to the next item instead"));
149 connect(d->bSkip, SIGNAL(clicked()),
this, SLOT(
skipPressed()));
153 const QString text = (_mode &
M_ISDIR) ?
i18nc(
"Write files into an existing folder",
"&Write Into") :
i18n(
"&Overwrite");
155 d->bOverwrite->setToolTip(
i18n(
"Files and folders will be copied into the existing directory, alongside its existing contents.\nYou will be prompted again in case of a conflict with an existing file in the directory."));
161 connect(d->bResume, SIGNAL(clicked()),
this, SLOT(
resumePressed()));
164 QVBoxLayout* pLayout =
new QVBoxLayout(
this);
165 pLayout->addStrut(400);
169 QLabel *lb =
new QLabel(
i18n(
"This action would overwrite '%1' with itself.\n"
170 "Please enter a new file name:",
173 d->bRename->setText(
i18n(
"C&ontinue"));
174 pLayout->addWidget(lb);
176 if (d->src.isLocalFile()) {
189 if (d->dest.isLocalFile()) {
199 d->destItem =
KFileItem(destUds, d->dest);
202 d->m_srcPreview = createLabel(parent, QString(),
false);
203 d->m_destPreview = createLabel(parent, QString(),
false);
208 d->m_srcPreview->setAlignment(Qt::AlignCenter);
209 d->m_destPreview->setAlignment(Qt::AlignCenter);
211 d->m_srcPendingPreview =
true;
212 d->m_destPendingPreview =
true;
215 d->m_srcArea = createContainerLayout(parent, d->srcItem, d->m_srcPreview);
216 d->m_destArea = createContainerLayout(parent, d->destItem, d->m_destPreview);
218 connect(d->m_srcArea->verticalScrollBar(), SIGNAL(valueChanged(
int)), d->m_destArea->verticalScrollBar(), SLOT(setValue(
int)));
219 connect(d->m_destArea->verticalScrollBar(), SIGNAL(valueChanged(
int)), d->m_srcArea->verticalScrollBar(), SLOT(setValue(
int)));
220 connect(d->m_srcArea->horizontalScrollBar(), SIGNAL(valueChanged(
int)), d->m_destArea->horizontalScrollBar(), SLOT(setValue(
int)));
221 connect(d->m_destArea->horizontalScrollBar(), SIGNAL(valueChanged(
int)), d->m_srcArea->horizontalScrollBar(), SLOT(setValue(
int)));
224 QGridLayout* gridLayout =
new QGridLayout();
225 pLayout->addLayout(gridLayout);
227 QLabel* titleLabel =
new QLabel(
i18n(
"This action will overwrite the destination."),
this);
229 QLabel* srcTitle = createLabel(parent,
i18n(
"Source"),
true);
230 QLabel* destTitle = createLabel(parent,
i18n(
"Destination"),
true);
232 QLabel* srcInfo = createSqueezedLabel(parent, d->src.pathOrUrl());
233 QLabel* destInfo = createSqueezedLabel(parent, d->dest.pathOrUrl());
235 if (mtimeDest > mtimeSrc) {
236 QLabel* warningLabel =
new QLabel(
i18n(
"Warning, the destination is more recent."),
this);
238 gridLayout->addWidget(titleLabel, 0, 0, 1, 2);
239 gridLayout->addWidget(warningLabel, 1, 0, 1, 2);
240 gridLayout->setRowMinimumHeight(2, 15);
242 gridLayout->addWidget(srcTitle, 3, 0);
243 gridLayout->addWidget(srcInfo, 4, 0);
244 gridLayout->addWidget(d->m_srcArea, 5, 0);
246 gridLayout->addWidget(destTitle, 3, 1);
247 gridLayout->addWidget(destInfo, 4, 1);
248 gridLayout->addWidget(d->m_destArea, 5, 1);
250 gridLayout->addWidget(titleLabel, 0, 0, 1, 2);
251 gridLayout->setRowMinimumHeight(1, 15);
253 gridLayout->addWidget(srcTitle, 2, 0);
254 gridLayout->addWidget(srcInfo, 3, 0);
255 gridLayout->addWidget(d->m_srcArea, 4, 0);
257 gridLayout->addWidget(destTitle, 2, 1);
258 gridLayout->addWidget(destInfo, 3, 1);
259 gridLayout->addWidget(d->m_destArea, 4, 1);
266 if (mtimeDest < mtimeSrc)
267 sentence1 =
i18n(
"An older item named '%1' already exists.", d->dest.pathOrUrl());
268 else if (mtimeDest == mtimeSrc)
269 sentence1 =
i18n(
"A similar file named '%1' already exists.", d->dest.pathOrUrl());
271 sentence1 =
i18n(
"A more recent item named '%1' already exists.", d->dest.pathOrUrl());
274 pLayout->addWidget(lb);
279 pLayout->addSpacing(15);
283 pLayout->addWidget(lb2);
286 QHBoxLayout* layout2 =
new QHBoxLayout();
287 pLayout->addLayout(layout2);
290 layout2->addWidget(d->m_pLineEdit);
293 const QString fileName = d->dest.fileName();
296 connect(d->m_pLineEdit, SIGNAL(textChanged(QString)),
299 d->m_pLineEdit->setFocus();
301 d->m_pLineEdit->hide();
304 if (d->bSuggestNewName) {
305 layout2->addWidget(d->bSuggestNewName);
306 setTabOrder(d->m_pLineEdit, d->bSuggestNewName);
310 pLayout->addWidget(separator);
312 QHBoxLayout* layout =
new QHBoxLayout();
313 pLayout->addLayout(layout);
315 layout->addStretch(1);
318 layout->addWidget(d->bApplyAll);
319 setTabOrder(d->bApplyAll, d->bCancel);
323 layout->addWidget(d->bRename);
324 setTabOrder(d->bRename, d->bCancel);
328 layout->addWidget(d->bSkip);
329 setTabOrder(d->bSkip, d->bCancel);
333 layout->addWidget(d->bOverwrite);
334 setTabOrder(d->bOverwrite, d->bCancel);
338 layout->addWidget(d->bResume);
339 setTabOrder(d->bResume, d->bCancel);
342 d->bCancel->setDefault(
true);
343 layout->addWidget(d->bCancel);
357 d->bRename->setEnabled(
true);
358 d->bRename->setDefault(
true);
361 d->bOverwrite->setEnabled(
false);
364 d->bRename->setEnabled(
false);
367 d->bOverwrite->setEnabled(
true);
374 KUrl newDest(d->dest);
375 QString fileName = d->m_pLineEdit->text();
384 KUrl newDest(d->dest);
385 KUrl destDirectory(d->dest);
401 if (d->m_pLineEdit->text().isEmpty()) {
405 if (d->bApplyAll && d->bApplyAll->isChecked()) {
421 QString dotSuffix, suggestedName;
422 QString basename = oldName;
423 const QChar spacer(
' ');
426 int index = basename.indexOf(
'.');
428 while (continous == index) {
429 index = basename.indexOf(
'.', index + 1);
434 dotSuffix = basename.mid(index);
435 basename.truncate(index);
438 int pos = basename.lastIndexOf(spacer);
441 QString tmp = basename.mid(pos + 1);
446 suggestedName = basename + spacer +
'1' + dotSuffix;
449 basename.replace(pos + 1, tmp.length(), QString::number(
number + 1));
450 suggestedName = basename + dotSuffix;
453 suggestedName = basename + spacer +
"1" + dotSuffix ;
463 return suggestedName;
472 if (d->m_pLineEdit->text().isEmpty())
475 KUrl destDirectory(d->dest);
478 d->setRenameBoxText(
suggestName(destDirectory, d->m_pLineEdit->text()));
485 if (d->bApplyAll && d->bApplyAll->isChecked()) {
499 if (d->bApplyAll && d->bApplyAll->isChecked()) {
513 if (d->bApplyAll && d->bApplyAll->isChecked()) {
525void RenameDialog::applyAllPressed()
527 if (d->bApplyAll && d->bApplyAll->isChecked()) {
529 d->m_pLineEdit->setEnabled(
false);
532 d->bRename->setEnabled(
true);
535 if (d->bSuggestNewName) {
536 d->bSuggestNewName->setEnabled(
false);
539 d->m_pLineEdit->setEnabled(
true);
542 d->bRename->setEnabled(
false);
545 if (d->bSuggestNewName) {
546 d->bSuggestNewName->setEnabled(
true);
551void RenameDialog::showSrcIcon(
const KFileItem& fileitem)
554 d->m_srcPendingPreview =
false;
555 d->m_srcPreview->setPixmap(fileitem.
pixmap(d->m_srcPreview->height()));
558void RenameDialog::showDestIcon(
const KFileItem& fileitem)
561 d->m_destPendingPreview =
false;
562 d->m_destPreview->setPixmap(fileitem.
pixmap(d->m_srcPreview->height()));
565void RenameDialog::showSrcPreview(
const KFileItem& fileitem,
const QPixmap& pixmap)
569 if (d->m_srcPendingPreview) {
570 d->m_srcPreview->setPixmap(pixmap);
571 d->m_srcPendingPreview =
false;
575void RenameDialog::showDestPreview(
const KFileItem& fileitem,
const QPixmap& pixmap)
579 if (d->m_destPendingPreview) {
580 d->m_destPreview->setPixmap(pixmap);
581 d->m_destPendingPreview =
false;
585void RenameDialog::resizePanels()
588 QSize screenSize = QApplication::desktop()->availableGeometry(
this).size();
589 QSize halfSize = d->m_srcArea->widget()->sizeHint().expandedTo(d->m_destArea->widget()->sizeHint());
590 QSize currentSize = d->m_srcArea->size().expandedTo(d->m_destArea->size());
591 int maxHeightPossible = screenSize.height() - (size().height() - currentSize.height());
592 QSize maxHalfSize = QSize(screenSize.width() / qreal(2.1), maxHeightPossible * qreal(0.9));
594 if (halfSize.height() > maxHalfSize.height() &&
595 halfSize.width() <= maxHalfSize.width() + d->m_srcArea->verticalScrollBar()->width())
597 halfSize.rwidth() += d->m_srcArea->verticalScrollBar()->width();
598 maxHalfSize.rwidth() += d->m_srcArea->verticalScrollBar()->width();
601 d->m_srcArea->setMinimumSize(halfSize.boundedTo(maxHalfSize));
602 d->m_destArea->setMinimumSize(halfSize.boundedTo(maxHalfSize));
605 QSize(d->m_srcPreview->width() * qreal(0.9), d->m_srcPreview->height()));
609 QSize(d->m_destPreview->width() * qreal(0.9), d->m_destPreview->height()));
612 connect(srcJob, SIGNAL(gotPreview(
KFileItem,QPixmap)),
613 this, SLOT(showSrcPreview(
KFileItem,QPixmap)));
614 connect(destJob, SIGNAL(gotPreview(
KFileItem,QPixmap)),
615 this, SLOT(showDestPreview(
KFileItem,QPixmap)));
616 connect(srcJob, SIGNAL(failed(
KFileItem)),
618 connect(destJob, SIGNAL(failed(
KFileItem)),
632 connect(metaWidget, SIGNAL(metaDataRequestFinished(
KFileItemList)),
this, SLOT(resizePanels()));
639 QVBoxLayout* containerLayout =
new QVBoxLayout(widgetContainer);
641 containerLayout->setContentsMargins(0, 0, 0, 0);
642 containerLayout->setSpacing(0);
643 containerLayout->addWidget(preview);
644 containerLayout->addWidget(metaWidget);
645 containerLayout->addStretch(1);
647 QScrollArea* metaDataArea =
new QScrollArea(parent);
649 metaDataArea->setWidget(widgetContainer);
650 metaDataArea->setWidgetResizable(
true);
651 metaDataArea->setFrameShape(QFrame::NoFrame);
656QLabel* RenameDialog::createLabel(
QWidget* parent,
const QString& text,
bool containerTitle)
660 if (containerTitle) {
661 QFont font =
label->font();
663 label->setFont(font);
666 label->setAlignment(Qt::AlignHCenter);
667 label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
668 label->setText(text);
677 label->setAlignment(Qt::AlignHCenter);
678 label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
683#include "renamedialog.moc"
List of KFileItems, which adds a few helper methods to QList<KFileItem>.
A KFileItem is a generic class to handle a file, local or remote.
QPixmap pixmap(int _size, int _state=0) const
Returns a pixmap representing the file.
KIO Job to get a thumbnail picture.
void setScaleType(ScaleType type)
Sets the scale type for the generated preview.
@ Unscaled
The original size of the preview will be returned.
Universal Directory Service.
@ UDS_CREATION_TIME
The time the file was created.
@ UDS_MODIFICATION_TIME
The last time the file was modified.
@ UDS_SIZE
Size of the file.
@ UDS_NAME
Filename - as displayed in directory listings etc.
void insert(uint field, const QString &value)
insert field with numeric value
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
static QString extractKnownExtension(const QString &fileName)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
void setFileName(const QString &_txt)
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
void setPath(const QString &path)
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
QString i18n(const char *text)
QString i18nc(const char *ctxt, const char *text)
A namespace for KIO globals.
QString encodeFileName(const QString &str)
Encodes (from the text displayed to the real filename) This translates '/' into a "unicode fraction s...
QString decodeFileName(const QString &str)
Decodes (from the filename to the text displayed) This doesn't do anything anymore,...
PreviewJob * filePreview(const KFileItemList &items, int width, int height=0, int iconSize=0, int iconAlpha=70, bool scale=true, bool save=true, const QStringList *enabledPlugins=0)
Creates a PreviewJob to generate or retrieve a preview image for the given URL.
RenameDialog_Mode
M_OVERWRITE: We have an existing dest, show details about it and offer to overwrite it.
qulonglong filesize_t
64-bit file size
QString number(KIO::filesize_t size)
Converts a size to a string representation Not unlike QString::number(...)
QString label(StandardShortcut id)
QString csqueeze(const QString &str, int maxlen=40)