File indexing completed on 2025-01-12 12:26:25
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 2001,2002 Rolf Magnus <ramagnus@kde.org> 0003 0004 library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License version 2 as published by the Free Software Foundation. 0007 0008 This library is distributed in the hope that it will be useful, 0009 but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0011 Library General Public License for more details. 0012 0013 You should have received a copy of the GNU Library General Public License 0014 along with this library; see the file COPYING.LIB. If not, write to 0015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0016 Boston, MA 02110-1301, USA. 0017 */ 0018 0019 #include "kfilemetainfowidget.h" 0020 0021 #include <ktextedit.h> 0022 #include <klocalizedstring.h> 0023 #include <kcombobox.h> 0024 #include <klineedit.h> 0025 #include <kstringvalidator.h> 0026 #include <kdebug.h> 0027 0028 #include <QLabel> 0029 #include <QCheckBox> 0030 #include <QDoubleSpinBox> 0031 #include <QDateEdit> 0032 #include <QPixmap> 0033 #include <QImage> 0034 #include <QLayout> 0035 #include <QSizePolicy> 0036 #include <QDoubleValidator> 0037 0038 class KFileMetaInfoWidgetPrivate 0039 { 0040 public: 0041 KFileMetaInfoWidgetPrivate(KFileMetaInfoWidget *qq) 0042 : q(qq) 0043 { 0044 } 0045 0046 void init(KFileMetaInfoItem item, KFileMetaInfoWidget::Mode mode); 0047 0048 KFileMetaInfoWidget *q; 0049 QVariant m_value; // the value will be saved here until apply() is called 0050 KFileMetaInfoItem m_item; 0051 QWidget *m_widget; 0052 QValidator *m_validator; 0053 bool m_dirty : 1; 0054 }; 0055 0056 /* 0057 Widgets used for different types: 0058 0059 bool : QCheckBox 0060 int : QSpinBox 0061 QString : KComboBox if the validator is a KStringListValidator, else lineedit 0062 QDateTime : QDateTimeEdit 0063 0064 */ 0065 0066 KFileMetaInfoWidget::KFileMetaInfoWidget(KFileMetaInfoItem item, 0067 QValidator *val, 0068 QWidget *parent) 0069 : QWidget(parent), d(new KFileMetaInfoWidgetPrivate(this)) 0070 { 0071 d->m_value = item.value(); 0072 d->m_item = item; 0073 d->m_validator = val; 0074 d->init(item, ReadWrite); 0075 } 0076 0077 KFileMetaInfoWidget::KFileMetaInfoWidget(KFileMetaInfoItem item, 0078 Mode mode, 0079 QValidator *val, 0080 QWidget *parent) 0081 : QWidget(parent), d(new KFileMetaInfoWidgetPrivate(this)) 0082 { 0083 d->m_value = item.value(); 0084 d->m_item = item; 0085 d->m_validator = val; 0086 d->init(item, mode); 0087 } 0088 0089 void KFileMetaInfoWidgetPrivate::init(KFileMetaInfoItem item, KFileMetaInfoWidget::Mode mode) 0090 { 0091 Q_UNUSED(item) 0092 kDebug(7033) << "*** item " << m_item.name() 0093 << " is a " << m_value.typeName() << endl; 0094 0095 if (m_item.isEditable() && !(mode & KFileMetaInfoWidget::ReadOnly)) { 0096 m_widget = q->makeWidget(); 0097 } else 0098 switch (m_value.type()) { 0099 case QVariant::Image : 0100 m_widget = new QLabel(q); 0101 m_widget->setObjectName(QLatin1String("info image")); 0102 static_cast<QLabel *>(m_widget)->setPixmap(QPixmap::fromImage(m_value.value<QImage>())); 0103 break; 0104 case QVariant::Pixmap : 0105 m_widget = new QLabel(q); 0106 m_widget->setObjectName(QLatin1String("info pixmap")); 0107 static_cast<QLabel *>(m_widget)->setPixmap(m_value.value<QPixmap>()); 0108 break; 0109 default: 0110 m_widget = new QLabel(m_value.toString(), q); 0111 m_widget->setObjectName(QLatin1String("info label")); 0112 } 0113 0114 QHBoxLayout *lay = new QHBoxLayout(q); 0115 lay->setContentsMargins(0, 0, 0, 0); 0116 lay->addWidget(m_widget); 0117 0118 QSizePolicy sp = q->sizePolicy(); 0119 sp.setVerticalPolicy(QSizePolicy::Minimum); 0120 q->setSizePolicy(sp); 0121 } 0122 0123 KFileMetaInfoWidget::~KFileMetaInfoWidget() 0124 { 0125 delete d; 0126 } 0127 0128 bool KFileMetaInfoWidget::apply() 0129 { 0130 return d->m_item.isEditable() && d->m_item.setValue(d->m_value); 0131 } 0132 0133 void KFileMetaInfoWidget::setValue(const QVariant &value) 0134 { 0135 d->m_value = value; 0136 } 0137 0138 QVariant KFileMetaInfoWidget::value() const 0139 { 0140 return d->m_value; 0141 } 0142 0143 QValidator *KFileMetaInfoWidget::validator() const 0144 { 0145 return d->m_validator; 0146 } 0147 0148 KFileMetaInfoItem KFileMetaInfoWidget::item() const 0149 { 0150 return d->m_item; 0151 } 0152 0153 QWidget *KFileMetaInfoWidget::makeWidget() 0154 { 0155 QString valClass; 0156 QWidget *w; 0157 0158 switch (d->m_value.type()) { 0159 case QVariant::Invalid: // no type 0160 // just make a label 0161 w = new QLabel(i18n("<Error>"), this); 0162 w->setObjectName(QLatin1String("label")); 0163 break; 0164 0165 case QVariant::Int: // an int 0166 case QVariant::UInt: // an unsigned int 0167 w = makeIntWidget(); 0168 break; 0169 0170 case QVariant::Bool: // a bool 0171 w = makeBoolWidget(); 0172 break; 0173 0174 case QVariant::Double: // a double 0175 w = makeDoubleWidget(); 0176 break; 0177 0178 case QVariant::Date: // a QDate 0179 w = makeDateWidget(); 0180 break; 0181 0182 case QVariant::Time: // a QTime 0183 w = makeTimeWidget(); 0184 break; 0185 0186 case QVariant::DateTime: // a QDateTime 0187 w = makeDateTimeWidget(); 0188 break; 0189 0190 #if 0 0191 case QVariant::Size: // a QSize 0192 case QVariant::String: // a QString 0193 case QVariant::List: // a QValueList 0194 case QVariant::Map: // a QMap 0195 case QVariant::StringList: // a QStringList 0196 case QVariant::Font: // a QFont 0197 case QVariant::Pixmap: // a QPixmap 0198 case QVariant::Brush: // a QBrush 0199 case QVariant::Rect: // a QRect 0200 case QVariant::Color: // a QColor 0201 case QVariant::Palette: // a QPalette 0202 case QVariant::ColorGroup: // a QColorGroup 0203 case QCoreVariant::Icon: // a QIconSet 0204 case QVariant::Point: // a QPoint 0205 case QVariant::Image: // a QImage 0206 case QVariant::CString: // a QCString 0207 case QVariant::PointArray: // a QPointArray 0208 case QVariant::Region: // a QRegion 0209 case QVariant::Bitmap: // a QBitmap 0210 case QVariant::Cursor: // a QCursor 0211 case QVariant::ByteArray: // a QByteArray 0212 case QVariant::BitArray: // a QBitArray 0213 case QVariant::SizePolicy: // a QSizePolicy 0214 case QVariant::KeySequence: // a QKeySequence 0215 #endif 0216 default: 0217 w = makeStringWidget(); 0218 } 0219 0220 kDebug(7033) << "*** item " << d->m_item.name() 0221 << "is a " << d->m_item.value().typeName() << endl; 0222 if (d->m_validator) 0223 kDebug(7033) << " and validator is a " 0224 << d->m_validator->metaObject()->className() << endl; 0225 0226 kDebug(7033) << "*** created a " << w->metaObject()->className() 0227 << " for it\n"; 0228 0229 return w; 0230 } 0231 0232 // **************************************************************** 0233 // now the different methods to make the widgets for specific types 0234 // **************************************************************** 0235 0236 QWidget *KFileMetaInfoWidget::makeBoolWidget() 0237 { 0238 QCheckBox *cb = new QCheckBox(this); 0239 cb->setObjectName(QLatin1String("metainfo bool widget")); 0240 cb->setChecked(d->m_item.value().toBool()); 0241 connect(cb, SIGNAL(toggled(bool)), this, SLOT(slotChanged(bool))); 0242 return cb; 0243 } 0244 0245 QWidget *KFileMetaInfoWidget::makeIntWidget() 0246 { 0247 QSpinBox *sb = new QSpinBox(this); 0248 sb->setObjectName(QLatin1String("metainfo integer widget")); 0249 sb->setValue(d->m_item.value().toInt()); 0250 0251 if (d->m_validator) { 0252 if (QIntValidator *iv = qobject_cast<QIntValidator *>(d->m_validator)) { 0253 sb->setMinimum(iv->bottom()); 0254 sb->setMaximum(iv->top()); 0255 } 0256 //reparentValidator(sb, m_validator); 0257 //sb->setValidator(m_validator); 0258 } 0259 0260 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0261 // make sure that an uint cannot be set to a value < 0 0262 if (d->m_item.properties().type() == QVariant::UInt) { 0263 sb->setMinimum(qMax(sb->minimum(), 0)); 0264 } 0265 #endif 0266 0267 connect(sb, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int))); 0268 return sb; 0269 } 0270 0271 QWidget *KFileMetaInfoWidget::makeDoubleWidget() 0272 { 0273 double value = d->m_item.value().toDouble(); 0274 0275 QDoubleSpinBox *dni = new QDoubleSpinBox(this); 0276 dni->setMinimum(qMin(0.0, value)); //krazy:exclude=qminmax 0277 dni->setMaximum(qMax(0.0, value)); //krazy:exclude=qminmax 0278 dni->setValue(value); 0279 dni->setSingleStep(0.01); 0280 dni->setDecimals(2); 0281 0282 if (d->m_validator) { 0283 if (QDoubleValidator *dv = qobject_cast<QDoubleValidator *>(d->m_validator)) { 0284 dni->setMinimum(dv->bottom()); 0285 dni->setMaximum(dv->top()); 0286 } 0287 reparentValidator(dni, d->m_validator); 0288 } 0289 0290 connect(dni, SIGNAL(valueChanged(double)), this, SLOT(slotChanged(double))); 0291 return dni; 0292 } 0293 0294 QWidget *KFileMetaInfoWidget::makeStringWidget() 0295 { 0296 if (KStringListValidator *val = qobject_cast<KStringListValidator *>(d->m_validator)) { 0297 KComboBox *b = new KComboBox(true, this); 0298 b->addItems(val->stringList()); 0299 int i = b->findText(d->m_item.value().toString()); 0300 if (i != -1) { 0301 b->setCurrentIndex(i); 0302 } else { 0303 b->setEditText(d->m_item.value().toString()); 0304 } 0305 connect(b, SIGNAL(activated(QString)), this, SLOT(slotComboChanged(QString))); 0306 b->setValidator(val); 0307 reparentValidator(b, val); 0308 return b; 0309 } 0310 0311 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0312 if (d->m_item.properties().attributes() & PredicateProperties::MultiLine) { 0313 KTextEdit *edit = new KTextEdit(this); 0314 edit->setAcceptRichText(false); 0315 edit->setPlainText(d->m_item.value().toString()); 0316 connect(edit, SIGNAL(textChanged()), 0317 this, SLOT(slotMultiLineEditChanged())); 0318 // can't use a validator with a KTextEdit, but we may need to delete it 0319 if (d->m_validator) { 0320 reparentValidator(edit, d->m_validator); 0321 } 0322 return edit; 0323 } 0324 #endif 0325 0326 KLineEdit *e = new KLineEdit(d->m_item.value().toString(), this); 0327 if (d->m_validator) { 0328 e->setValidator(d->m_validator); 0329 reparentValidator(e, d->m_validator); 0330 } 0331 connect(e, SIGNAL(textChanged(QString)), 0332 this, SLOT(slotLineEditChanged(QString))); 0333 return e; 0334 } 0335 0336 QWidget *KFileMetaInfoWidget::makeDateWidget() 0337 { 0338 QWidget *e = new QDateEdit(d->m_item.value().toDate(), this); 0339 connect(e, SIGNAL(valueChanged(QDate)), 0340 this, SLOT(slotDateChanged(QDate))); 0341 return e; 0342 } 0343 0344 QWidget *KFileMetaInfoWidget::makeTimeWidget() 0345 { 0346 return new QTimeEdit(d->m_item.value().toTime(), this); 0347 } 0348 0349 QWidget *KFileMetaInfoWidget::makeDateTimeWidget() 0350 { 0351 return new QDateTimeEdit(d->m_item.value().toDateTime(), this); 0352 } 0353 0354 void KFileMetaInfoWidget::reparentValidator(QWidget *widget, 0355 QValidator *validator) 0356 { 0357 if (!validator->parent()) { 0358 validator->setParent(widget); 0359 } 0360 } 0361 0362 // **************************************************************** 0363 // now the slots that let us get notified if the value changed in the child 0364 // **************************************************************** 0365 0366 void KFileMetaInfoWidget::slotChanged(bool value) 0367 { 0368 Q_ASSERT(qobject_cast<QComboBox *>(d->m_widget)); 0369 d->m_value = QVariant(value); 0370 emit valueChanged(d->m_value); 0371 d->m_dirty = true; 0372 } 0373 0374 void KFileMetaInfoWidget::slotChanged(int value) 0375 { 0376 Q_ASSERT(qobject_cast<QSpinBox *>(d->m_widget)); 0377 d->m_value = QVariant(value); 0378 emit valueChanged(d->m_value); 0379 d->m_dirty = true; 0380 } 0381 0382 void KFileMetaInfoWidget::slotChanged(double value) 0383 { 0384 Q_ASSERT(qobject_cast<QSpinBox *>(d->m_widget)); 0385 d->m_value = QVariant(value); 0386 emit valueChanged(d->m_value); 0387 d->m_dirty = true; 0388 } 0389 0390 void KFileMetaInfoWidget::slotComboChanged(const QString &value) 0391 { 0392 Q_ASSERT(qobject_cast<KComboBox *>(d->m_widget)); 0393 d->m_value = QVariant(value); 0394 emit valueChanged(d->m_value); 0395 d->m_dirty = true; 0396 } 0397 0398 void KFileMetaInfoWidget::slotLineEditChanged(const QString &value) 0399 { 0400 Q_ASSERT(qobject_cast<KLineEdit *>(d->m_widget)); 0401 d->m_value = QVariant(value); 0402 emit valueChanged(d->m_value); 0403 d->m_dirty = true; 0404 } 0405 0406 // that may be a little expensive for long texts, but what can we do? 0407 void KFileMetaInfoWidget::slotMultiLineEditChanged() 0408 { 0409 Q_ASSERT(qobject_cast<KTextEdit *>(d->m_widget)); 0410 d->m_value = QVariant(static_cast<const KTextEdit *>(sender())->toPlainText()); 0411 emit valueChanged(d->m_value); 0412 d->m_dirty = true; 0413 } 0414 0415 void KFileMetaInfoWidget::slotDateChanged(const QDate &value) 0416 { 0417 Q_ASSERT(qobject_cast<QDateEdit *>(d->m_widget)); 0418 d->m_value = QVariant(value); 0419 emit valueChanged(d->m_value); 0420 d->m_dirty = true; 0421 } 0422 0423 void KFileMetaInfoWidget::slotTimeChanged(const QTime &value) 0424 { 0425 Q_ASSERT(qobject_cast<QTimeEdit *>(d->m_widget)); 0426 d->m_value = QVariant(value); 0427 emit valueChanged(d->m_value); 0428 d->m_dirty = true; 0429 } 0430 0431 void KFileMetaInfoWidget::slotDateTimeChanged(const QDateTime &value) 0432 { 0433 Q_ASSERT(qobject_cast<QDateTimeEdit *>(d->m_widget)); 0434 d->m_value = QVariant(value); 0435 emit valueChanged(d->m_value); 0436 d->m_dirty = true; 0437 } 0438 0439 #include "moc_kfilemetainfowidget.cpp"