File indexing completed on 2024-04-28 07:50:46
0001 /* 0002 * Copyright 1999 by Martin R. Jones <mjones@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU General Public License 0015 * along with this program; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0017 */ 0018 #include "amordialog.h" 0019 0020 #include <QCheckBox> 0021 #include <QLabel> 0022 #include <QListWidget> 0023 #include <QSlider> 0024 #include <QPixmap> 0025 #include <QVBoxLayout> 0026 #include <QTextBrowser> 0027 #include <QStandardPaths> 0028 #include <QGridLayout> 0029 #include <QDir> 0030 #include <QDialogButtonBox> 0031 #include <QPushButton> 0032 0033 #include <KConfig> 0034 #include <KConfigGroup> 0035 #include <KSharedConfig> 0036 #include <KLocalizedString> 0037 0038 AmorDialog::AmorDialog(QWidget *parent) 0039 : QDialog( parent ) 0040 { 0041 setAttribute(Qt::WA_DeleteOnClose); 0042 setWindowTitle(i18nc("@title:window", "Options")); 0043 0044 0045 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel, this); 0046 connect(buttonBox, &QDialogButtonBox::clicked, 0047 this, [this, buttonBox](QAbstractButton *btn) { 0048 if (btn == buttonBox->button(QDialogButtonBox::Ok)) { 0049 slotOk(); 0050 } else if (btn == buttonBox->button(QDialogButtonBox::Apply)) { 0051 slotApply(); 0052 } else if (btn == buttonBox->button(QDialogButtonBox::Cancel)) { 0053 slotCancel(); 0054 } 0055 }); 0056 0057 mConfig.read(); 0058 auto l = new QVBoxLayout(this); 0059 QGridLayout *gridLayout = new QGridLayout(); 0060 gridLayout->setContentsMargins( 0, 0, 0, 0 ); 0061 l->addLayout(gridLayout); 0062 l->addStretch(2); 0063 l->addWidget(buttonBox); 0064 0065 QLabel *label = new QLabel( i18n( "Theme:" ), this); 0066 gridLayout->addWidget( label, 0, 0 ); 0067 0068 mThemeListView = new QListWidget(this); 0069 mThemeListView->setIconSize( QSize( 32, 32 ) ); 0070 mThemeListView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); 0071 mThemeListView->setAlternatingRowColors( true ); 0072 connect( mThemeListView, SIGNAL(currentRowChanged(int)), SLOT(slotHighlighted(int)) ); 0073 mThemeListView->setMinimumSize( fontMetrics().maxWidth()*20, fontMetrics().lineSpacing()*6 ); 0074 gridLayout->addWidget( mThemeListView, 1, 0 ); 0075 0076 mAboutEdit = new QTextBrowser( this ); 0077 mAboutEdit->setReadOnly( true ); 0078 mAboutEdit->setMinimumHeight( fontMetrics().lineSpacing()*4 ); 0079 gridLayout->addWidget( mAboutEdit, 2, 0 ); 0080 0081 // Animation offset 0082 label = new QLabel( i18n("Offset:"), this ); 0083 gridLayout->addWidget( label, 0, 1 ); 0084 0085 QSlider *slider = new QSlider( Qt::Vertical, this ); 0086 slider->setRange( -40, 40 ); 0087 slider->setPageStep( 5 ); 0088 slider->setValue( mConfig.mOffset ); 0089 connect( slider, SIGNAL(valueChanged(int)), SLOT(slotOffset(int)) ); 0090 gridLayout->addWidget( slider, 1, 1, 2, 1 ); 0091 0092 // Always on top 0093 QCheckBox *checkBox = new QCheckBox( i18n( "Always on top" ), this ); 0094 connect( checkBox, SIGNAL(toggled(bool)), SLOT(slotOnTop(bool)) ); 0095 checkBox->setChecked( mConfig.mOnTop ); 0096 gridLayout->addWidget( checkBox, 3, 0, 1, 2 ); 0097 0098 checkBox = new QCheckBox( i18n( "Show random tips" ), this ); 0099 connect( checkBox, SIGNAL(toggled(bool)), SLOT(slotRandomTips(bool)) ); 0100 checkBox->setChecked( mConfig.mTips ); // always keep this one after the connect, or the QList would not be grayed when it should 0101 gridLayout->addWidget( checkBox, 4, 0, 1, 2 ); 0102 0103 checkBox = new QCheckBox( i18n( "Use a random character" ), this ); 0104 connect( checkBox, SIGNAL(toggled(bool)), SLOT(slotRandomTheme(bool)) ); 0105 checkBox->setChecked( mConfig.mRandomTheme ); 0106 gridLayout->addWidget( checkBox, 5, 0, 1, 2 ); 0107 0108 checkBox = new QCheckBox( i18n( "Allow application tips" ), this ); 0109 connect( checkBox, SIGNAL(toggled(bool)), SLOT(slotApplicationTips(bool)) ); 0110 checkBox->setChecked( mConfig.mAppTips ); 0111 gridLayout->addWidget( checkBox, 6, 0, 1, 2 ); 0112 0113 readThemes(); 0114 } 0115 0116 0117 void AmorDialog::readThemes() 0118 { 0119 // Non-recursive search for theme files, with the relative paths stored 0120 // in files so that absolute paths are not used. 0121 const auto folders = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("amor"), 0122 QStandardPaths::LocateDirectory); 0123 0124 for (const auto &folder : folders) { 0125 QDir amorDir(folder); 0126 const auto files = amorDir.entryList({ QStringLiteral("*rc") }, QDir::Files, QDir::NoSort); 0127 0128 for (const auto &file : files) { 0129 addTheme(folder, file); 0130 } 0131 } 0132 } 0133 0134 0135 void AmorDialog::addTheme(const QString& folder, const QString& file) 0136 { 0137 KConfig config(QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0138 QStringLiteral("amor/%1").arg(file))); 0139 KConfigGroup configGroup( &config, "Config" ); 0140 0141 QString pixmapPath = folder 0142 + QDir::separator() 0143 + configGroup.readPathEntry( "PixmapPath", QString() ); 0144 if( pixmapPath.isEmpty() ) { 0145 return; 0146 } 0147 0148 pixmapPath += QDir::separator(); 0149 if( pixmapPath[0] != QDir::separator() ) { 0150 // relative to config file. We add a / to indicate the dir 0151 pixmapPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0152 QStringLiteral("amor/%1").arg(pixmapPath), 0153 QStandardPaths::LocateDirectory); 0154 } 0155 0156 QString description = configGroup.readEntry( "Description" ); 0157 QString about = configGroup.readEntry( "About", " " ); 0158 QString pixmapName = configGroup.readEntry( "Icon" ); 0159 0160 pixmapPath += pixmapName; 0161 QPixmap pixmap( pixmapPath ); 0162 0163 QListWidgetItem *item = new QListWidgetItem( QIcon(pixmap), description, mThemeListView ); 0164 mThemes.append( file ); 0165 mThemeAbout.append( about ); 0166 0167 if( mConfig.mTheme == file ) { 0168 mThemeListView->setCurrentItem( item ); 0169 } 0170 } 0171 0172 0173 void AmorDialog::slotHighlighted(int index) 0174 { 0175 if( index < 0 ) { 0176 return; 0177 } 0178 0179 mConfig.mTheme = mThemes.at( index ); 0180 mAboutEdit->setPlainText( mThemeAbout.at( index ) ); 0181 } 0182 0183 0184 void AmorDialog::slotOffset(int off) 0185 { 0186 mConfig.mOffset = off; 0187 Q_EMIT offsetChanged( mConfig.mOffset ); 0188 } 0189 0190 0191 void AmorDialog::slotOnTop(bool onTop) 0192 { 0193 mConfig.mOnTop = onTop; 0194 } 0195 0196 0197 void AmorDialog::slotRandomTips(bool tips) 0198 { 0199 mConfig.mTips = tips; 0200 } 0201 0202 0203 void AmorDialog::slotRandomTheme(bool randomTheme) 0204 { 0205 mThemeListView->setEnabled( !randomTheme ); 0206 mConfig.mRandomTheme = randomTheme; 0207 } 0208 0209 0210 void AmorDialog::slotApplicationTips(bool tips) 0211 { 0212 mConfig.mAppTips = tips; 0213 } 0214 0215 0216 void AmorDialog::slotOk() 0217 { 0218 mConfig.write(); 0219 Q_EMIT changed(); 0220 accept(); 0221 } 0222 0223 0224 void AmorDialog::slotApply() 0225 { 0226 mConfig.write(); 0227 Q_EMIT changed(); 0228 } 0229 0230 0231 void AmorDialog::slotCancel() 0232 { 0233 // restore offset 0234 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0235 KConfigGroup cs( config, "General" ); 0236 Q_EMIT offsetChanged( cs.readEntry( "Offset", 0 ) ); 0237 reject(); 0238 } 0239 0240 0241 // kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; 0242 // vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: