File indexing completed on 2024-12-01 11:10:30
0001 /* 0002 SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "detailshandler.h" 0007 0008 // local 0009 #include "ui_detailsdialog.h" 0010 #include "colorsmodel.h" 0011 #include "detailsdialog.h" 0012 #include "patternwidget.h" 0013 #include "schemesmodel.h" 0014 #include "delegates/colorcmbitemdelegate.h" 0015 #include "delegates/schemecmbitemdelegate.h" 0016 #include "../settingsdialog/layoutscontroller.h" 0017 #include "../settingsdialog/layoutsmodel.h" 0018 #include "../settingsdialog/delegates/layoutcmbitemdelegate.h" 0019 #include "../../data/layoutstable.h" 0020 #include "../../layout/abstractlayout.h" 0021 0022 // Qt 0023 #include <QColorDialog> 0024 #include <QFileDialog> 0025 #include <QIcon> 0026 0027 // KDE 0028 #include <KIconDialog> 0029 0030 namespace Latte { 0031 namespace Settings { 0032 namespace Handler { 0033 0034 DetailsHandler::DetailsHandler(Dialog::DetailsDialog *dialog) 0035 : Generic(dialog), 0036 m_dialog(dialog), 0037 m_ui(m_dialog->ui()), 0038 m_colorsModel(new Model::Colors(this, dialog->corona())), 0039 m_schemesModel(new Model::Schemes(this)) 0040 { 0041 init(); 0042 } 0043 0044 DetailsHandler::~DetailsHandler() 0045 { 0046 } 0047 0048 void DetailsHandler::init() 0049 { 0050 //! Layouts 0051 m_layoutsProxyModel = new QSortFilterProxyModel(this); 0052 m_layoutsProxyModel->setSourceModel(m_dialog->layoutsController()->baseModel()); 0053 m_layoutsProxyModel->setSortRole(Model::Layouts::SORTINGROLE); 0054 m_layoutsProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); 0055 m_layoutsProxyModel->sort(Model::Layouts::NAMECOLUMN, Qt::AscendingOrder); 0056 0057 m_ui->layoutsCmb->setModel(m_layoutsProxyModel); 0058 m_ui->layoutsCmb->setModelColumn(Model::Layouts::NAMECOLUMN); 0059 m_ui->layoutsCmb->setItemDelegate(new Settings::Layout::Delegate::LayoutCmbItemDelegate(this)); 0060 0061 //! Schemes 0062 m_ui->customSchemeCmb->setModel(m_schemesModel); 0063 m_ui->customSchemeCmb->setItemDelegate(new Settings::Details::Delegate::SchemeCmbItemDelegate(this)); 0064 0065 //! Background Pattern 0066 m_backButtonsGroup = new QButtonGroup(this); 0067 m_backButtonsGroup->addButton(m_ui->colorRadioBtn, Latte::Layout::ColorBackgroundStyle); 0068 m_backButtonsGroup->addButton(m_ui->backRadioBtn, Latte::Layout::PatternBackgroundStyle); 0069 m_backButtonsGroup->setExclusive(true); 0070 0071 m_ui->colorsCmb->setItemDelegate(new Details::Delegate::ColorCmbBoxItem(this)); 0072 m_ui->colorsCmb->setModel(m_colorsModel); 0073 0074 m_ui->patternClearBtn->setFixedHeight(m_ui->backgroundBtn->height()+2); 0075 0076 connect(m_backButtonsGroup, static_cast<void(QButtonGroup::*)(int, bool)>(&QButtonGroup::buttonToggled), 0077 [ = ](int id, bool checked) { 0078 0079 if (checked) { 0080 setBackgroundStyle(static_cast<Latte::Layout::BackgroundStyle>(id)); 0081 } 0082 }); 0083 0084 connect(m_ui->backgroundBtn, &QPushButton::pressed, this, &DetailsHandler::selectBackground); 0085 connect(m_ui->iconBtn, &QPushButton::pressed, this, &DetailsHandler::selectIcon); 0086 connect(m_ui->iconClearBtn, &QPushButton::pressed, this, &DetailsHandler::clearIcon); 0087 connect(m_ui->textColorBtn, &QPushButton::pressed, this, &DetailsHandler::selectTextColor); 0088 connect(m_ui->patternClearBtn, &QPushButton::pressed, this, &DetailsHandler::clearPattern); 0089 0090 0091 //! Options 0092 connect(m_ui->popUpMarginSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, [&](int i) { 0093 setPopUpMargin(i); 0094 }); 0095 0096 connect(m_ui->inMenuChk, &QCheckBox::stateChanged, this, [&]() { 0097 setIsShownInMenu(m_ui->inMenuChk->isChecked()); 0098 }); 0099 0100 connect(m_ui->borderlessChk, &QCheckBox::stateChanged, this, [&]() { 0101 setHasDisabledBorders(m_ui->borderlessChk->isChecked()); 0102 }); 0103 0104 connect(this, &DetailsHandler::currentLayoutChanged, this, &DetailsHandler::reload); 0105 0106 reload(); 0107 m_lastConfirmedLayoutIndex = m_ui->colorsCmb->currentIndex(); 0108 0109 //! connect layout combobox after the selected layout has been loaded 0110 connect(m_ui->layoutsCmb, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DetailsHandler::onCurrentLayoutIndexChanged); 0111 0112 //! connect colors combobox after the selected layout has been loaded 0113 connect(m_ui->colorsCmb, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DetailsHandler::onCurrentColorIndexChanged); 0114 0115 //! connect custom scheme combobox after the selected layout has been loaded 0116 connect(m_ui->customSchemeCmb, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DetailsHandler::onCurrentSchemeIndexChanged); 0117 0118 //! pattern widgets 0119 connect(m_ui->backPatternWidget, &Widget::PatternWidget::mouseReleased, this, [&]() { 0120 setBackgroundStyle(Latte::Layout::PatternBackgroundStyle); 0121 }); 0122 connect(m_ui->colorPatternWidget, &Widget::PatternWidget::mouseReleased, this, [&]() { 0123 setBackgroundStyle(Latte::Layout::ColorBackgroundStyle); 0124 }); 0125 0126 0127 //! data were changed 0128 connect(this, &DetailsHandler::dataChanged, this, [&]() { 0129 loadLayout(c_data); 0130 }); 0131 } 0132 0133 void DetailsHandler::reload() 0134 { 0135 o_data = m_dialog->layoutsController()->selectedLayoutCurrentData(); 0136 c_data = o_data; 0137 0138 Latte::Data::LayoutIcon icon = m_dialog->layoutsController()->selectedLayoutIcon(); 0139 0140 m_ui->layoutsCmb->setCurrentText(o_data.name); 0141 m_ui->layoutsCmb->setLayoutIcon(icon); 0142 0143 loadLayout(c_data); 0144 } 0145 0146 void DetailsHandler::loadLayout(const Latte::Data::Layout &data) 0147 { 0148 if (data.icon.isEmpty()) { 0149 m_ui->iconBtn->setIcon(QIcon::fromTheme("add")); 0150 m_ui->iconClearBtn->setVisible(false); 0151 } else { 0152 m_ui->iconBtn->setIcon(QIcon::fromTheme(data.icon)); 0153 m_ui->iconClearBtn->setVisible(true); 0154 } 0155 0156 if (data.backgroundStyle == Latte::Layout::ColorBackgroundStyle) { 0157 m_ui->colorRadioBtn->setChecked(true); 0158 m_ui->backRadioBtn->setChecked(false); 0159 0160 m_ui->colorsCmb->setVisible(true); 0161 m_ui->backgroundBtn->setVisible(false); 0162 m_ui->textColorBtn->setVisible(false); 0163 m_ui->patternClearBtn->setVisible(false); 0164 } else { 0165 m_ui->colorRadioBtn->setChecked(false); 0166 m_ui->backRadioBtn->setChecked(true); 0167 0168 m_ui->colorsCmb->setVisible(false); 0169 m_ui->backgroundBtn->setVisible(true); 0170 m_ui->textColorBtn->setVisible(true); 0171 m_ui->patternClearBtn->setVisible(true); 0172 } 0173 0174 int schind = m_schemesModel->row(data.schemeFile); 0175 m_ui->customSchemeCmb->setCurrentIndex(schind); 0176 updateCustomSchemeCmb(schind); 0177 0178 m_ui->colorPatternWidget->setBackground(m_colorsModel->colorPath(data.color)); 0179 m_ui->colorPatternWidget->setTextColor(Latte::Layout::AbstractLayout::defaultTextColor(data.color)); 0180 0181 m_ui->colorsCmb->setCurrentIndex(m_colorsModel->row(data.color)); 0182 0183 if (data.background.isEmpty()) { 0184 m_ui->backPatternWidget->setBackground(m_colorsModel->colorPath(Latte::Layout::AbstractLayout::defaultCustomBackground())); 0185 } else { 0186 m_ui->backPatternWidget->setBackground(data.background); 0187 } 0188 0189 if (data.background.isEmpty() && data.textColor.isEmpty()) { 0190 m_ui->backPatternWidget->setTextColor(Latte::Layout::AbstractLayout::defaultCustomTextColor()); 0191 } else { 0192 m_ui->backPatternWidget->setTextColor(data.textColor); 0193 } 0194 0195 if (!data.background.isEmpty() || !data.textColor.isEmpty()) { 0196 m_ui->patternClearBtn->setEnabled(true); 0197 } else { 0198 m_ui->patternClearBtn->setEnabled(false); 0199 } 0200 0201 m_ui->popUpMarginSpinBox->setValue(data.popUpMargin); 0202 0203 m_ui->inMenuChk->setChecked(data.isShownInMenu); 0204 m_ui->borderlessChk->setChecked(data.hasDisabledBorders); 0205 0206 updateWindowTitle(); 0207 } 0208 0209 Latte::Data::Layout DetailsHandler::currentData() const 0210 { 0211 return c_data; 0212 } 0213 0214 bool DetailsHandler::hasChangedData() const 0215 { 0216 return o_data != c_data; 0217 } 0218 0219 bool DetailsHandler::inDefaultValues() const 0220 { 0221 //nothing special 0222 return true; 0223 } 0224 0225 0226 void DetailsHandler::reset() 0227 { 0228 c_data = o_data; 0229 emit currentLayoutChanged(); 0230 } 0231 0232 void DetailsHandler::resetDefaults() 0233 { 0234 //do nothing 0235 } 0236 0237 void DetailsHandler::save() 0238 { 0239 m_dialog->layoutsController()->setLayoutProperties(currentData()); 0240 } 0241 0242 void DetailsHandler::clearIcon() 0243 { 0244 setIcon(""); 0245 } 0246 0247 void DetailsHandler::clearPattern() 0248 { 0249 setBackground(""); 0250 setTextColor(""); 0251 } 0252 0253 void DetailsHandler::onCurrentColorIndexChanged(int row) 0254 { 0255 QString selectedColor = m_ui->colorsCmb->itemData(row, Model::Colors::IDROLE).toString(); 0256 setColor(selectedColor); 0257 } 0258 0259 void DetailsHandler::onCurrentLayoutIndexChanged(int row) 0260 { 0261 bool switchtonewlayout{false}; 0262 0263 if (m_lastConfirmedLayoutIndex != row) { 0264 if (hasChangedData()) { //new layout was chosen but there are changes 0265 KMessageBox::ButtonCode result = saveChangesConfirmation(); 0266 0267 if (result == KMessageBox::Yes) { 0268 switchtonewlayout = true; 0269 m_lastConfirmedLayoutIndex = row; 0270 save(); 0271 } else if (result == KMessageBox::No) { 0272 switchtonewlayout = true; 0273 m_lastConfirmedLayoutIndex = row; 0274 } else if (result == KMessageBox::Cancel) { 0275 //do nothing 0276 } 0277 } else { //new layout was chosen and there are no changes 0278 switchtonewlayout = true; 0279 m_lastConfirmedLayoutIndex = row; 0280 } 0281 } 0282 0283 if (switchtonewlayout) { 0284 QString layoutId = m_layoutsProxyModel->data(m_layoutsProxyModel->index(row, Model::Layouts::IDCOLUMN), Qt::UserRole).toString(); 0285 m_dialog->layoutsController()->selectRow(layoutId); 0286 reload(); 0287 emit currentLayoutChanged(); 0288 } else { 0289 //! reset combobox index 0290 m_ui->layoutsCmb->setCurrentText(c_data.name); 0291 } 0292 } 0293 0294 void DetailsHandler::updateCustomSchemeCmb(const int &row) 0295 { 0296 int scmind = row; 0297 m_ui->customSchemeCmb->setCurrentText(m_ui->customSchemeCmb->itemData(scmind, Qt::DisplayRole).toString()); 0298 m_ui->customSchemeCmb->setTextColor(m_ui->customSchemeCmb->itemData(scmind, Model::Schemes::TEXTCOLORROLE).value<QColor>()); 0299 m_ui->customSchemeCmb->setBackgroundColor(m_ui->customSchemeCmb->itemData(scmind, Model::Schemes::BACKGROUNDCOLORROLE).value<QColor>()); 0300 } 0301 0302 void DetailsHandler::onCurrentSchemeIndexChanged(int row) 0303 { 0304 updateCustomSchemeCmb(row); 0305 QString selectedScheme = m_ui->customSchemeCmb->itemData(row, Model::Schemes::IDROLE).toString(); 0306 setCustomSchemeFile(selectedScheme); 0307 } 0308 0309 void DetailsHandler::setBackground(const QString &background) 0310 { 0311 if (c_data.background == background) { 0312 return; 0313 } 0314 0315 c_data.background = background; 0316 emit dataChanged(); 0317 } 0318 0319 void DetailsHandler::setColor(const QString &color) 0320 { 0321 if (c_data.color == color) { 0322 return; 0323 } 0324 0325 c_data.color = color; 0326 emit dataChanged(); 0327 } 0328 0329 void DetailsHandler::setCustomSchemeFile(const QString &file) 0330 { 0331 if (c_data.schemeFile == file) { 0332 return; 0333 } 0334 0335 c_data.schemeFile = file; 0336 emit dataChanged(); 0337 } 0338 0339 void DetailsHandler::setIcon(const QString &icon) 0340 { 0341 if (c_data.icon == icon) { 0342 return; 0343 } 0344 0345 c_data.icon = icon; 0346 emit dataChanged(); 0347 } 0348 0349 void DetailsHandler::setTextColor(const QString &textColor) 0350 { 0351 if (c_data.textColor == textColor) { 0352 return; 0353 } 0354 0355 c_data.textColor = textColor; 0356 emit dataChanged(); 0357 } 0358 0359 void DetailsHandler::setIsShownInMenu(bool inMenu) 0360 { 0361 if (c_data.isShownInMenu == inMenu) { 0362 return; 0363 } 0364 0365 c_data.isShownInMenu = inMenu; 0366 emit dataChanged(); 0367 } 0368 0369 void DetailsHandler::setHasDisabledBorders(bool disabled) 0370 { 0371 if (c_data.hasDisabledBorders == disabled) { 0372 return; 0373 } 0374 0375 c_data.hasDisabledBorders = disabled; 0376 emit dataChanged(); 0377 } 0378 0379 void DetailsHandler::setBackgroundStyle(const Latte::Layout::BackgroundStyle &style) 0380 { 0381 if (c_data.backgroundStyle == style) { 0382 return; 0383 } 0384 0385 c_data.backgroundStyle = style; 0386 emit dataChanged(); 0387 } 0388 0389 void DetailsHandler::setPopUpMargin(const int &margin) 0390 { 0391 if (c_data.popUpMargin == margin) { 0392 return; 0393 } 0394 0395 c_data.popUpMargin = margin; 0396 emit dataChanged(); 0397 } 0398 0399 void DetailsHandler::selectBackground() 0400 { 0401 QStringList mimeTypeFilters; 0402 mimeTypeFilters << "image/jpeg" // will show "JPEG image (*.jpeg *.jpg) 0403 << "image/png"; // will show "PNG image (*.png)" 0404 0405 QFileDialog dialog(m_dialog); 0406 dialog.setMimeTypeFilters(mimeTypeFilters); 0407 0408 QString background = m_ui->backPatternWidget->background(); 0409 0410 if (background.startsWith("/") && QFileInfo(background).exists()) { 0411 dialog.setDirectory(QFileInfo(background).absolutePath()); 0412 dialog.selectFile(background); 0413 } 0414 0415 if (dialog.exec()) { 0416 QStringList files = dialog.selectedFiles(); 0417 0418 if (files.count() > 0) { 0419 setBackground(files[0]); 0420 } 0421 } 0422 } 0423 0424 void DetailsHandler::selectIcon() 0425 { 0426 QString icon = KIconDialog::getIcon(); 0427 0428 if (!icon.isEmpty()) { 0429 setIcon(icon); 0430 } 0431 } 0432 0433 void DetailsHandler::selectTextColor() 0434 { 0435 QColorDialog dialog(m_dialog); 0436 dialog.setCurrentColor(QColor(m_ui->backPatternWidget->textColor())); 0437 0438 if (dialog.exec()) { 0439 qDebug() << "layout selected text color: " << dialog.selectedColor().name(); 0440 setTextColor(dialog.selectedColor().name()); 0441 } 0442 } 0443 0444 void DetailsHandler::updateWindowTitle() 0445 { 0446 m_dialog->setWindowTitle(i18nc("<layout name> Details","%1 Details", m_ui->layoutsCmb->currentText())); 0447 } 0448 0449 KMessageBox::ButtonCode DetailsHandler::saveChangesConfirmation() 0450 { 0451 if (hasChangedData()) { 0452 QString layoutName = c_data.name; 0453 QString saveChangesText = i18n("The settings of <b>%1</b> layout have changed.<br/>Do you want to apply the changes or discard them?", layoutName); 0454 0455 return m_dialog->saveChangesConfirmation(saveChangesText); 0456 } 0457 0458 return KMessageBox::Cancel; 0459 } 0460 0461 } 0462 } 0463 }