File indexing completed on 2024-05-05 16:08:27

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"