9#include "utils/configurethemesdialog.h"
10#include "utils/configurethemesdialog_p.h"
12#include "core/theme.h"
13#include "utils/themeeditor.h"
15#include "core/manager.h"
23#include <KConfigGroup>
24#include <KLocalizedString>
26#include <QDialogButtonBox>
39 ThemeListWidgetItem(
QListWidget *par,
const Core::Theme &set)
42 mTheme =
new Core::Theme(set);
45 ~ThemeListWidgetItem()
override
50 [[nodiscard]] Core::Theme *theme()
const
61 Core::Theme *mTheme =
nullptr;
74 [[nodiscard]]
QSize sizeHint()
const override
83using namespace MessageList::Utils;
85ConfigureThemesDialog::ConfigureThemesDialog(
QWidget *parent)
87 , d(new ConfigureThemesDialogPrivate(this))
96 setWindowTitle(
i18nc(
"@title:window",
"Customize Themes"));
99 mainLayout->addWidget(base);
100 mainLayout->addWidget(buttonBox);
103 g->setContentsMargins({});
105 d->mThemeList =
new ThemeListWidget(base);
107 d->mThemeList->setSortingEnabled(
true);
108 g->addWidget(d->mThemeList, 0, 0, 7, 1);
111 d->themeListItemClicked(item);
114 d->themeListItemClicked(item);
117 d->mNewThemeButton =
new QPushButton(
i18nc(
"@action:button",
"New Theme"), base);
118 d->mNewThemeButton->setIcon(
QIcon::fromTheme(QStringLiteral(
"document-new")));
119 g->addWidget(d->mNewThemeButton, 0, 1);
122 d->newThemeButtonClicked();
125 d->mCloneThemeButton =
new QPushButton(
i18nc(
"@action:button",
"Clone Theme"), base);
126 d->mCloneThemeButton->setIcon(
QIcon::fromTheme(QStringLiteral(
"edit-copy")));
127 g->addWidget(d->mCloneThemeButton, 1, 1);
130 d->cloneThemeButtonClicked();
133 auto f =
new QFrame(base);
135 f->setMinimumHeight(24);
138 d->mExportThemeButton =
new QPushButton(
i18nc(
"@action:button",
"Export Theme..."), base);
139 g->addWidget(d->mExportThemeButton, 3, 1);
142 d->exportThemeButtonClicked();
145 d->mImportThemeButton =
new QPushButton(
i18nc(
"@action:button",
"Import Theme..."), base);
146 g->addWidget(d->mImportThemeButton, 4, 1);
148 d->importThemeButtonClicked();
153 f->setMinimumHeight(24);
156 d->mDeleteThemeButton =
new QPushButton(
i18nc(
"@action:button",
"Delete Theme"), base);
157 d->mDeleteThemeButton->setIcon(
QIcon::fromTheme(QStringLiteral(
"edit-delete")));
158 g->addWidget(d->mDeleteThemeButton, 6, 1);
161 d->deleteThemeButtonClicked();
164 d->mEditor =
new ThemeEditor(base);
165 g->addWidget(d->mEditor, 8, 0, 1, 2);
167 connect(d->mEditor, &ThemeEditor::themeNameChanged,
this, [
this]() {
168 d->editedThemeNameChanged();
171 g->setColumnStretch(0, 1);
172 g->setRowStretch(4, 1);
175 d->okButtonClicked();
181ConfigureThemesDialog::~ConfigureThemesDialog() =
default;
183void ConfigureThemesDialog::selectTheme(
const QString &themeId)
185 ThemeListWidgetItem *item = d->findThemeItemById(themeId);
187 d->mThemeList->setCurrentItem(item);
188 d->themeListItemClicked(item);
192void ConfigureThemesDialog::ConfigureThemesDialogPrivate::okButtonClicked()
196 Manager::instance()->removeAllThemes();
198 const int c = mThemeList->count();
201 auto item =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->item(i));
203 Manager::instance()->addTheme(item->theme());
209 Manager::instance()->themesConfigurationCompleted();
210 Q_EMIT q->okClicked();
214void ConfigureThemesDialog::ConfigureThemesDialogPrivate::commitEditor()
216 Theme *editedTheme = mEditor->editedTheme();
223 ThemeListWidgetItem *editedItem = findThemeItemByTheme(editedTheme);
232 QString goodName = uniqueNameForTheme(editedTheme->
name(), editedTheme);
233 editedTheme->
setName(goodName);
237void ConfigureThemesDialog::ConfigureThemesDialogPrivate::editedThemeNameChanged()
239 Theme *set = mEditor->editedTheme();
244 ThemeListWidgetItem *it = findThemeItemByTheme(set);
249 QString goodName = uniqueNameForTheme(set->
name(), set);
254void ConfigureThemesDialog::ConfigureThemesDialogPrivate::fillThemeList()
260 (void)
new ThemeListWidgetItem(mThemeList, *(*it));
264void ConfigureThemesDialog::ConfigureThemesDialogPrivate::themeListItemClicked(
QListWidgetItem *cur)
268 const int numberOfSelectedItem(mThemeList->selectedItems().count());
270 ThemeListWidgetItem *item = cur ?
dynamic_cast<ThemeListWidgetItem *
>(cur) : nullptr;
271 mDeleteThemeButton->setEnabled(item && !item->theme()->readOnly());
272 mCloneThemeButton->setEnabled(numberOfSelectedItem == 1);
273 mEditor->editTheme(item ? item->theme() :
nullptr);
274 mExportThemeButton->setEnabled(numberOfSelectedItem > 0);
281ThemeListWidgetItem *ConfigureThemesDialog::ConfigureThemesDialogPrivate::findThemeItemById(
const QString &themeId)
283 const int c = mThemeList->count();
286 auto item =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->item(i));
288 if (item->theme()->
id() == themeId) {
297ThemeListWidgetItem *ConfigureThemesDialog::ConfigureThemesDialogPrivate::findThemeItemByName(
const QString &name,
Theme *skipTheme)
299 const int c = mThemeList->count();
302 auto item =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->item(i));
304 if (item->theme() != skipTheme) {
305 if (item->theme()->
name() == name) {
315ThemeListWidgetItem *ConfigureThemesDialog::ConfigureThemesDialogPrivate::findThemeItemByTheme(
Theme *set)
317 const int c = mThemeList->count();
320 auto item =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->item(i));
322 if (item->theme() == set) {
331QString ConfigureThemesDialog::ConfigureThemesDialogPrivate::uniqueNameForTheme(
const QString &baseName,
Theme *skipTheme)
335 ret =
i18n(
"Unnamed Theme");
340 ThemeListWidgetItem *item = findThemeItemByName(ret, skipTheme);
344 item = findThemeItemByName(ret, skipTheme);
349void ConfigureThemesDialog::ConfigureThemesDialogPrivate::newThemeButtonClicked()
351 const int numberOfSelectedItem(mThemeList->selectedItems().count());
353 emptyTheme.
setName(uniqueNameForTheme(
i18n(
"New Theme")));
355 col->setLabel(
i18n(
"New Column"));
356 col->setVisibleByDefault(
true);
360 auto item =
new ThemeListWidgetItem(mThemeList, emptyTheme);
362 mThemeList->clearSelection();
363 mThemeList->setCurrentItem(item);
366 mEditor->editTheme(theme);
368 mDeleteThemeButton->setEnabled(!theme->readOnly());
369 mExportThemeButton->setEnabled(item);
370 mCloneThemeButton->setEnabled(numberOfSelectedItem == 1);
372 mDeleteThemeButton->setEnabled(
false);
373 mExportThemeButton->setEnabled(
false);
374 mCloneThemeButton->setEnabled(
false);
378void ConfigureThemesDialog::ConfigureThemesDialogPrivate::cloneThemeButtonClicked()
380 auto item =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->currentItem());
386 Theme copyTheme(*(item->theme()));
387 copyTheme.setReadOnly(
false);
389 copyTheme.generateUniqueId();
390 copyTheme.setName(uniqueNameForTheme(item->theme()->
name()));
391 item =
new ThemeListWidgetItem(mThemeList, copyTheme);
393 mThemeList->setCurrentItem(item);
394 mEditor->editTheme(item->theme());
396 const int numberOfSelectedItem(mThemeList->selectedItems().count());
397 mDeleteThemeButton->setEnabled(!item->theme()->readOnly());
398 mExportThemeButton->setEnabled(
true);
399 mCloneThemeButton->setEnabled(numberOfSelectedItem == 1);
402void ConfigureThemesDialog::ConfigureThemesDialogPrivate::deleteThemeButtonClicked()
408 const QString question =
list.
count() > 1 ?
i18n(
"Do you want to delete selected themes?") :
i18n(
"Do you want to delete \"%1\"?",
list.first()->text());
411 if (answer == KMessageBox::ButtonCode::PrimaryAction) {
412 mEditor->editTheme(
nullptr);
414 auto item =
dynamic_cast<ThemeListWidgetItem *
>(it);
418 if (!item->theme()->readOnly()) {
421 if (mThemeList->count() < 2) {
426 auto newItem =
dynamic_cast<ThemeListWidgetItem *
>(mThemeList->currentItem());
427 mDeleteThemeButton->setEnabled(newItem && !newItem->theme()->readOnly());
428 mExportThemeButton->setEnabled(newItem);
429 const int numberOfSelectedItem(mThemeList->selectedItems().count());
430 mCloneThemeButton->setEnabled(numberOfSelectedItem == 1);
434void ConfigureThemesDialog::ConfigureThemesDialogPrivate::importThemeButtonClicked()
440 if (config.hasGroup(QStringLiteral(
"MessageListView::Themes"))) {
441 KConfigGroup grp(&config, QStringLiteral(
"MessageListView::Themes"));
442 const int cnt = grp.readEntry(
"Count", 0);
445 const QString data = grp.readEntry(QStringLiteral(
"Set%1").arg(idx),
QString());
447 auto set =
new Theme();
449 set->setReadOnly(
false);
453 (void)
new ThemeListWidgetItem(mThemeList, *set);
464void ConfigureThemesDialog::ConfigureThemesDialogPrivate::exportThemeButtonClicked()
474 KConfigGroup grp(&config, QStringLiteral(
"MessageListView::Themes"));
479 auto themeItem =
static_cast<ThemeListWidgetItem *
>(item);
480 grp.writeEntry(QStringLiteral(
"Set%1").arg(idx), themeItem->theme()->saveToString());
486#include "moc_configurethemesdialog.cpp"
const QString & id() const
Returns the unique id of this OptionSet.
void generateUniqueId()
(Re)generates a (hopefully) unique identifier for this option set.
void setName(const QString &name)
Sets the name of this OptionSet.
const QString & name() const
Returns the name of this OptionSet.
bool loadFromString(const QString &data)
Attempts to unpack this configuration object from a string (that is likely to come out from a config ...
The Column class defines a view column available inside this theme.
The Row class defines a row of items inside a Column.
The Theme class defines the visual appearance of the MessageList.
void detach()
Detaches this object from the shared runtime data for columns.
void addColumn(Column *column)
Appends a column to this theme.
void resetColumnState()
Resets the column state (visibility and width) to their default values (the "visible by default" ones...
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardAction id)
const QList< QKeySequence > & end()
The implementation independent part of the MessageList library.
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QIcon fromTheme(const QString &name)
qsizetype count() const const
bool isEmpty() const const
void setText(const QString &text)
const_iterator constBegin() const const
const_iterator constEnd() const const
QObject * parent() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)