File indexing completed on 2023-12-10 04:59:17
0001 /* 0002 * Mount dialog 0003 * 0004 * SPDX-FileCopyrightText: 2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4kmountdialog.h" 0010 #include "core/smb4kbookmarkhandler.h" 0011 #include "core/smb4kglobal.h" 0012 #include "core/smb4kmounter.h" 0013 #include "core/smb4knotification.h" 0014 #include "core/smb4ksettings.h" 0015 0016 // Qt includes 0017 #include <QDialogButtonBox> 0018 #include <QFrame> 0019 #include <QGridLayout> 0020 #include <QHostAddress> 0021 #include <QLabel> 0022 #include <QSizePolicy> 0023 #include <QVBoxLayout> 0024 #include <QWindow> 0025 0026 // KDE includes 0027 #include <KConfigGroup> 0028 #include <KLocalizedString> 0029 #include <KWindowConfig> 0030 0031 Smb4KMountDialog::Smb4KMountDialog(QWidget *parent) 0032 : QDialog(parent) 0033 { 0034 setWindowTitle(i18n("Mount Dialog")); 0035 setAttribute(Qt::WA_DeleteOnClose); 0036 0037 QVBoxLayout *layout = new QVBoxLayout(this); 0038 0039 QWidget *descriptionWidget = new QWidget(this); 0040 0041 QHBoxLayout *descriptionWidgetLayout = new QHBoxLayout(descriptionWidget); 0042 0043 QLabel *descriptionPixmap = new QLabel(descriptionWidget); 0044 descriptionPixmap->setPixmap(KDE::icon(QStringLiteral("media-mount")).pixmap(KIconLoader::SizeHuge)); 0045 descriptionPixmap->setAlignment(Qt::AlignBottom); 0046 descriptionPixmap->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 0047 0048 descriptionWidgetLayout->addWidget(descriptionPixmap); 0049 0050 QLabel *descriptionText = new QLabel(this); 0051 descriptionText->setText(i18n("Enter the location and optionally the IP address and workgroup to mount a share.")); 0052 descriptionText->setWordWrap(true); 0053 descriptionText->setAlignment(Qt::AlignBottom); 0054 descriptionText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 0055 0056 descriptionWidgetLayout->addWidget(descriptionText); 0057 0058 layout->addWidget(descriptionWidget); 0059 0060 QWidget *inputWidget = new QWidget(this); 0061 0062 QGridLayout *inputWidgetLayout = new QGridLayout(inputWidget); 0063 inputWidgetLayout->setContentsMargins(0, 0, 0, 0); 0064 0065 QLabel *locationLabel = new QLabel(i18n("Location:"), inputWidget); 0066 m_locationInput = new KLineEdit(inputWidget); 0067 m_locationInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0068 m_locationInput->setClearButtonEnabled(true); 0069 m_locationInput->setFocus(); 0070 0071 connect(m_locationInput, &KLineEdit::textChanged, this, &Smb4KMountDialog::slotEnableButtons); 0072 connect(m_locationInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotLocationEntered); 0073 0074 QLabel *ipAddressLabel = new QLabel(i18n("IP Address:"), inputWidget); 0075 m_ipAddressInput = new KLineEdit(inputWidget); 0076 m_ipAddressInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0077 m_ipAddressInput->setClearButtonEnabled(true); 0078 0079 connect(m_ipAddressInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotIpAddressEntered); 0080 0081 QLabel *workgroupLabel = new QLabel(i18n("Workgroup:"), inputWidget); 0082 m_workgroupInput = new KLineEdit(inputWidget); 0083 m_workgroupInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0084 m_workgroupInput->setClearButtonEnabled(true); 0085 0086 connect(m_workgroupInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotWorkgroupEntered); 0087 0088 inputWidgetLayout->addWidget(locationLabel, 0, 0); 0089 inputWidgetLayout->addWidget(m_locationInput, 0, 1); 0090 inputWidgetLayout->addWidget(ipAddressLabel, 1, 0); 0091 inputWidgetLayout->addWidget(m_ipAddressInput, 1, 1); 0092 inputWidgetLayout->addWidget(workgroupLabel, 2, 0); 0093 inputWidgetLayout->addWidget(m_workgroupInput, 2, 1); 0094 0095 layout->addWidget(inputWidget); 0096 0097 m_bookmarkWidget = new QWidget(this); 0098 m_bookmarkWidget->setVisible(false); 0099 0100 QVBoxLayout *bookmarkWidgetLayout = new QVBoxLayout(m_bookmarkWidget); 0101 bookmarkWidgetLayout->setContentsMargins(0, 0, 0, 0); 0102 0103 QFrame *horizontalLine = new QFrame(m_bookmarkWidget); 0104 horizontalLine->setFrameShape(QFrame::HLine); 0105 0106 m_bookmarkShare = new QCheckBox(i18n("Bookmark this share"), m_bookmarkWidget); 0107 0108 connect(m_bookmarkShare, &QCheckBox::clicked, this, &Smb4KMountDialog::slotEnableBookmarkInputWidget); 0109 0110 m_bookmarkInputWidget = new QWidget(m_bookmarkWidget); 0111 m_bookmarkInputWidget->setEnabled(false); 0112 0113 QGridLayout *bookmarkInputWidgetLayout = new QGridLayout(m_bookmarkInputWidget); 0114 bookmarkInputWidgetLayout->setContentsMargins(0, 0, 0, 0); 0115 0116 QLabel *bookmarkLabelLabel = new QLabel(i18n("Label:"), m_bookmarkInputWidget); 0117 m_bookmarkLabelInput = new KLineEdit(m_bookmarkInputWidget); 0118 m_bookmarkLabelInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0119 m_bookmarkLabelInput->setClearButtonEnabled(true); 0120 0121 connect(m_bookmarkLabelInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotLabelEntered); 0122 0123 QLabel *bookmarkCategoryLabel = new QLabel(i18n("Category:"), m_bookmarkInputWidget); 0124 m_bookmarkCategoryInput = new KComboBox(m_bookmarkInputWidget); 0125 m_bookmarkCategoryInput->setEditable(true); 0126 m_bookmarkCategoryInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0127 m_bookmarkCategoryInput->lineEdit()->setClearButtonEnabled(true); 0128 0129 connect(m_bookmarkCategoryInput->lineEdit(), &QLineEdit::editingFinished, this, &Smb4KMountDialog::slotCategoryEntered); 0130 0131 bookmarkInputWidgetLayout->addWidget(bookmarkLabelLabel, 0, 0); 0132 bookmarkInputWidgetLayout->addWidget(m_bookmarkLabelInput, 0, 1); 0133 bookmarkInputWidgetLayout->addWidget(bookmarkCategoryLabel, 1, 0); 0134 bookmarkInputWidgetLayout->addWidget(m_bookmarkCategoryInput, 1, 1); 0135 0136 bookmarkWidgetLayout->addWidget(horizontalLine); 0137 bookmarkWidgetLayout->addWidget(m_bookmarkShare); 0138 bookmarkWidgetLayout->addWidget(m_bookmarkInputWidget); 0139 0140 layout->addWidget(m_bookmarkWidget); 0141 0142 QDialogButtonBox *buttonBox = new QDialogButtonBox(this); 0143 m_okButton = buttonBox->addButton(QDialogButtonBox::Ok); 0144 m_cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel); 0145 m_bookmarkButton = buttonBox->addButton(i18nc("Bookmark a share in the mount dialog.", "Bookmark >>"), QDialogButtonBox::ActionRole); 0146 0147 m_okButton->setEnabled(false); 0148 m_bookmarkButton->setEnabled(false); 0149 0150 connect(m_okButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotAccepted); 0151 connect(m_cancelButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotRejected); 0152 connect(m_bookmarkButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotBookmarkButtonClicked); 0153 0154 layout->addWidget(buttonBox); 0155 0156 setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350); 0157 0158 create(); 0159 0160 KConfigGroup dialogGroup(Smb4KSettings::self()->config(), "MountDialog"); 0161 QSize dialogSize; 0162 0163 if (dialogGroup.exists()) { 0164 KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup); 0165 dialogSize = windowHandle()->size(); 0166 } else { 0167 dialogSize = sizeHint(); 0168 } 0169 0170 resize(dialogSize); // workaround for QTBUG-40584 0171 0172 KConfigGroup completionGroup(Smb4KSettings::self()->config(), "CompletionItems"); 0173 0174 if (completionGroup.exists()) { 0175 m_locationInput->completionObject()->setItems(completionGroup.readEntry("LocationCompletion", QStringList())); 0176 m_ipAddressInput->completionObject()->setItems(completionGroup.readEntry("IpAddressCompletion", QStringList())); 0177 m_workgroupInput->completionObject()->setItems(completionGroup.readEntry("WorkgroupCompletion", QStringList())); 0178 m_bookmarkLabelInput->completionObject()->setItems(completionGroup.readEntry("LabelCompletion", QStringList())); 0179 m_bookmarkCategoryInput->completionObject()->setItems(completionGroup.readEntry("CategoryCompletion", Smb4KBookmarkHandler::self()->categoryList())); 0180 } 0181 } 0182 0183 Smb4KMountDialog::~Smb4KMountDialog() 0184 { 0185 } 0186 0187 bool Smb4KMountDialog::isValidLocation(const QString &text) 0188 { 0189 QString userInput = text; 0190 0191 if (userInput.startsWith(QStringLiteral("\\"))) { 0192 userInput.replace(QStringLiteral("\\"), QStringLiteral("/")); 0193 } 0194 0195 QUrl url = QUrl::fromUserInput(userInput).adjusted(QUrl::StripTrailingSlash); 0196 url.setScheme(QStringLiteral("smb")); 0197 0198 return (url.isValid() && !url.host().isEmpty() && !url.path().isEmpty() && url.path().length() != 1); 0199 } 0200 0201 void Smb4KMountDialog::adjustDialogSize() 0202 { 0203 ensurePolished(); 0204 layout()->activate(); 0205 0206 QSize dialogSize; 0207 dialogSize.setWidth(width()); 0208 dialogSize.setHeight(height() - m_bookmarkWidget->height() - layout()->contentsMargins().bottom() - layout()->contentsMargins().top()); 0209 0210 resize(dialogSize); 0211 } 0212 0213 void Smb4KMountDialog::slotEnableButtons(const QString &text) 0214 { 0215 bool enable = isValidLocation(text); 0216 m_okButton->setEnabled(enable); 0217 m_bookmarkButton->setEnabled(enable); 0218 } 0219 0220 void Smb4KMountDialog::slotBookmarkButtonClicked() 0221 { 0222 m_bookmarkWidget->setVisible(!m_bookmarkWidget->isVisible()); 0223 0224 if (!m_bookmarkWidget->isVisible()) { 0225 adjustDialogSize(); 0226 } 0227 } 0228 0229 void Smb4KMountDialog::slotEnableBookmarkInputWidget() 0230 { 0231 m_bookmarkInputWidget->setEnabled(m_bookmarkShare->isChecked()); 0232 } 0233 0234 void Smb4KMountDialog::slotLocationEntered() 0235 { 0236 QString userInputUrl = m_locationInput->userText().trimmed(); 0237 0238 if (userInputUrl.startsWith(QStringLiteral("\\"))) { 0239 userInputUrl.replace(QStringLiteral("\\"), QStringLiteral("/")); 0240 } 0241 0242 QUrl url = QUrl::fromUserInput(userInputUrl).adjusted(QUrl::StripTrailingSlash); 0243 url.setScheme(QStringLiteral("smb")); 0244 0245 if (isValidLocation(userInputUrl)) { 0246 m_locationInput->completionObject()->addItem(userInputUrl); 0247 } 0248 } 0249 0250 void Smb4KMountDialog::slotIpAddressEntered() 0251 { 0252 QString userInputIpAddress = m_ipAddressInput->userText().trimmed(); 0253 0254 if (!userInputIpAddress.isEmpty()) { 0255 m_ipAddressInput->completionObject()->addItem(userInputIpAddress); 0256 } 0257 } 0258 0259 void Smb4KMountDialog::slotWorkgroupEntered() 0260 { 0261 QString userInputWorkgroup = m_workgroupInput->userText().trimmed(); 0262 0263 if (!userInputWorkgroup.isEmpty()) { 0264 m_workgroupInput->completionObject()->addItem(userInputWorkgroup); 0265 } 0266 } 0267 0268 void Smb4KMountDialog::slotLabelEntered() 0269 { 0270 QString userInputLabel = m_bookmarkLabelInput->userText().trimmed(); 0271 0272 if (!userInputLabel.isEmpty()) { 0273 m_bookmarkLabelInput->completionObject()->addItem(userInputLabel); 0274 } 0275 } 0276 0277 void Smb4KMountDialog::slotCategoryEntered() 0278 { 0279 QString userInputCategory = m_bookmarkCategoryInput->currentText(); 0280 0281 if (!userInputCategory.isEmpty()) { 0282 m_bookmarkCategoryInput->completionObject()->addItem(userInputCategory); 0283 } 0284 } 0285 0286 void Smb4KMountDialog::slotAccepted() 0287 { 0288 QString userInputUrl = m_locationInput->userText().trimmed(); 0289 0290 if (userInputUrl.startsWith(QStringLiteral("\\"))) { 0291 userInputUrl.replace(QStringLiteral("\\"), QStringLiteral("/")); 0292 } 0293 0294 QUrl url = QUrl::fromUserInput(userInputUrl).adjusted(QUrl::StripTrailingSlash); 0295 url.setScheme(QStringLiteral("smb")); 0296 0297 // This case might never happen, because the buttons are only 0298 // enabled when isValidLocation() returns TRUE, but we leave 0299 // this here for safety. 0300 if (!isValidLocation(userInputUrl)) { 0301 m_locationInput->setFocus(); 0302 return; 0303 } 0304 0305 SharePtr share = SharePtr(new Smb4KShare()); 0306 share->setUrl(url); 0307 0308 BookmarkPtr bookmark = BookmarkPtr(new Smb4KBookmark()); 0309 bookmark->setUrl(url); 0310 0311 QHostAddress userIpAddressInput(m_ipAddressInput->userText().trimmed()); 0312 0313 if (userIpAddressInput.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { 0314 share->setHostIpAddress(userIpAddressInput.toString()); 0315 bookmark->setHostIpAddress(userIpAddressInput.toString()); 0316 } 0317 0318 QString userInputWorkgroup = m_workgroupInput->userText().trimmed(); 0319 0320 if (!userInputWorkgroup.isEmpty()) { 0321 share->setWorkgroupName(userInputWorkgroup); 0322 bookmark->setWorkgroupName(userInputWorkgroup); 0323 } 0324 0325 if (m_bookmarkShare->isChecked()) { 0326 bookmark->setLabel(m_bookmarkLabelInput->userText()); 0327 bookmark->setCategoryName(m_bookmarkCategoryInput->currentText()); 0328 0329 Smb4KBookmarkHandler::self()->addBookmark(bookmark); 0330 } 0331 0332 Smb4KMounter::self()->mountShare(share); 0333 0334 share.clear(); 0335 bookmark.clear(); 0336 0337 if (m_bookmarkWidget->isVisible()) { 0338 m_bookmarkInputWidget->setVisible(false); 0339 adjustDialogSize(); 0340 } 0341 0342 KConfigGroup dialogGroup(Smb4KSettings::self()->config(), "MountDialog"); 0343 KWindowConfig::saveWindowSize(windowHandle(), dialogGroup); 0344 0345 KConfigGroup completionGroup(Smb4KSettings::self()->config(), "CompletionItems"); 0346 completionGroup.writeEntry("LocationCompletion", m_locationInput->completionObject()->items()); 0347 completionGroup.writeEntry("IpAddressCompletion", m_ipAddressInput->completionObject()->items()); 0348 completionGroup.writeEntry("WorkgroupCompletion", m_workgroupInput->completionObject()->items()); 0349 completionGroup.writeEntry("LabelCompletion", m_bookmarkLabelInput->completionObject()->items()); 0350 completionGroup.writeEntry("CategoryCompletion", m_bookmarkCategoryInput->completionObject()->items()); 0351 0352 accept(); 0353 } 0354 0355 void Smb4KMountDialog::slotRejected() 0356 { 0357 reject(); 0358 }