File indexing completed on 2024-04-21 15:42:55

0001 /***************************************************************************
0002     The configuration page for the mount options
0003                              -------------------
0004     begin                : So Mär 22 2015
0005     copyright            : (C) 2015-2019 by Alexander Reinholdt
0006     email                : alexander.reinholdt@kdemail.net
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful, but   *
0016  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
0018  *   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, write to the                         *
0022  *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
0023  *   MA 02110-1335, USA                                                    *
0024  ***************************************************************************/
0025 
0026 #ifdef HAVE_CONFIG_H
0027 #include <config.h>
0028 #endif
0029 
0030 // application specific includes
0031 #include "smb4kconfigpagemounting.h"
0032 #include "core/smb4kglobal.h"
0033 
0034 #if defined(Q_OS_LINUX)
0035 #include "core/smb4kmountsettings_linux.h"
0036 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
0037 #include "core/smb4kmountsettings_bsd.h"
0038 #endif
0039 
0040 // Qt includes
0041 #include <QVBoxLayout>
0042 #include <QGroupBox>
0043 #include <QLabel>
0044 #include <QToolButton>
0045 #include <QMenu>
0046 #include <QCheckBox>
0047 #include <QInputDialog>
0048 #include <QSpinBox>
0049 
0050 // KDE includes
0051 #include <KI18n/KLocalizedString>
0052 #include <KCompletion/KLineEdit>
0053 #include <KCompletion/KComboBox>
0054 #include <KIconThemes/KIconLoader>
0055 #include <KWidgetsAddons/KMessageBox>
0056 #include <KIOWidgets/KUrlRequester>
0057 
0058 using namespace Smb4KGlobal;
0059 
0060 
0061 Smb4KConfigPageMounting::Smb4KConfigPageMounting(QWidget* parent): QTabWidget(parent)
0062 {
0063   setupWidget();
0064 }
0065 
0066 
0067 Smb4KConfigPageMounting::~Smb4KConfigPageMounting()
0068 {
0069 }
0070 
0071 
0072 #if defined(Q_OS_LINUX)
0073 //
0074 // Linux
0075 //
0076 void Smb4KConfigPageMounting::setupWidget()
0077 {
0078   //
0079   // Basic Settings tab
0080   // 
0081   QWidget *basicTab = new QWidget(this);
0082   QVBoxLayout *basicTabLayout = new QVBoxLayout(basicTab);
0083   basicTabLayout->setSpacing(5);
0084   basicTabLayout->setMargin(0);
0085   
0086   //
0087   // Directories
0088   // 
0089   QGroupBox *directoryBox = new QGroupBox(i18n("Directories"), basicTab);
0090 
0091   QGridLayout *directoryBoxLayout = new QGridLayout(directoryBox);
0092   directoryBoxLayout->setSpacing(5);
0093 
0094   QLabel *prefixLabel = new QLabel(Smb4KMountSettings::self()->mountPrefixItem()->label(), directoryBox);
0095   KUrlRequester *prefix = new KUrlRequester(directoryBox);
0096   prefix->setMode(KFile::Directory | KFile::LocalOnly);
0097   prefix->setObjectName("kcfg_MountPrefix");
0098 
0099   prefixLabel->setBuddy(prefix);
0100   
0101   QCheckBox *lowercaseSubdirs = new QCheckBox(Smb4KMountSettings::self()->forceLowerCaseSubdirsItem()->label(), directoryBox);
0102   lowercaseSubdirs->setObjectName("kcfg_ForceLowerCaseSubdirs");
0103 
0104   directoryBoxLayout->addWidget(prefixLabel, 0, 0, 0);
0105   directoryBoxLayout->addWidget(prefix, 0, 1, 0);
0106   directoryBoxLayout->addWidget(lowercaseSubdirs, 1, 0, 1, 2, 0);
0107   
0108   basicTabLayout->addWidget(directoryBox, 0);
0109   
0110   // 
0111   // Behavior
0112   // 
0113   QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), this);
0114   QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox);
0115   behaviorBoxLayout->setSpacing(5);
0116   
0117   QCheckBox *remountShares = new QCheckBox(Smb4KMountSettings::self()->remountSharesItem()->label(), behaviorBox);
0118   remountShares->setObjectName("kcfg_RemountShares");
0119   
0120   QLabel *remountAttemptsLabel = new QLabel(Smb4KMountSettings::self()->remountAttemptsItem()->label(), behaviorBox);
0121   remountAttemptsLabel->setIndent(25);
0122   
0123   QSpinBox *remountAttempts = new QSpinBox(behaviorBox);
0124   remountAttempts->setObjectName("kcfg_RemountAttempts");
0125   remountAttemptsLabel->setBuddy(remountAttempts);
0126   
0127   QLabel *remountIntervalLabel = new QLabel(Smb4KMountSettings::self()->remountIntervalItem()->label(), behaviorBox);
0128   remountIntervalLabel->setIndent(25);
0129   
0130   QSpinBox *remountInterval = new QSpinBox(behaviorBox);
0131   remountInterval->setObjectName("kcfg_RemountInterval");
0132   remountInterval->setSuffix(i18n(" min"));
0133   remountIntervalLabel->setBuddy(remountInterval);
0134 
0135   QCheckBox *unmountAllShares = new QCheckBox(Smb4KMountSettings::self()->unmountSharesOnExitItem()->label(), behaviorBox);
0136   unmountAllShares->setObjectName("kcfg_UnmountSharesOnExit");
0137   
0138   QCheckBox *unmountForeignShares = new QCheckBox(Smb4KMountSettings::self()->unmountForeignSharesItem()->label(), behaviorBox);
0139   unmountForeignShares->setObjectName("kcfg_UnmountForeignShares");
0140 
0141   QCheckBox *unmountInaccessibleShares = new QCheckBox(Smb4KMountSettings::self()->forceUnmountInaccessibleItem()->label(), behaviorBox);
0142   unmountInaccessibleShares->setObjectName("kcfg_ForceUnmountInaccessible");
0143   
0144   QCheckBox *detectAllShares = new QCheckBox(Smb4KMountSettings::self()->detectAllSharesItem()->label(), behaviorBox);
0145   detectAllShares->setObjectName("kcfg_DetectAllShares");
0146 
0147   behaviorBoxLayout->addWidget(remountShares, 0, 0, 1, 2, 0);
0148   behaviorBoxLayout->addWidget(remountAttemptsLabel, 1, 0, 0);
0149   behaviorBoxLayout->addWidget(remountAttempts, 1, 1, 0);
0150   behaviorBoxLayout->addWidget(remountIntervalLabel, 2, 0, 0);
0151   behaviorBoxLayout->addWidget(remountInterval, 2, 1, 0);
0152   behaviorBoxLayout->addWidget(unmountAllShares, 3, 0, 1, 2, 0);
0153   behaviorBoxLayout->addWidget(unmountInaccessibleShares, 4, 0, 1, 2, 0);
0154   behaviorBoxLayout->addWidget(unmountForeignShares, 5, 0, 1, 2, 0);
0155   behaviorBoxLayout->addWidget(detectAllShares, 6, 0, 1, 2, 0);
0156   
0157   basicTabLayout->addWidget(behaviorBox, 0);
0158   basicTabLayout->addStretch(100);
0159   
0160   addTab(basicTab, i18n("Basic Settings"));
0161   
0162   //
0163   // Common Mount Settings tab
0164   //
0165   QWidget *commonTab = new QWidget(this);
0166   QVBoxLayout *commonTabLayout = new QVBoxLayout(commonTab);
0167   commonTabLayout->setSpacing(5);
0168   commonTabLayout->setMargin(0);
0169 
0170   // 
0171   // Common options group box
0172   // 
0173   QGroupBox *commonOptions = new QGroupBox(i18n("Common Options"), commonTab);
0174 
0175   QGridLayout *commonOptionsLayout = new QGridLayout(commonOptions);
0176   commonOptionsLayout->setSpacing(5);
0177 
0178   // Write access
0179   QCheckBox *useWriteAccess = new QCheckBox(Smb4KMountSettings::self()->useWriteAccessItem()->label(), commonOptions);
0180   useWriteAccess->setObjectName("kcfg_UseWriteAccess");
0181 
0182   KComboBox *writeAccess = new KComboBox(commonOptions);
0183   writeAccess->setObjectName("kcfg_WriteAccess");
0184   
0185   QList<KCoreConfigSkeleton::ItemEnum::Choice> writeAccessChoices = Smb4KMountSettings::self()->writeAccessItem()->choices();
0186   
0187   for (const KCoreConfigSkeleton::ItemEnum::Choice &wa : writeAccessChoices)
0188   {
0189     writeAccess->addItem(wa.label);
0190   }
0191   
0192   commonOptionsLayout->addWidget(useWriteAccess, 0, 0, 0);
0193   commonOptionsLayout->addWidget(writeAccess, 0, 1, 0);
0194 
0195   // Character set
0196   QCheckBox *useCharacterSet = new QCheckBox(Smb4KMountSettings::self()->useClientCharsetItem()->label(), commonOptions);
0197   useCharacterSet->setObjectName("kcfg_UseClientCharset");
0198 
0199   KComboBox *characterSet = new KComboBox(commonOptions);
0200   characterSet->setObjectName("kcfg_ClientCharset");
0201   
0202   QList<KCoreConfigSkeleton::ItemEnum::Choice> charsetChoices = Smb4KMountSettings::self()->clientCharsetItem()->choices();
0203   
0204   for (const KCoreConfigSkeleton::ItemEnum::Choice &c : charsetChoices)
0205   {
0206     characterSet->addItem(c.label);
0207   }
0208   
0209   commonOptionsLayout->addWidget(useCharacterSet, 1, 0, 0);
0210   commonOptionsLayout->addWidget(characterSet, 1, 1, 0);
0211 
0212   // Remote filesystem port
0213   QCheckBox *useFilesystemPort = new QCheckBox(Smb4KMountSettings::self()->useRemoteFileSystemPortItem()->label(), commonOptions);
0214   useFilesystemPort->setObjectName("kcfg_UseRemoteFileSystemPort");
0215   
0216   QSpinBox *filesystemPort = new QSpinBox(commonOptions);
0217   filesystemPort->setObjectName("kcfg_RemoteFileSystemPort");
0218 
0219   commonOptionsLayout->addWidget(useFilesystemPort, 2, 0, 0);
0220   commonOptionsLayout->addWidget(filesystemPort, 2, 1, 0);
0221   
0222   commonTabLayout->addWidget(commonOptions, 0);
0223   
0224   //
0225   // CIFS Unix Extensions Support group box
0226   // 
0227   QGroupBox *cifsExtensionSupportBox= new QGroupBox(i18n("CIFS Unix Extensions Support"), commonTab);
0228   
0229   QGridLayout *cifsExtensionSupportLayout = new QGridLayout(cifsExtensionSupportBox);
0230   cifsExtensionSupportLayout->setSpacing(5);
0231   
0232   // CIFS Unix extensions support
0233   QCheckBox *cifsExtensionsSupport = new QCheckBox(Smb4KMountSettings::self()->cifsUnixExtensionsSupportItem()->label(), cifsExtensionSupportBox);
0234   cifsExtensionsSupport->setObjectName("kcfg_CifsUnixExtensionsSupport");
0235   
0236   cifsExtensionSupportLayout->addWidget(cifsExtensionsSupport, 0, 0, 1, 2, 0);
0237   
0238   // User information
0239   QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), cifsExtensionSupportBox);
0240   useUserId->setObjectName("kcfg_UseUserId");
0241 
0242   QWidget *userIdInputWidget = new QWidget(cifsExtensionSupportBox);
0243   userIdInputWidget->setObjectName("UserIdInputWidget");
0244 
0245   QGridLayout *userLayout = new QGridLayout(userIdInputWidget);
0246   userLayout->setSpacing(5);
0247   userLayout->setMargin(0);
0248 
0249   KLineEdit *userId = new KLineEdit(userIdInputWidget);
0250   userId->setObjectName("kcfg_UserId");
0251   userId->setAlignment(Qt::AlignRight);
0252   userId->setReadOnly(true);
0253 
0254   QToolButton *userChooser = new QToolButton(userIdInputWidget);
0255   userChooser->setIcon(KDE::icon("edit-find-user"));
0256   userChooser->setToolTip(i18n("Choose a different user"));
0257   userChooser->setPopupMode(QToolButton::InstantPopup);
0258 
0259   QMenu *userMenu = new QMenu(userChooser);
0260   userChooser->setMenu(userMenu);
0261   
0262   QList<KUser> allUsers = KUser::allUsers();
0263 
0264   for (const KUser &u : allUsers)
0265   {
0266     QAction *userAction = userMenu->addAction(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId()));
0267     userAction->setData(u.userId().nativeId());
0268   }
0269 
0270   userLayout->addWidget(userId, 0, 0, 0);
0271   userLayout->addWidget(userChooser, 0, 1, Qt::AlignCenter);
0272   
0273   cifsExtensionSupportLayout->addWidget(useUserId, 1, 0, 0);
0274   cifsExtensionSupportLayout->addWidget(userIdInputWidget, 1, 1, 0);
0275 
0276   // Group information
0277   QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), cifsExtensionSupportBox);
0278   useGroupId->setObjectName("kcfg_UseGroupId");
0279 
0280   QWidget *groupIdInputWidget = new QWidget(cifsExtensionSupportBox);
0281   groupIdInputWidget->setObjectName("GroupIdInputWidget");
0282 
0283   QGridLayout *groupLayout = new QGridLayout(groupIdInputWidget);
0284   groupLayout->setSpacing(5);
0285   groupLayout->setMargin(0);
0286 
0287   KLineEdit *groupId = new KLineEdit(groupIdInputWidget);
0288   groupId->setObjectName("kcfg_GroupId");
0289   groupId->setAlignment(Qt::AlignRight);
0290   groupId->setReadOnly(true);
0291   
0292   QToolButton *groupChooser = new QToolButton(groupIdInputWidget);
0293   groupChooser->setIcon(KDE::icon("edit-find-user"));
0294   groupChooser->setToolTip(i18n("Choose a different group"));
0295   groupChooser->setPopupMode(QToolButton::InstantPopup);
0296 
0297   QMenu *groupMenu = new QMenu(groupChooser);
0298   groupChooser->setMenu(groupMenu);
0299 
0300   QList<KUserGroup> groupList = KUserGroup::allGroups();
0301   
0302   for (const KUserGroup &g : groupList)
0303   {
0304     QAction *groupAction = groupMenu->addAction(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId()));
0305     groupAction->setData(g.groupId().nativeId());
0306   }
0307 
0308   groupLayout->addWidget(groupId, 0, 0, 0);
0309   groupLayout->addWidget(groupChooser, 0, 1, Qt::AlignCenter);
0310   
0311   cifsExtensionSupportLayout->addWidget(useGroupId, 2, 0, 0);
0312   cifsExtensionSupportLayout->addWidget(groupIdInputWidget, 2, 1, 0);
0313 
0314   // File mask
0315   QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), cifsExtensionSupportBox);
0316   useFileMode->setObjectName("kcfg_UseFileMode");
0317 
0318   KLineEdit *fileMode = new KLineEdit(cifsExtensionSupportBox);
0319   fileMode->setObjectName("kcfg_FileMode");
0320   fileMode->setClearButtonEnabled(true);
0321   fileMode->setAlignment(Qt::AlignRight);
0322   
0323   cifsExtensionSupportLayout->addWidget(useFileMode, 3, 0, 0);
0324   cifsExtensionSupportLayout->addWidget(fileMode, 3, 1, 0);
0325 
0326   // Directory mask
0327   QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), cifsExtensionSupportBox);
0328   useDirectoryMode->setObjectName("kcfg_UseDirectoryMode");
0329 
0330   KLineEdit *directoryMode = new KLineEdit(cifsExtensionSupportBox);
0331   directoryMode->setObjectName("kcfg_DirectoryMode");
0332   directoryMode->setClearButtonEnabled(true);
0333   directoryMode->setAlignment(Qt::AlignRight);
0334 
0335   cifsExtensionSupportLayout->addWidget(useDirectoryMode, 4, 0, 0);
0336   cifsExtensionSupportLayout->addWidget(directoryMode, 4, 1, 0);
0337 
0338   commonTabLayout->addWidget(cifsExtensionSupportBox, 1, 0);
0339   commonTabLayout->addStretch(100);
0340   
0341   addTab(commonTab, i18n("Common Mount Settings"));
0342 
0343   // 
0344   // Advanced Mount Settings tab
0345   // 
0346   QWidget *advancedTab = new QWidget(this);
0347   QVBoxLayout *advancedTabLayout = new QVBoxLayout(advancedTab);
0348   advancedTabLayout->setSpacing(5);
0349   advancedTabLayout->setMargin(0);
0350   
0351   QGroupBox *advancedOptions = new QGroupBox(i18n("Advanced Options"), advancedTab);
0352 
0353   QGridLayout *advancedOptionsLayout = new QGridLayout(advancedOptions);
0354   advancedOptionsLayout->setSpacing(5);
0355   
0356   // Force Uid
0357   QCheckBox *forceUid = new QCheckBox(Smb4KMountSettings::self()->forceUIDItem()->label(), advancedOptions);
0358   forceUid->setObjectName("kcfg_ForceUID");
0359   
0360   advancedOptionsLayout->addWidget(forceUid, 0, 0, 0);
0361   
0362   // Force Gid
0363   QCheckBox *forceGid = new QCheckBox(Smb4KMountSettings::self()->forceGIDItem()->label(), advancedOptions);
0364   forceGid->setObjectName("kcfg_ForceGID");
0365   
0366   advancedOptionsLayout->addWidget(forceGid, 0, 1, 0);
0367 
0368   // Permission checks
0369   QCheckBox *permissionChecks = new QCheckBox(Smb4KMountSettings::self()->permissionChecksItem()->label(), advancedOptions);
0370   permissionChecks->setObjectName("kcfg_PermissionChecks");
0371   
0372   advancedOptionsLayout->addWidget(permissionChecks, 1, 0, 0);
0373   
0374   // Client controls Ids
0375   QCheckBox *clientControlsIds = new QCheckBox(Smb4KMountSettings::self()->clientControlsIDsItem()->label(), advancedOptions);
0376   clientControlsIds->setObjectName("kcfg_ClientControlsIDs");
0377   
0378   advancedOptionsLayout->addWidget(clientControlsIds, 1, 1, 0);
0379 
0380   // Use server inode numbers
0381   QCheckBox *useServerInodes = new QCheckBox(Smb4KMountSettings::self()->serverInodeNumbersItem()->label(), advancedOptions);
0382   useServerInodes->setObjectName("kcfg_ServerInodeNumbers");
0383   
0384   advancedOptionsLayout->addWidget(useServerInodes, 2, 0, 0);
0385 
0386   // Translate reserved characters
0387   QCheckBox *translateReservedCharacters = new QCheckBox(Smb4KMountSettings::self()->translateReservedCharsItem()->label(), advancedOptions);
0388   translateReservedCharacters->setObjectName("kcfg_TranslateReservedChars");
0389   
0390   advancedOptionsLayout->addWidget(translateReservedCharacters, 2, 1, 0);
0391   
0392   // No locking
0393   QCheckBox *no_locking = new QCheckBox(Smb4KMountSettings::self()->noLockingItem()->label(), advancedOptions);
0394   no_locking->setObjectName("kcfg_NoLocking");
0395   
0396   advancedOptionsLayout->addWidget(no_locking, 3, 0, 0);
0397   
0398   // Extra widget for the rest of the options
0399   QWidget *advancedOptionsExtraWidget = new QWidget(advancedOptions);
0400 
0401   QGridLayout *advancedOptionsExtraWidgetLayout = new QGridLayout(advancedOptionsExtraWidget);
0402   advancedOptionsExtraWidgetLayout->setSpacing(5);
0403   advancedOptionsExtraWidgetLayout->setMargin(0);
0404   
0405   // SMB protocol version
0406   QCheckBox *useSmbProtocol = new QCheckBox(Smb4KMountSettings::self()->useSmbProtocolVersionItem()->label(), advancedOptionsExtraWidget);
0407   useSmbProtocol->setObjectName("kcfg_UseSmbProtocolVersion");
0408 
0409   KComboBox *smbProtocol = new KComboBox(advancedOptionsExtraWidget);
0410   smbProtocol->setObjectName("kcfg_SmbProtocolVersion");
0411   
0412   QList<KCoreConfigSkeleton::ItemEnum::Choice> smbProtocolChoices = Smb4KMountSettings::self()->smbProtocolVersionItem()->choices();
0413   
0414   for (const KCoreConfigSkeleton::ItemEnum::Choice &c : smbProtocolChoices)
0415   {
0416     smbProtocol->addItem(c.label);
0417   }
0418   
0419   advancedOptionsExtraWidgetLayout->addWidget(useSmbProtocol, 0, 0, 0);
0420   advancedOptionsExtraWidgetLayout->addWidget(smbProtocol, 0, 1, 0);
0421   
0422   // Cache mode
0423   QCheckBox *useCacheMode = new QCheckBox(Smb4KMountSettings::self()->useCacheModeItem()->label(), advancedOptionsExtraWidget);
0424   useCacheMode->setObjectName("kcfg_UseCacheMode");
0425   
0426   KComboBox *cacheMode = new KComboBox(advancedOptionsExtraWidget);
0427   cacheMode->setObjectName("kcfg_CacheMode");
0428   
0429   QList<KCoreConfigSkeleton::ItemEnum::Choice> cacheModeChoices = Smb4KMountSettings::self()->cacheModeItem()->choices();
0430   
0431   for (const KCoreConfigSkeleton::ItemEnum::Choice &c : cacheModeChoices)
0432   {
0433     cacheMode->addItem(c.label);
0434   }
0435   
0436   advancedOptionsExtraWidgetLayout->addWidget(useCacheMode, 1, 0, 0);
0437   advancedOptionsExtraWidgetLayout->addWidget(cacheMode, 1, 1, 0);
0438   
0439   // Security mode
0440   QCheckBox *useSecurityMode = new QCheckBox(Smb4KMountSettings::self()->useSecurityModeItem()->label(), advancedOptionsExtraWidget);
0441   useSecurityMode->setObjectName("kcfg_UseSecurityMode");
0442                                  
0443   KComboBox *securityMode = new KComboBox(advancedOptionsExtraWidget);
0444   securityMode->setObjectName("kcfg_SecurityMode");
0445   
0446   QList<KConfigSkeleton::ItemEnum::Choice> securityModeChoices = Smb4KMountSettings::self()->securityModeItem()->choices();
0447   
0448   for (const KConfigSkeleton::ItemEnum::Choice &c : securityModeChoices)
0449   {
0450     securityMode->addItem(c.label);
0451   }
0452   
0453   advancedOptionsExtraWidgetLayout->addWidget(useSecurityMode, 2, 0, 0);
0454   advancedOptionsExtraWidgetLayout->addWidget(securityMode, 2, 1, 0);
0455 
0456   // Additional options
0457   QLabel *additionalOptionsLabel = new QLabel(Smb4KMountSettings::self()->customCIFSOptionsItem()->label(), advancedOptionsExtraWidget);
0458   
0459   QWidget *additionalOptionsWidget = new QWidget(advancedOptionsExtraWidget);
0460   
0461   QHBoxLayout *additionalOptionsWidgetLayout = new QHBoxLayout(additionalOptionsWidget);
0462   additionalOptionsWidgetLayout->setSpacing(5);
0463   additionalOptionsWidgetLayout->setMargin(0);
0464 
0465   KLineEdit *additionalOptions = new KLineEdit(additionalOptionsWidget);
0466   additionalOptions->setObjectName("kcfg_CustomCIFSOptions");
0467   additionalOptions->setReadOnly(true);
0468   additionalOptions->setClearButtonEnabled(true);
0469   additionalOptionsLabel->setBuddy(additionalOptions);
0470   
0471   QToolButton *additionalOptionsEdit = new QToolButton(advancedOptionsExtraWidget);
0472   additionalOptionsEdit->setIcon(KDE::icon("document-edit"));
0473   additionalOptionsEdit->setToolTip(i18n("Edit the additional CIFS options."));
0474   
0475   additionalOptionsWidgetLayout->addWidget(additionalOptions, 0);
0476   additionalOptionsWidgetLayout->addWidget(additionalOptionsEdit, 0);
0477 
0478   advancedOptionsExtraWidgetLayout->addWidget(additionalOptionsLabel, 3, 0, 0);
0479   advancedOptionsExtraWidgetLayout->addWidget(additionalOptionsWidget, 3, 1, 0);
0480 
0481   advancedOptionsLayout->addWidget(advancedOptionsExtraWidget, 4, 0, 1, 2, 0);
0482   
0483   advancedTabLayout->addWidget(advancedOptions, 0);
0484   advancedTabLayout->addStretch(100);
0485   
0486   addTab(advancedTab, i18n("Advanced Mount Settings"));
0487   
0488   //
0489   // Adjust widgets
0490   // 
0491   slotCIFSUnixExtensionsSupport(Smb4KMountSettings::cifsUnixExtensionsSupport());
0492   
0493   //
0494   // Connections
0495   //
0496   connect(userMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewUserTriggered(QAction*)));
0497   connect(groupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewGroupTriggered(QAction*)));
0498   connect(cifsExtensionsSupport, SIGNAL(clicked(bool)), this, SLOT(slotCIFSUnixExtensionsSupport(bool)));
0499   connect(additionalOptionsEdit, SIGNAL(clicked(bool)), this, SLOT(slotAdditionalCIFSOptions()));  
0500 }
0501 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
0502 //
0503 // FreeBSD and NetBSD
0504 //
0505 void Smb4KConfigPageMounting::setupWidget()
0506 {
0507   //
0508   // Basic Settings tab
0509   // 
0510   QWidget *basicTab = new QWidget(this);
0511   QVBoxLayout *basicTabLayout = new QVBoxLayout(basicTab);
0512   basicTabLayout->setSpacing(5);
0513   basicTabLayout->setMargin(0);
0514   
0515   //
0516   // Directories
0517   // 
0518   QGroupBox *directoryBox = new QGroupBox(i18n("Directories"), basicTab);
0519 
0520   QGridLayout *directoryBoxLayout = new QGridLayout(directoryBox);
0521   directoryBoxLayout->setSpacing(5);
0522 
0523   QLabel *prefixLabel = new QLabel(Smb4KMountSettings::self()->mountPrefixItem()->label(), directoryBox);
0524   KUrlRequester *prefix = new KUrlRequester(directoryBox);
0525   prefix->setMode(KFile::Directory | KFile::LocalOnly);
0526   prefix->setObjectName("kcfg_MountPrefix");
0527 
0528   prefixLabel->setBuddy(prefix);
0529   
0530   QCheckBox *lowercaseSubdirs = new QCheckBox(Smb4KMountSettings::self()->forceLowerCaseSubdirsItem()->label(), directoryBox);
0531   lowercaseSubdirs->setObjectName("kcfg_ForceLowerCaseSubdirs");
0532 
0533   directoryBoxLayout->addWidget(prefixLabel, 0, 0, 0);
0534   directoryBoxLayout->addWidget(prefix, 0, 1, 0);
0535   directoryBoxLayout->addWidget(lowercaseSubdirs, 1, 0, 1, 2, 0);
0536   
0537   basicTabLayout->addWidget(directoryBox, 0);
0538   
0539   // 
0540   // Behavior
0541   // 
0542   QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), basicTab);
0543   QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox);
0544   behaviorBoxLayout->setSpacing(5);
0545   
0546   QCheckBox *remountShares = new QCheckBox(Smb4KMountSettings::self()->remountSharesItem()->label(), behaviorBox);
0547   remountShares->setObjectName("kcfg_RemountShares");
0548   
0549   QLabel *remountAttemptsLabel = new QLabel(Smb4KMountSettings::self()->remountAttemptsItem()->label(), behaviorBox);
0550   remountAttemptsLabel->setIndent(25);
0551   
0552   QSpinBox *remountAttempts = new QSpinBox(behaviorBox);
0553   remountAttempts->setObjectName("kcfg_RemountAttempts");
0554   remountAttemptsLabel->setBuddy(remountAttempts);
0555   
0556   QLabel *remountIntervalLabel = new QLabel(Smb4KMountSettings::self()->remountIntervalItem()->label(), behaviorBox);
0557   remountIntervalLabel->setIndent(25);
0558   
0559   QSpinBox *remountInterval = new QSpinBox(behaviorBox);
0560   remountInterval->setObjectName("kcfg_RemountInterval");
0561   remountInterval->setSuffix(i18n(" min"));
0562   remountIntervalLabel->setBuddy(remountInterval);
0563 
0564   QCheckBox *unmountAllShares = new QCheckBox(Smb4KMountSettings::self()->unmountSharesOnExitItem()->label(), behaviorBox);
0565   unmountAllShares->setObjectName("kcfg_UnmountSharesOnExit");
0566   
0567   QCheckBox *unmountForeignShares = new QCheckBox(Smb4KMountSettings::self()->unmountForeignSharesItem()->label(), behaviorBox);
0568   unmountForeignShares->setObjectName("kcfg_UnmountForeignShares");
0569 
0570   QCheckBox *detectAllShares = new QCheckBox(Smb4KMountSettings::self()->detectAllSharesItem()->label(), behaviorBox);
0571   detectAllShares->setObjectName("kcfg_DetectAllShares");
0572 
0573   behaviorBoxLayout->addWidget(remountShares, 0, 0, 1, 2, 0);
0574   behaviorBoxLayout->addWidget(remountAttemptsLabel, 1, 0, 0);
0575   behaviorBoxLayout->addWidget(remountAttempts, 1, 1, 0);
0576   behaviorBoxLayout->addWidget(remountIntervalLabel, 2, 0, 0);
0577   behaviorBoxLayout->addWidget(remountInterval, 2, 1, 0);
0578   behaviorBoxLayout->addWidget(unmountAllShares, 3, 0, 1, 2, 0);
0579   behaviorBoxLayout->addWidget(unmountForeignShares, 4, 0, 1, 2, 0);
0580   behaviorBoxLayout->addWidget(detectAllShares, 5, 0, 1, 2, 0);
0581   
0582   basicTabLayout->addWidget(behaviorBox, 0);
0583   basicTabLayout->addStretch(100);
0584   
0585   addTab(basicTab, i18n("Basic Settings"));
0586   
0587   //
0588   // Mount Settings tab
0589   // 
0590   QWidget *mountTab = new QWidget(this);
0591   QVBoxLayout *mountTabLayout = new QVBoxLayout(mountTab);
0592   mountTabLayout->setSpacing(5);
0593   mountTabLayout->setMargin(0);
0594 
0595   //
0596   // Common Options
0597   //
0598   QGroupBox *commonOptionsBox = new QGroupBox(i18n("Common Options"), mountTab);
0599   QGridLayout *commonOptionsBoxLayout = new QGridLayout(commonOptionsBox);
0600   commonOptionsBoxLayout->setSpacing(5);
0601 
0602   // User information
0603   QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), commonOptionsBox);
0604   useUserId->setObjectName("kcfg_UseUserId");
0605 
0606   QWidget *userIdInputWidget = new QWidget(commonOptionsBox);
0607   userIdInputWidget->setObjectName("UserIdInputWidget");
0608 
0609   QGridLayout *userLayout = new QGridLayout(userIdInputWidget);
0610   userLayout->setSpacing(5);
0611   userLayout->setMargin(0);
0612 
0613   KLineEdit *userId = new KLineEdit(userIdInputWidget);
0614   userId->setObjectName("kcfg_UserId");
0615   userId->setAlignment(Qt::AlignRight);
0616   userId->setReadOnly(true);
0617 
0618   QToolButton *userChooser = new QToolButton(userIdInputWidget);
0619   userChooser->setIcon(KDE::icon("edit-find-user"));
0620   userChooser->setToolTip(i18n("Choose a different user"));
0621   userChooser->setPopupMode(QToolButton::InstantPopup);
0622 
0623   QMenu *userMenu = new QMenu(userChooser);
0624   userChooser->setMenu(userMenu);
0625   
0626   QList<KUser> allUsers = KUser::allUsers();
0627 
0628   for (const KUser &u : allUsers)
0629   {
0630     QAction *userAction = userMenu->addAction(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId()));
0631     userAction->setData(u.userId().nativeId());
0632   }
0633 
0634   userLayout->addWidget(userId, 0, 0, 0);
0635   userLayout->addWidget(userChooser, 0, 1, Qt::AlignCenter);
0636   
0637   commonOptionsBoxLayout->addWidget(useUserId, 0, 0, 0);
0638   commonOptionsBoxLayout->addWidget(userIdInputWidget, 0, 1, 0);
0639   
0640   // Group information
0641   QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), commonOptionsBox);
0642   useGroupId->setObjectName("kcfg_UseGroupId");
0643 
0644   QWidget *groupIdInputWidget = new QWidget(commonOptionsBox);
0645   groupIdInputWidget->setObjectName("GroupIdInputWidget");
0646 
0647   QGridLayout *groupLayout = new QGridLayout(groupIdInputWidget);
0648   groupLayout->setSpacing(5);
0649   groupLayout->setMargin(0);
0650 
0651   KLineEdit *groupId = new KLineEdit(groupIdInputWidget);
0652   groupId->setObjectName("kcfg_GroupId");
0653   groupId->setAlignment(Qt::AlignRight);
0654   groupId->setReadOnly(true);
0655   
0656   QToolButton *groupChooser = new QToolButton(groupIdInputWidget);
0657   groupChooser->setIcon(KDE::icon("edit-find-user"));
0658   groupChooser->setToolTip(i18n("Choose a different group"));
0659   groupChooser->setPopupMode(QToolButton::InstantPopup);
0660 
0661   QMenu *groupMenu = new QMenu(groupChooser);
0662   groupChooser->setMenu(groupMenu);
0663 
0664   QList<KUserGroup> groupList = KUserGroup::allGroups();
0665   
0666   for (const KUserGroup &g : groupList)
0667   {
0668     QAction *groupAction = groupMenu->addAction(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId()));
0669     groupAction->setData(g.groupId().nativeId());
0670   }
0671 
0672   groupLayout->addWidget(groupId, 0, 0, 0);
0673   groupLayout->addWidget(groupChooser, 0, 1, Qt::AlignCenter);
0674   
0675   commonOptionsBoxLayout->addWidget(useGroupId, 1, 0, 0);
0676   commonOptionsBoxLayout->addWidget(groupIdInputWidget, 1, 1, 0);
0677 
0678   // File mask
0679   QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), commonOptionsBox);
0680   useFileMode->setObjectName("kcfg_UseFileMode");
0681 
0682   KLineEdit *fileMode = new KLineEdit(commonOptionsBox);
0683   fileMode->setObjectName("kcfg_FileMode");
0684   fileMode->setClearButtonEnabled(true);
0685   fileMode->setAlignment(Qt::AlignRight);
0686   
0687   commonOptionsBoxLayout->addWidget(useFileMode, 2, 0, 0);
0688   commonOptionsBoxLayout->addWidget(fileMode, 2, 1, 0);
0689 
0690   // Directory mask
0691   QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), commonOptionsBox);
0692   useDirectoryMode->setObjectName("kcfg_UseDirectoryMode");
0693 
0694   KLineEdit *directoryMode = new KLineEdit(commonOptionsBox);
0695   directoryMode->setObjectName("kcfg_DirectoryMode");
0696   directoryMode->setClearButtonEnabled(true);
0697   directoryMode->setAlignment(Qt::AlignRight);
0698 
0699   commonOptionsBoxLayout->addWidget(useDirectoryMode, 3, 0, 0);
0700   commonOptionsBoxLayout->addWidget(directoryMode, 3, 1, 0);
0701   
0702   // 
0703   // Character sets
0704   // 
0705   QGroupBox *characterSetsBox = new QGroupBox(i18n("Character Sets"), mountTab);
0706   QGridLayout *characterSetsBoxLayout = new QGridLayout(characterSetsBox);
0707   characterSetsBoxLayout->setSpacing(5);  
0708   
0709   // Client character set
0710   QCheckBox *useCharacterSets = new QCheckBox(Smb4KMountSettings::self()->useCharacterSetsItem()->label(), characterSetsBox);
0711   useCharacterSets->setObjectName("kcfg_UseCharacterSets");
0712   
0713   QLabel *clientCharacterSetLabel = new QLabel(Smb4KMountSettings::self()->clientCharsetItem()->label(), characterSetsBox);
0714   clientCharacterSetLabel->setIndent(25);
0715   clientCharacterSetLabel->setObjectName("ClientCharacterSetLabel");
0716   
0717   KComboBox *clientCharacterSet = new KComboBox(characterSetsBox);
0718   clientCharacterSet->setObjectName("kcfg_ClientCharset");
0719   
0720   QList<KCoreConfigSkeleton::ItemEnum::Choice> charsetChoices = Smb4KMountSettings::self()->clientCharsetItem()->choices();
0721   
0722   for (const KCoreConfigSkeleton::ItemEnum::Choice &c : charsetChoices)
0723   {
0724     clientCharacterSet->addItem(c.label);
0725   }
0726   
0727   clientCharacterSetLabel->setBuddy(clientCharacterSet);
0728   
0729   // Server character set
0730   QLabel *serverCharacterSetLabel = new QLabel(Smb4KMountSettings::self()->serverCodepageItem()->label(), characterSetsBox);
0731   serverCharacterSetLabel->setIndent(25);
0732   serverCharacterSetLabel->setObjectName("ServerCodepageLabel");
0733   
0734   KComboBox *serverCharacterSet = new KComboBox(characterSetsBox);
0735   serverCharacterSet->setObjectName("kcfg_ServerCodepage");
0736   
0737   QList<KCoreConfigSkeleton::ItemEnum::Choice> codepageChoices = Smb4KMountSettings::self()->serverCodepageItem()->choices();
0738   
0739   for (const KCoreConfigSkeleton::ItemEnum::Choice &c : codepageChoices)
0740   {
0741     serverCharacterSet->addItem(c.label);
0742   }
0743   
0744   serverCharacterSetLabel->setBuddy(serverCharacterSet);
0745   
0746   characterSetsBoxLayout->addWidget(useCharacterSets, 0, 0, 1, 2, 0);
0747   characterSetsBoxLayout->addWidget(clientCharacterSetLabel, 1, 0, 0);
0748   characterSetsBoxLayout->addWidget(clientCharacterSet, 1, 1, 0);
0749   characterSetsBoxLayout->addWidget(serverCharacterSetLabel, 2, 0, 0);
0750   characterSetsBoxLayout->addWidget(serverCharacterSet, 2, 1, 0);  
0751   
0752   mountTabLayout->addWidget(commonOptionsBox, 0);
0753   mountTabLayout->addWidget(characterSetsBox, 0);
0754   mountTabLayout->addStretch(100);
0755   
0756   addTab(mountTab, i18n("Mount Settings"));
0757   
0758   //
0759   // Connections
0760   //
0761   connect(userMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewUserTriggered(QAction*)));
0762   connect(groupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewGroupTriggered(QAction*)));
0763   connect(useCharacterSets, SIGNAL(toggled(bool)), this, SLOT(slotCharacterSets(bool)));
0764   
0765   //
0766   // Enable / disable widgets
0767   //
0768   slotCharacterSets(Smb4KMountSettings::useCharacterSets());
0769 }
0770 #else
0771 //
0772 // Dummy
0773 //
0774 void Smb4KConfigPageMounting::setupWidget()
0775 {
0776 }
0777 #endif
0778 
0779 
0780 void Smb4KConfigPageMounting::slotNewUserTriggered(QAction *action)
0781 {
0782   KLineEdit *userId = findChild<KLineEdit *>("kcfg_UserId");
0783 
0784   if (userId)
0785   {
0786     userId->setText(action->data().toString());
0787   }
0788 }
0789 
0790 
0791 void Smb4KConfigPageMounting::slotNewGroupTriggered(QAction *action)
0792 {
0793   KLineEdit *groupId = findChild<KLineEdit *>("kcfg_GroupId");
0794 
0795   if (groupId)
0796   {
0797     groupId->setText(action->data().toString());
0798   }
0799 }
0800 
0801 
0802 void Smb4KConfigPageMounting::slotCIFSUnixExtensionsSupport(bool checked)
0803 {
0804   QCheckBox *useUserId = findChild<QCheckBox *>("kcfg_UseUserId");
0805   
0806   if (useUserId)
0807   {
0808     useUserId->setEnabled(!checked);
0809   }
0810   
0811   QWidget *userIdInputWidget = findChild<QWidget *>("UserIdInputWidget");
0812   
0813   if (userIdInputWidget)
0814   {
0815     userIdInputWidget->setEnabled(!checked);
0816   }
0817   
0818   QCheckBox *useGroupId = findChild<QCheckBox *>("kcfg_UseGroupId");
0819   
0820   if (useGroupId)
0821   {
0822     useGroupId->setEnabled(!checked);
0823   }
0824   
0825   QWidget *groupIdInputWidget = findChild<QWidget *>("GroupIdInputWidget");
0826   
0827   if (groupIdInputWidget)
0828   {
0829     groupIdInputWidget->setEnabled(!checked);
0830   }
0831   
0832   QCheckBox *useFileMode = findChild<QCheckBox *>("kcfg_UseFileMode");
0833   
0834   if (useFileMode)
0835   {
0836     useFileMode->setEnabled(!checked);
0837   }
0838   
0839   KLineEdit *fileMode = findChild<KLineEdit *>("kcfg_FileMode");
0840   
0841   if (fileMode)
0842   {
0843     fileMode->setEnabled(!checked);
0844   }
0845   
0846   QCheckBox *useDirectoryMode = findChild<QCheckBox *>("kcfg_UseDirectoryMode");
0847   
0848   if (useDirectoryMode)
0849   {
0850     useDirectoryMode->setEnabled(!checked);
0851   }
0852   
0853   KLineEdit *directoryMode = findChild<KLineEdit *>("kcfg_DirectoryMode");
0854   
0855   if (directoryMode)
0856   {
0857     directoryMode->setEnabled(!checked);
0858   }
0859 }
0860 
0861 
0862 
0863 void Smb4KConfigPageMounting::slotAdditionalCIFSOptions()
0864 {
0865 #if defined(Q_OS_LINUX)
0866   KLineEdit *cifsOptions = findChild<KLineEdit *>("kcfg_CustomCIFSOptions");
0867   
0868   if (cifsOptions)
0869   {
0870     QString options = cifsOptions->originalText();
0871     
0872     bool ok = false;
0873     options = QInputDialog::getText(this, i18n("Additional CIFS Options"), i18n("<qt>Enter the desired options as a comma separated list:</qt>"), QLineEdit::Normal, options, &ok);
0874     
0875     if (ok)
0876     {
0877       if(!options.trimmed().isEmpty())
0878       {
0879         // SECURITY: Only pass those arguments to mount.cifs that do not pose
0880         // a potential security risk and that have not already been defined.
0881         //
0882         // This is, among others, the proper fix to the security issue reported
0883         // by Heiner Markert (aka CVE-2014-2581).
0884         QStringList whitelist = whitelistedMountArguments();
0885         QStringList deniedArgs;
0886         QStringList list = options.split(',', QString::SkipEmptyParts);
0887         QMutableStringListIterator it(list);
0888         
0889         while (it.hasNext())
0890         {
0891           QString arg = it.next().section("=", 0, 0);
0892           
0893           if (!whitelist.contains(arg))
0894           {
0895             deniedArgs << arg;
0896             it.remove();
0897           }
0898         }
0899         
0900         if (!deniedArgs.isEmpty())
0901         {
0902           QString msg = i18np("<qt>The following entry is going to be removed from the additional options: %2. Please read the handbook for details.</qt>", "<qt>The following %1 entries are going to be removed from the additional options: %2. Please read the handbook for details.</qt>", deniedArgs.size(), deniedArgs.join(", "));
0903           KMessageBox::sorry(this, msg);
0904         }
0905         
0906         cifsOptions->setText(list.join(",").trimmed());
0907       }
0908       else
0909       {
0910         cifsOptions->clear();
0911       }
0912     }
0913   }
0914 #endif
0915 }
0916 
0917 
0918 void Smb4KConfigPageMounting::slotCharacterSets(bool on)
0919 {
0920   //
0921   // Client character set
0922   // 
0923   QLabel *clientCharacterSetLabel = findChild<QLabel *>("ClientCharacterSetLabel");
0924   
0925   if (clientCharacterSetLabel)
0926   {
0927     clientCharacterSetLabel->setEnabled(on);
0928   }
0929   
0930   KComboBox *clientCharacterSet = findChild<KComboBox *>("kcfg_ClientCharset");
0931   
0932   if (clientCharacterSet)
0933   {
0934     clientCharacterSet->setEnabled(on);
0935   }
0936   
0937   //
0938   // Server character set
0939   // 
0940   QLabel *serverCharacterSetLabel = findChild<QLabel *>("ServerCodepageLabel");
0941   
0942   if (serverCharacterSetLabel)
0943   {
0944     serverCharacterSetLabel->setEnabled(on);
0945   }
0946   
0947   KComboBox *serverCharacterSet = findChild<KComboBox *>("kcfg_ServerCodepage");
0948   
0949   if (serverCharacterSet)
0950   {
0951     serverCharacterSet->setEnabled(on);
0952   }
0953 }
0954