File indexing completed on 2024-05-12 05:09:47

0001 /***************************************************************************
0002     Copyright (C) 2003-2021 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "fieldwidget.h"
0026 #include "../field.h"
0027 #include "../tellico_debug.h"
0028 
0029 #include <KUrlLabel>
0030 #include <KLocalizedString>
0031 
0032 #include <QWhatsThis>
0033 #include <QLabel>
0034 #include <QCheckBox>
0035 #include <QStyle>
0036 #include <QHBoxLayout>
0037 
0038 namespace {
0039   // if you change this, update numberfieldwidget, too
0040   const int FIELD_EDIT_WIDGET_INDEX = 2;
0041 }
0042 
0043 using Tellico::GUI::FieldWidget;
0044 
0045 FieldWidget::FieldWidget(Tellico::Data::FieldPtr field_, QWidget* parent_)
0046     : QWidget(parent_), m_field(field_), m_settingText(false) {
0047   QHBoxLayout* l = new QHBoxLayout(this);
0048   l->setMargin(2);
0049   l->setSpacing(2);
0050   l->addSpacing(4); // add some more space in the columns between widgets
0051 
0052   Q_ASSERT(field_);
0053   Data::Field::Type type = field_->type();
0054   QString s = i18nc("Edit Label", "%1:", field_->title());
0055   if(type == Data::Field::URL) {
0056     // set URL to empty for now
0057     m_label = new KUrlLabel(QString(), s, this);
0058   } else {
0059     m_label = new QLabel(s, this);
0060   }
0061   m_label->setFixedWidth(m_label->sizeHint().width());
0062   l->addWidget(m_label);
0063 
0064   if(field_->isSingleCategory()) {
0065     m_label->hide();
0066   }
0067 
0068   // expands indicates if the edit widget should expand to full width of widget
0069   m_expands = (type == Data::Field::Line
0070                || type == Data::Field::Para
0071                || type == Data::Field::Number
0072                || type == Data::Field::URL
0073                || type == Data::Field::Table
0074                || type == Data::Field::Table2
0075                || type == Data::Field::Image
0076                || type == Data::Field::Date);
0077 
0078   m_editMultiple = new QCheckBox(this);
0079   m_editMultiple->setChecked(true);
0080   m_editMultiple->setFixedWidth(m_editMultiple->sizeHint().width()); // don't let it have any extra space
0081   connect(m_editMultiple, &QCheckBox::toggled, this, &FieldWidget::setEnabled);
0082   l->addWidget(m_editMultiple);
0083 
0084   setWhatsThis(field_->description());
0085 }
0086 
0087 void FieldWidget::insertDefault() {
0088   setText(m_field->defaultValue());
0089 }
0090 
0091 bool FieldWidget::isEnabled() {
0092   return widget()->isEnabled();
0093 }
0094 
0095 void FieldWidget::setEnabled(bool enabled_) {
0096   if(enabled_ == isEnabled()) {
0097     return;
0098   }
0099 
0100   widget()->setEnabled(enabled_);
0101   m_editMultiple->setChecked(enabled_);
0102 }
0103 
0104 void FieldWidget::setText(const QString& text_) {
0105   m_oldValue = text_;
0106   m_settingText = true;
0107   setTextImpl(text_);
0108   m_oldValue = text(); // the widget might have clean-up the text after being set
0109   m_settingText = false;
0110   // now check to see if the widget modified the text
0111   checkModified();
0112 }
0113 
0114 void FieldWidget::clear() {
0115   m_oldValue.clear();
0116   clearImpl();
0117 }
0118 
0119 int FieldWidget::labelWidth() const {
0120   return m_label->sizeHint().width();
0121 }
0122 
0123 void FieldWidget::setLabelWidth(int width_) {
0124   m_label->setFixedWidth(width_);
0125 }
0126 
0127 bool FieldWidget::expands() const {
0128   return m_expands;
0129 }
0130 
0131 void FieldWidget::editMultiple(bool show_) {
0132   if(show_ == !m_editMultiple->isHidden()) {
0133     return;
0134   }
0135 
0136   // FIXME: maybe valueChanged should only be signaled when the button is toggled on
0137   if(show_) {
0138     m_editMultiple->show();
0139     connect(m_editMultiple, &QAbstractButton::clicked, this, &FieldWidget::multipleChecked);
0140   } else {
0141     m_editMultiple->hide();
0142     disconnect(m_editMultiple, &QAbstractButton::clicked, this, &FieldWidget::multipleChecked);
0143   }
0144   // the widget length needs to be updated since it gets shorter
0145   widget()->updateGeometry();
0146 }
0147 
0148 void FieldWidget::registerWidget() {
0149   QWidget* w = widget();
0150   m_label->setBuddy(w);
0151   if(w->focusPolicy() != Qt::NoFocus) {
0152     setFocusProxy(w);
0153   }
0154 
0155   QHBoxLayout* l = static_cast<QHBoxLayout*>(layout());
0156   l->insertWidget(FIELD_EDIT_WIDGET_INDEX, w, m_expands ? 1 : 0 /*stretch*/);
0157   if(!m_expands) {
0158     l->insertStretch(FIELD_EDIT_WIDGET_INDEX+1, 1 /*stretch*/);
0159   }
0160   updateGeometry();
0161 }
0162 
0163 void FieldWidget::setField(Tellico::Data::FieldPtr field_) {
0164   m_field = field_;
0165 }
0166 
0167 void FieldWidget::updateField(Tellico::Data::FieldPtr oldField_, Tellico::Data::FieldPtr newField_) {
0168   m_field = newField_;
0169   m_label->setText(i18nc("Edit Label", "%1:", newField_->title()));
0170   updateGeometry();
0171   setWhatsThis(newField_->description());
0172   updateFieldHook(oldField_, newField_);
0173 }
0174 
0175 void FieldWidget::checkModified() {
0176   // some of the widgets have signals that fire when the text is modified
0177   // in particular, the tablewidget used to prune empty rows when text() was called
0178   // just to guard against that in the future, don't emit anything if
0179   // we're in the process of setting the text
0180   if(m_settingText) {
0181     return;
0182   }
0183   const QString value = text();
0184   if(value != m_oldValue) {
0185 //    myDebug() << "old value:" << m_oldValue << "| new value:" << value;
0186     m_oldValue = value;
0187     emit valueChanged(m_field);
0188   }
0189 }
0190 
0191 void FieldWidget::multipleChecked() {
0192   emit valueChanged(m_field);
0193 }