File indexing completed on 2024-12-01 07:42:42
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 layout->addSpacing(layout->spacing()); 0060 0061 QWidget *inputWidget = new QWidget(this); 0062 0063 QGridLayout *inputWidgetLayout = new QGridLayout(inputWidget); 0064 inputWidgetLayout->setContentsMargins(0, 0, 0, 0); 0065 0066 QLabel *locationLabel = new QLabel(i18n("Location:"), inputWidget); 0067 m_locationInput = new KLineEdit(inputWidget); 0068 m_locationInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0069 m_locationInput->setClearButtonEnabled(true); 0070 m_locationInput->setFocus(); 0071 0072 connect(m_locationInput, &KLineEdit::textChanged, this, &Smb4KMountDialog::slotEnableButtons); 0073 connect(m_locationInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotLocationEntered); 0074 0075 QLabel *ipAddressLabel = new QLabel(i18n("IP Address:"), inputWidget); 0076 m_ipAddressInput = new KLineEdit(inputWidget); 0077 m_ipAddressInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0078 m_ipAddressInput->setClearButtonEnabled(true); 0079 0080 connect(m_ipAddressInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotIpAddressEntered); 0081 0082 QLabel *workgroupLabel = new QLabel(i18n("Workgroup:"), inputWidget); 0083 m_workgroupInput = new KLineEdit(inputWidget); 0084 m_workgroupInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0085 m_workgroupInput->setClearButtonEnabled(true); 0086 0087 connect(m_workgroupInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotWorkgroupEntered); 0088 0089 inputWidgetLayout->addWidget(locationLabel, 0, 0); 0090 inputWidgetLayout->addWidget(m_locationInput, 0, 1); 0091 inputWidgetLayout->addWidget(ipAddressLabel, 1, 0); 0092 inputWidgetLayout->addWidget(m_ipAddressInput, 1, 1); 0093 inputWidgetLayout->addWidget(workgroupLabel, 2, 0); 0094 inputWidgetLayout->addWidget(m_workgroupInput, 2, 1); 0095 0096 layout->addWidget(inputWidget); 0097 0098 m_bookmarkWidget = new QWidget(this); 0099 m_bookmarkWidget->setVisible(false); 0100 0101 QVBoxLayout *bookmarkWidgetLayout = new QVBoxLayout(m_bookmarkWidget); 0102 bookmarkWidgetLayout->setContentsMargins(0, 0, 0, 0); 0103 0104 QFrame *horizontalLine = new QFrame(m_bookmarkWidget); 0105 horizontalLine->setFrameShape(QFrame::HLine); 0106 0107 m_bookmarkShare = new QCheckBox(i18n("Bookmark this share"), m_bookmarkWidget); 0108 0109 connect(m_bookmarkShare, &QCheckBox::clicked, this, &Smb4KMountDialog::slotEnableBookmarkInputWidget); 0110 0111 m_bookmarkInputWidget = new QWidget(m_bookmarkWidget); 0112 m_bookmarkInputWidget->setEnabled(false); 0113 0114 QGridLayout *bookmarkInputWidgetLayout = new QGridLayout(m_bookmarkInputWidget); 0115 bookmarkInputWidgetLayout->setContentsMargins(0, 0, 0, 0); 0116 0117 QLabel *bookmarkLabelLabel = new QLabel(i18n("Label:"), m_bookmarkInputWidget); 0118 m_bookmarkLabelInput = new KLineEdit(m_bookmarkInputWidget); 0119 m_bookmarkLabelInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0120 m_bookmarkLabelInput->setClearButtonEnabled(true); 0121 0122 connect(m_bookmarkLabelInput, &KLineEdit::editingFinished, this, &Smb4KMountDialog::slotLabelEntered); 0123 0124 QLabel *bookmarkCategoryLabel = new QLabel(i18n("Category:"), m_bookmarkInputWidget); 0125 m_bookmarkCategoryInput = new KComboBox(m_bookmarkInputWidget); 0126 m_bookmarkCategoryInput->setEditable(true); 0127 m_bookmarkCategoryInput->setCompletionMode(KCompletion::CompletionPopupAuto); 0128 m_bookmarkCategoryInput->lineEdit()->setClearButtonEnabled(true); 0129 0130 connect(m_bookmarkCategoryInput->lineEdit(), &QLineEdit::editingFinished, this, &Smb4KMountDialog::slotCategoryEntered); 0131 0132 bookmarkInputWidgetLayout->addWidget(bookmarkLabelLabel, 0, 0); 0133 bookmarkInputWidgetLayout->addWidget(m_bookmarkLabelInput, 0, 1); 0134 bookmarkInputWidgetLayout->addWidget(bookmarkCategoryLabel, 1, 0); 0135 bookmarkInputWidgetLayout->addWidget(m_bookmarkCategoryInput, 1, 1); 0136 0137 bookmarkWidgetLayout->addWidget(horizontalLine); 0138 bookmarkWidgetLayout->addWidget(m_bookmarkShare); 0139 bookmarkWidgetLayout->addWidget(m_bookmarkInputWidget); 0140 0141 layout->addWidget(m_bookmarkWidget); 0142 0143 QDialogButtonBox *buttonBox = new QDialogButtonBox(this); 0144 m_okButton = buttonBox->addButton(QDialogButtonBox::Ok); 0145 m_cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel); 0146 m_bookmarkButton = buttonBox->addButton(i18nc("Bookmark a share in the mount dialog.", "Bookmark >>"), QDialogButtonBox::ActionRole); 0147 0148 m_okButton->setEnabled(false); 0149 m_bookmarkButton->setEnabled(false); 0150 0151 connect(m_okButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotAccepted); 0152 connect(m_cancelButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotRejected); 0153 connect(m_bookmarkButton, &QPushButton::clicked, this, &Smb4KMountDialog::slotBookmarkButtonClicked); 0154 0155 layout->addWidget(buttonBox); 0156 0157 setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350); 0158 0159 create(); 0160 0161 KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("MountDialog")); 0162 QSize dialogSize; 0163 0164 if (dialogGroup.exists()) { 0165 KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup); 0166 dialogSize = windowHandle()->size(); 0167 } else { 0168 dialogSize = sizeHint(); 0169 } 0170 0171 resize(dialogSize); // workaround for QTBUG-40584 0172 0173 KConfigGroup completionGroup(Smb4KSettings::self()->config(), QStringLiteral("CompletionItems")); 0174 0175 if (completionGroup.exists()) { 0176 m_locationInput->completionObject()->setItems(completionGroup.readEntry("LocationCompletion", QStringList())); 0177 m_ipAddressInput->completionObject()->setItems(completionGroup.readEntry("IpAddressCompletion", QStringList())); 0178 m_workgroupInput->completionObject()->setItems(completionGroup.readEntry("WorkgroupCompletion", QStringList())); 0179 m_bookmarkLabelInput->completionObject()->setItems(completionGroup.readEntry("LabelCompletion", QStringList())); 0180 m_bookmarkCategoryInput->completionObject()->setItems(completionGroup.readEntry("CategoryCompletion", Smb4KBookmarkHandler::self()->categoryList())); 0181 } 0182 } 0183 0184 Smb4KMountDialog::~Smb4KMountDialog() 0185 { 0186 } 0187 0188 bool Smb4KMountDialog::isValidLocation(const QString &text) 0189 { 0190 QString userInput = text; 0191 0192 if (userInput.startsWith(QStringLiteral("\\"))) { 0193 userInput.replace(QStringLiteral("\\"), QStringLiteral("/")); 0194 } 0195 0196 QUrl url = QUrl::fromUserInput(userInput).adjusted(QUrl::StripTrailingSlash); 0197 url.setScheme(QStringLiteral("smb")); 0198 0199 return (url.isValid() && !url.host().isEmpty() && !url.path().isEmpty() && url.path().length() != 1); 0200 } 0201 0202 void Smb4KMountDialog::adjustDialogSize() 0203 { 0204 ensurePolished(); 0205 layout()->activate(); 0206 0207 QSize dialogSize; 0208 dialogSize.setWidth(width()); 0209 dialogSize.setHeight(height() - m_bookmarkWidget->height() - layout()->contentsMargins().bottom() - layout()->contentsMargins().top()); 0210 0211 resize(dialogSize); 0212 } 0213 0214 void Smb4KMountDialog::slotEnableButtons(const QString &text) 0215 { 0216 bool enable = isValidLocation(text); 0217 m_okButton->setEnabled(enable); 0218 m_bookmarkButton->setEnabled(enable); 0219 } 0220 0221 void Smb4KMountDialog::slotBookmarkButtonClicked() 0222 { 0223 m_bookmarkWidget->setVisible(!m_bookmarkWidget->isVisible()); 0224 0225 if (!m_bookmarkWidget->isVisible()) { 0226 adjustDialogSize(); 0227 } 0228 } 0229 0230 void Smb4KMountDialog::slotEnableBookmarkInputWidget() 0231 { 0232 m_bookmarkInputWidget->setEnabled(m_bookmarkShare->isChecked()); 0233 } 0234 0235 void Smb4KMountDialog::slotLocationEntered() 0236 { 0237 QString userInputUrl = m_locationInput->userText().trimmed(); 0238 0239 if (userInputUrl.startsWith(QStringLiteral("\\"))) { 0240 userInputUrl.replace(QStringLiteral("\\"), QStringLiteral("/")); 0241 } 0242 0243 QUrl url = QUrl::fromUserInput(userInputUrl).adjusted(QUrl::StripTrailingSlash); 0244 url.setScheme(QStringLiteral("smb")); 0245 0246 if (isValidLocation(userInputUrl)) { 0247 m_locationInput->completionObject()->addItem(userInputUrl); 0248 } 0249 } 0250 0251 void Smb4KMountDialog::slotIpAddressEntered() 0252 { 0253 QString userInputIpAddress = m_ipAddressInput->userText().trimmed(); 0254 0255 if (!userInputIpAddress.isEmpty()) { 0256 m_ipAddressInput->completionObject()->addItem(userInputIpAddress); 0257 } 0258 } 0259 0260 void Smb4KMountDialog::slotWorkgroupEntered() 0261 { 0262 QString userInputWorkgroup = m_workgroupInput->userText().trimmed(); 0263 0264 if (!userInputWorkgroup.isEmpty()) { 0265 m_workgroupInput->completionObject()->addItem(userInputWorkgroup); 0266 } 0267 } 0268 0269 void Smb4KMountDialog::slotLabelEntered() 0270 { 0271 QString userInputLabel = m_bookmarkLabelInput->userText().trimmed(); 0272 0273 if (!userInputLabel.isEmpty()) { 0274 m_bookmarkLabelInput->completionObject()->addItem(userInputLabel); 0275 } 0276 } 0277 0278 void Smb4KMountDialog::slotCategoryEntered() 0279 { 0280 QString userInputCategory = m_bookmarkCategoryInput->currentText(); 0281 0282 if (!userInputCategory.isEmpty()) { 0283 m_bookmarkCategoryInput->completionObject()->addItem(userInputCategory); 0284 } 0285 } 0286 0287 void Smb4KMountDialog::slotAccepted() 0288 { 0289 QString userInputUrl = m_locationInput->userText().trimmed(); 0290 0291 if (userInputUrl.startsWith(QStringLiteral("\\"))) { 0292 userInputUrl.replace(QStringLiteral("\\"), QStringLiteral("/")); 0293 } 0294 0295 QUrl url = QUrl::fromUserInput(userInputUrl).adjusted(QUrl::StripTrailingSlash); 0296 url.setScheme(QStringLiteral("smb")); 0297 0298 // This case might never happen, because the buttons are only 0299 // enabled when isValidLocation() returns TRUE, but we leave 0300 // this here for safety. 0301 if (!isValidLocation(userInputUrl)) { 0302 m_locationInput->setFocus(); 0303 return; 0304 } 0305 0306 SharePtr share = SharePtr(new Smb4KShare()); 0307 share->setUrl(url); 0308 0309 BookmarkPtr bookmark = BookmarkPtr(new Smb4KBookmark()); 0310 bookmark->setUrl(url); 0311 0312 QHostAddress userIpAddressInput(m_ipAddressInput->userText().trimmed()); 0313 0314 if (userIpAddressInput.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { 0315 share->setHostIpAddress(userIpAddressInput.toString()); 0316 bookmark->setHostIpAddress(userIpAddressInput.toString()); 0317 } 0318 0319 QString userInputWorkgroup = m_workgroupInput->userText().trimmed(); 0320 0321 if (!userInputWorkgroup.isEmpty()) { 0322 share->setWorkgroupName(userInputWorkgroup); 0323 bookmark->setWorkgroupName(userInputWorkgroup); 0324 } 0325 0326 if (m_bookmarkShare->isChecked()) { 0327 bookmark->setLabel(m_bookmarkLabelInput->userText()); 0328 bookmark->setCategoryName(m_bookmarkCategoryInput->currentText()); 0329 0330 Smb4KBookmarkHandler::self()->addBookmark(bookmark); 0331 } 0332 0333 Smb4KMounter::self()->mountShare(share); 0334 0335 share.clear(); 0336 bookmark.clear(); 0337 0338 if (m_bookmarkWidget->isVisible()) { 0339 m_bookmarkInputWidget->setVisible(false); 0340 adjustDialogSize(); 0341 } 0342 0343 KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("MountDialog")); 0344 KWindowConfig::saveWindowSize(windowHandle(), dialogGroup); 0345 0346 KConfigGroup completionGroup(Smb4KSettings::self()->config(), QStringLiteral("CompletionItems")); 0347 completionGroup.writeEntry("LocationCompletion", m_locationInput->completionObject()->items()); 0348 completionGroup.writeEntry("IpAddressCompletion", m_ipAddressInput->completionObject()->items()); 0349 completionGroup.writeEntry("WorkgroupCompletion", m_workgroupInput->completionObject()->items()); 0350 completionGroup.writeEntry("LabelCompletion", m_bookmarkLabelInput->completionObject()->items()); 0351 completionGroup.writeEntry("CategoryCompletion", m_bookmarkCategoryInput->completionObject()->items()); 0352 0353 accept(); 0354 } 0355 0356 void Smb4KMountDialog::slotRejected() 0357 { 0358 reject(); 0359 }