File indexing completed on 2024-05-12 05:14:53
0001 /* 0002 * pickfileradio.cpp - radio button with an associated file picker 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2005-2020 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "pickfileradio.h" 0010 0011 #include "lib/buttongroup.h" 0012 #include "lib/lineedit.h" 0013 0014 #include <QPushButton> 0015 #include <QTimer> 0016 0017 0018 PickFileRadio::PickFileRadio(QPushButton* button, LineEdit* edit, const QString& text, ButtonGroup* group, QWidget* parent) 0019 : RadioButton(text, parent) 0020 , mGroup(group) 0021 { 0022 Q_ASSERT(parent); 0023 init(button, edit); 0024 } 0025 0026 PickFileRadio::PickFileRadio(const QString& text, ButtonGroup* group, QWidget* parent) 0027 : RadioButton(text, parent) 0028 , mGroup(group) 0029 , mButton(nullptr) 0030 { 0031 Q_ASSERT(parent); 0032 } 0033 0034 void PickFileRadio::init(QPushButton* button, LineEdit* edit) 0035 { 0036 Q_ASSERT(button); 0037 if (mEdit) 0038 mEdit->disconnect(this); 0039 mEdit = edit; 0040 mButton = button; 0041 mButton->setEnabled(false); 0042 connect(mButton, &QPushButton::clicked, this, &PickFileRadio::slotPickFile); 0043 if (mEdit) 0044 { 0045 mEdit->setEnabled(false); 0046 connect(mEdit, &LineEdit::textChanged, this, &PickFileRadio::fileChanged); 0047 } 0048 connect(mGroup, &ButtonGroup::buttonSet, this, &PickFileRadio::slotSelectionChanged); 0049 PickFileRadio::setReadOnly(RadioButton::isReadOnly()); // avoid calling virtual method from constructor 0050 } 0051 0052 void PickFileRadio::setReadOnly(bool ro) 0053 { 0054 RadioButton::setReadOnly(ro); 0055 if (mButton) 0056 { 0057 if (mEdit) 0058 mEdit->setReadOnly(ro); 0059 if (ro) 0060 mButton->hide(); 0061 else 0062 mButton->show(); 0063 } 0064 } 0065 0066 void PickFileRadio::setFile(const QString& file) 0067 { 0068 mFile = file; 0069 } 0070 0071 QString PickFileRadio::file() const 0072 { 0073 return mEdit ? mEdit->text() : mFile; 0074 } 0075 0076 /****************************************************************************** 0077 * Set the radio button enabled or disabled. 0078 * Adjusts the enabled/disabled state of other controls appropriately. 0079 */ 0080 void PickFileRadio::setEnabled(bool enable) 0081 { 0082 Q_ASSERT(mButton); 0083 RadioButton::setEnabled(enable); 0084 enable = enable && mGroup->checkedButton() == this; 0085 if (enable) 0086 { 0087 if (!pickFileIfNone()) 0088 enable = false; // revert to previously selected type 0089 } 0090 mButton->setEnabled(enable); 0091 if (mEdit) 0092 mEdit->setEnabled(enable); 0093 } 0094 0095 /****************************************************************************** 0096 * Called when the selected radio button changes. 0097 */ 0098 void PickFileRadio::slotSelectionChanged(QAbstractButton* button) 0099 { 0100 if (button == mLastButton || mRevertButton) 0101 return; 0102 if (mLastButton == this) 0103 { 0104 mButton->setEnabled(false); 0105 if (mEdit) 0106 mEdit->setEnabled(false); 0107 } 0108 else if (button == this) 0109 { 0110 if (!pickFileIfNone()) 0111 return; // revert to previously selected type 0112 mButton->setEnabled(true); 0113 if (mEdit) 0114 mEdit->setEnabled(true); 0115 } 0116 mLastButton = button; 0117 } 0118 0119 /****************************************************************************** 0120 * Prompt for a file name if there is none currently entered. 0121 */ 0122 bool PickFileRadio::pickFileIfNone() 0123 { 0124 if (mEdit) 0125 mFile = mEdit->text(); 0126 if (!mFile.isEmpty()) 0127 return true; 0128 QString file; 0129 if (!doPickFile(file)) 0130 return false; 0131 return !mFile.isEmpty(); 0132 } 0133 0134 /****************************************************************************** 0135 * Called when the file picker button is clicked. 0136 */ 0137 void PickFileRadio::slotPickFile() 0138 { 0139 QString file; 0140 doPickFile(file); 0141 } 0142 0143 /****************************************************************************** 0144 * Called when the file picker button is clicked. 0145 * @param file Updated with the file which was selected, or empty if no file 0146 * was selected. 0147 * Reply = true if 'file' value can be used. 0148 * = false if the dialogue was deleted while visible (indicating that 0149 * the parent widget was probably also deleted). 0150 */ 0151 bool PickFileRadio::doPickFile(QString& file) 0152 { 0153 // To avoid crashes on application quit, we need to check whether the 0154 // dialogue, and hence this PickFileRadio, was deleted while active, 0155 // before accessing class members. 0156 file.clear(); 0157 if (!pickFile(file)) 0158 return false; // 'this' is probably invalid now 0159 if (!file.isEmpty()) 0160 { 0161 mFile = file; 0162 if (mEdit) 0163 mEdit->setText(mFile); 0164 } 0165 if (mFile.isEmpty()) 0166 { 0167 // No file is selected, so revert to the previous radio button selection. 0168 // But wait a moment before setting the radio button, or it won't work. 0169 mRevertButton = true; // prevent picker dialog popping up twice 0170 QTimer::singleShot(0, this, &PickFileRadio::setLastButton); //NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) 0171 } 0172 file = mFile; 0173 return true; 0174 } 0175 0176 /****************************************************************************** 0177 * Select the previously selected radio button in the group. 0178 */ 0179 void PickFileRadio::setLastButton() 0180 { 0181 if (!mLastButton) 0182 setChecked(false); // we don't know the previous selection, so just turn this button off 0183 else 0184 mLastButton->setChecked(true); 0185 mRevertButton = false; 0186 } 0187 0188 #include "moc_pickfileradio.cpp" 0189 0190 // vim: et sw=4: