--- scribus/ui/stylemanager.cpp +++ scribus/ui/stylemanager.cpp @@ -5,11 +5,21 @@ for which a new license (GPL+exception) is in place. */ +#include #include +#include +#include #include +#include +#include #include -#include #include +#include +#include +#include +#include +#include +#include #include "commonstrings.h" #include "fileloader.h" @@ -537,7 +547,13 @@ slotOk(); int totalUnused = 0; - QStringList unusedSummary; + + struct UnusedStyleEntry + { + QString typeName; + QString styleName; + }; + QList unusedStyles; struct ItemDeletion { @@ -579,7 +595,7 @@ if (!usedMap->contains(styleName)) { removeList.append(RemoveItem(styleName, QString())); - unusedSummary << QString(" %1: %2").arg(styleitem->typeName(), styleName); + unusedStyles.append({styleitem->typeName(), styleName}); } } @@ -592,20 +608,70 @@ if (totalUnused == 0) { - ScMessageBox::information(this, tr("Remove Unused Styles"), - tr("All styles in this document are in use. Nothing to remove.")); + ScMessageBox::information(this, tr("Delete Unused Styles"), + tr("All styles in this document are in use. Nothing to delete.")); return; } - // Confirmation dialog - QString message = tr("Found %1 unused style(s):\n\n").arg(totalUnused); - message += unusedSummary.join("\n"); - message += "\n\n"; - message += tr("Remove all unused styles?"); - - int result = ScMessageBox::question(this, tr("Remove Unused Styles"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + QDialog dialog(this); + dialog.setWindowTitle(tr("Delete Unused Styles")); + dialog.setSizeGripEnabled(true); + + QVBoxLayout* layout = new QVBoxLayout(&dialog); + + QLabel* summaryLabel = new QLabel(tr("%n unused style(s) found.", nullptr, totalUnused), &dialog); + layout->addWidget(summaryLabel); + + QLabel* detailLabel = new QLabel(tr("The following styles are not used by any object in the document:"), &dialog); + detailLabel->setWordWrap(true); + layout->addWidget(detailLabel); + + QTreeWidget* unusedStyleList = new QTreeWidget(&dialog); + unusedStyleList->setHeaderLabels(QStringList() << tr("Type") << tr("Style")); + unusedStyleList->setRootIsDecorated(false); + unusedStyleList->setAlternatingRowColors(true); + unusedStyleList->setSelectionMode(QAbstractItemView::NoSelection); + unusedStyleList->setUniformRowHeights(true); + unusedStyleList->setMinimumHeight(180); + unusedStyleList->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + for (int i = 0; i < unusedStyles.count(); ++i) + { + QTreeWidgetItem* row = new QTreeWidgetItem(unusedStyleList); + row->setText(0, unusedStyles.at(i).typeName); + row->setText(1, unusedStyles.at(i).styleName); + } + + QHeaderView* unusedStyleListHeader = unusedStyleList->header(); + unusedStyleListHeader->setSectionResizeMode(QHeaderView::Interactive); + unusedStyleListHeader->setStretchLastSection(false); + unusedStyleList->resizeColumnToContents(0); + unusedStyleList->setColumnWidth(0, qMax(120, unusedStyleList->columnWidth(0))); + unusedStyleList->setColumnWidth(1, qMax(320, unusedStyleList->columnWidth(1))); + layout->addWidget(unusedStyleList); + + QLabel* warningLabel = new QLabel(tr("Delete all listed styles?"), &dialog); + warningLabel->setWordWrap(true); + layout->addWidget(warningLabel); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); + buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Delete Styles")); + connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); + layout->addWidget(buttonBox); + + const QScreen* dialogScreen = screen(); + if (dialogScreen) + { + const QRect availableGeometry = dialogScreen->availableGeometry(); + const int dialogWidth = qMin(qMax(560, availableGeometry.width() / 2), qMax(320, availableGeometry.width() - 80)); + const int dialogHeight = qMin(520, qMax(280, availableGeometry.height() - 120)); + dialog.resize(dialogWidth, dialogHeight); + } + else + dialog.resize(560, 520); - if (result != QMessageBox::Yes) + if (dialog.exec() != QDialog::Accepted) return; // Delete through each StyleItem — modifies temp copies only