diff options
Diffstat (limited to 'smb4k/configdlg/smb4kconfigdialog.cpp')
-rw-r--r-- | smb4k/configdlg/smb4kconfigdialog.cpp | 1222 |
1 files changed, 1222 insertions, 0 deletions
diff --git a/smb4k/configdlg/smb4kconfigdialog.cpp b/smb4k/configdlg/smb4kconfigdialog.cpp new file mode 100644 index 0000000..449aec3 --- /dev/null +++ b/smb4k/configdlg/smb4kconfigdialog.cpp @@ -0,0 +1,1222 @@ +/*************************************************************************** + smb4kconfigdialog - The configuration dialog of Smb4K + ------------------- + begin : Sa Apr 14 2007 + copyright : (C) 2007 by Alexander Reinholdt + email : dustpuppy@users.berlios.de + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +// Qt includes +#include <qradiobutton.h> +#include <qcheckbox.h> + +// KDE includes +#include <klistview.h> +#include <klineedit.h> +#include <kpushbutton.h> +#include <kmessagebox.h> +#include <kurlrequester.h> + +// system specific includes +#include <unistd.h> +#include <sys/types.h> + +// application specific includes +#include "smb4kconfigdialog.h" +#include "smb4kuserinterfaceoptions.h" +#include "smb4knetworkoptions.h" +#include "smb4kshareoptions.h" +#include "smb4kauthoptions.h" +#include "smb4ksuperuseroptions.h" +#include "smb4ksambaoptions.h" +#include "smb4krsyncoptions.h" +#include "../core/smb4ksettings.h" +#include "../core/smb4kglobal.h" +#include "../core/smb4ksambaoptionsinfo.h" +#include "../core/smb4ksambaoptionshandler.h" +#include "../core/smb4kcore.h" +#include "../core/smb4kauthinfo.h" +#include "../core/smb4kpasswordhandler.h" + +using namespace Smb4KGlobal; + +KInstance *Smb4KConfigDialogFactory::m_instance = 0L; +KAboutData *Smb4KConfigDialogFactory::m_about = 0L; + +// Variables we need to determine if super user entries +// have to be written to /etc/sudoers or /etc/super.tab +bool use_sudo = false; +bool use_super = false; +#ifdef __linux__ +bool force_unmount = false; +#endif +bool always_use_su = false; + +// Use this variable to determine if the dialog should be +// closed after Smb4KFileIO::finished() was emitted. +bool close_dialog = false; + + +Smb4KConfigDialog::Smb4KConfigDialog( Smb4KSettings *settings, QWidget *parent, const char *name ) +: KConfigDialog( parent, name, settings ) +{ + // FIXME: I guess, normally we would not need to close destructively, + // but at the moment there are issues with the KURLRequester in file + // mode. To work around those, we are closing the dialog destructively. + // Maybe we can remove this if we moved to KDE4. + setWFlags( Qt::WDestructiveClose ); + + // Add the pages: + Smb4KUserInterfaceOptions *interface_options = new Smb4KUserInterfaceOptions( this, "UserInterfaceOptions" ); + Smb4KNetworkOptions* network_options = new Smb4KNetworkOptions( this, "NetworkOptions" ); + Smb4KShareOptions *share_options= new Smb4KShareOptions( this, "ShareOptions" ); + Smb4KAuthOptions *auth_options = new Smb4KAuthOptions( this, "AuthenticationOptions" ); + Smb4KSambaOptions *samba_options = new Smb4KSambaOptions( this, "SambaOptions" ); + Smb4KRsyncOptions *rsync_options = new Smb4KRsyncOptions( this, "SynchronizationOptions" ); + Smb4KSuperUserOptions *super_user_options = new Smb4KSuperUserOptions( this, "SuperUserOptions" ); + + // Disable widgets if the respective programs are not installed. + if ( Smb4KSettings::rsync().isEmpty() ) + { + rsync_options->setEnabled( false ); + } + + if ( Smb4KSettings::sudo().isEmpty() && Smb4KSettings::super().isEmpty() ) + { + super_user_options->setEnabled( false ); + } + else + { + // The search for the programs and all related actions have been + // done by the core. We only need to disable widgets here. + if ( Smb4KSettings::sudo().isEmpty() ) + { + QRadioButton *sudo = static_cast<QRadioButton *>( super_user_options->child( "SudoButton", "QRadioButton", true ) ); + + if ( sudo ) + { + sudo->setEnabled( false ); + } + } + else if ( Smb4KSettings::super().isEmpty() ) + { + QRadioButton *super = static_cast<QRadioButton *>( super_user_options->child( "SuperButton", "QRadioButton", true ) ); + + if ( super ) + { + super->setEnabled( false ); + } + } + else + { + // Do nothing + } + } + + // There are a few settings we need to the initial values of. + // Initialize them here: + switch ( Smb4KSettings::superUserProgram() ) + { + case Smb4KSettings::EnumSuperUserProgram::Sudo: + { + use_sudo = true; + + break; + } + case Smb4KSettings::EnumSuperUserProgram::Super: + { + use_super = true; + + break; + } + default: + { + break; + } + } + + +#ifdef __linux__ + force_unmount = Smb4KSettings::useForceUnmount(); +#endif + always_use_su = Smb4KSettings::alwaysUseSuperUser(); + + // Now add the pages to the configuration dialog + addPage( interface_options, i18n( "User Interface" ), "view_choose" ); + addPage( network_options, i18n( "Network" ), "network" ); + addPage( share_options, i18n( "Shares" ), "hdd_mount" ); + addPage( auth_options, i18n( "Authentication" ), "identity" ); + addPage( samba_options, i18n( "Samba" ), "samba" ); + addPage( rsync_options, i18n( "Synchronization" ), "bottom" ); + addPage( super_user_options, i18n( "Super User" ), "penguin" ); + + // Stuff that's not managed by KConfig XT is loaded by + // Smb4KConfigDialog::showEvent()! + + // Resize the dialog + setInitialSize( configDialogSize( *(Smb4KSettings::self()->config()), "ConfigDialog" ) ); + + // Connections + connect( samba_options, SIGNAL( customSettingsChanged() ), + this, SLOT( slotCustomSambaSettingsChanged() ) ); + + connect( super_user_options, SIGNAL( removeEntries() ), + this, SLOT( slotRemoveSuperUserEntries() ) ); + + connect( Smb4KCore::fileIO(), SIGNAL( failed() ), + this, SLOT( slotReceivedFileIOFailed() ) ); + + connect( Smb4KCore::fileIO(), SIGNAL( finished() ), + this, SLOT( slotReceivedFileIOFinished() ) ); +} + + +Smb4KConfigDialog::~Smb4KConfigDialog() +{ +} + + +void Smb4KConfigDialog::loadCustomSambaOptions() +{ + // Get the list view: + KListView *custom_list = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) ); + + if ( !custom_list ) + { + return; + } + + // First of all clear the list view: + custom_list->clear(); + + // Now get the default values: + QString default_filesystem, protocol_hint, default_uid, default_gid; + bool write_access = true; + + switch( Smb4KSettings::filesystem() ) + { + case Smb4KSettings::EnumFilesystem::CIFS: + { + default_filesystem = "cifs"; + + break; + } + case Smb4KSettings::EnumFilesystem::SMBFS: + { + default_filesystem = "smbfs"; + + break; + } + default: + { + // FIXME: Set default_filesystem to "cifs"? + break; + } + } + + switch ( Smb4KSettings::protocolHint() ) + { + case Smb4KSettings::EnumProtocolHint::Automatic: + { + // In this case the user leaves it to the net + // command to determine the right protocol. + protocol_hint = QString::null; + + break; + } + case Smb4KSettings::EnumProtocolHint::RPC: + { + protocol_hint = "rpc"; + + break; + } + case Smb4KSettings::EnumProtocolHint::RAP: + { + protocol_hint = "rap"; + + break; + } + case Smb4KSettings::EnumProtocolHint::ADS: + { + protocol_hint = "ads"; + + break; + } + default: + { + protocol_hint = QString::null; + + break; + } + } + + switch( Smb4KSettings::writeAccess() ) + { + case Smb4KSettings::EnumWriteAccess::ReadWrite: + { + write_access = true; + + break; + } + case Smb4KSettings::EnumWriteAccess::ReadOnly: + { + write_access = false; + + break; + } + default: + { + break; + } + } + + const QValueList<Smb4KSambaOptionsInfo *> &list = optionsHandler()->customOptionsList(); + + for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = list.begin(); + it != list.end(); ++it ) + { + // If the only modification is that the share is to be remounted, + // we will not put it into the list: + if ( (*it)->type() == Smb4KSambaOptionsInfo::Share && + (*it)->remount() && + (*it)->port() == Smb4KSettings::remotePort() && +#ifndef __FreeBSD__ + QString::compare( (*it)->filesystem(), default_filesystem ) == 0 && + (*it)->writeAccess() == write_access && + (*it)->kerberos() == Smb4KSettings::useKerberos() /* FreeBSD does not know Kerberos for mounting */ && +#endif + ((QString::compare( default_filesystem, "cifs" ) == 0 && (*it)->uid().toInt() == (int)getuid()) || + (!(*it)->uid().isEmpty() && QString::compare( (*it)->uid(), Smb4KSettings::userID() ) == 0)) && + ((QString::compare( default_filesystem, "cifs" ) == 0 && (*it)->gid().toInt() == (int)getgid()) || + (!(*it)->gid().isEmpty() && QString::compare( (*it)->gid(), Smb4KSettings::groupID() ) == 0)) ) + { + continue; + } + + // Now put the item in the list: + KListViewItem *item = new KListViewItem( custom_list ); + + item->setText( Smb4KSambaOptions::ItemName, (*it)->itemName() ); + + item->setText( Smb4KSambaOptions::Port, ((*it)->port() != -1 ? + QString( "%1" ).arg( (*it)->port() ) : + QString( "%1" ).arg( Smb4KSettings::remotePort() )) ); + + switch ( (*it)->type() ) + { + case Smb4KSambaOptionsInfo::Host: + { + item->setText( Smb4KSambaOptions::Protocol, !(*it)->protocol().isEmpty() ? + (QString::compare( (*it)->protocol(), "auto" ) == 0 ? i18n( "auto" ) : (*it)->protocol().upper()) : + (protocol_hint.isEmpty() ? i18n( "auto" ) : protocol_hint.upper()) ); + + item->setText( Smb4KSambaOptions::Kerberos, (*it)->kerberos() ? + i18n( "yes" ) : + i18n( "no" ) ); + +#ifndef __FreeBSD__ + item->setText( Smb4KSambaOptions::FileSystem, "-" ); + + item->setText( Smb4KSambaOptions::WriteAccess, "-" ); +#endif + + item->setText( Smb4KSambaOptions::UID, "-" ); + + item->setText( Smb4KSambaOptions::GID, "-" ); + + break; + } + case Smb4KSambaOptionsInfo::Share: + { + item->setText( Smb4KSambaOptions::Protocol, "-" ); + +#ifndef __FreeBSD__ + item->setText( Smb4KSambaOptions::Kerberos, (*it)->kerberos() ? + i18n( "yes" ) : + i18n( "no" ) ); + + item->setText( Smb4KSambaOptions::FileSystem, !(*it)->filesystem().isEmpty() ? + (*it)->filesystem().upper() : + default_filesystem.upper() ); + + item->setText( Smb4KSambaOptions::WriteAccess, (*it)->writeAccess() ? + i18n( "read-write" ) : + i18n( "read-only" ) ); +#else + // FreeBSD does not know Kerberos for mounting + item->setText( Smb4KSambaOptions::Kerberos, "-" ); +#endif + item->setText( Smb4KSambaOptions::UID, !(*it)->uid().isEmpty() ? + (*it)->uid() : + Smb4KSettings::userID() ); + + item->setText( Smb4KSambaOptions::GID, !(*it)->gid().isEmpty() ? + (*it)->gid() : + Smb4KSettings::groupID() ); + + break; + } + default: + { + break; + } + } + } + + Smb4KSambaOptions *samba_options = static_cast<Smb4KSambaOptions *>( child( "SambaOptions", "Smb4KSambaOptions", true ) ); + + if ( samba_options ) + { + samba_options->resetCustomTab(); + } +} + + +void Smb4KConfigDialog::saveCustomSambaOptions() +{ + // Get the list view: + KListView *custom_list = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) ); + + if ( !custom_list ) + { + return; + } + + if ( custom_list->childCount() != 0 ) + { + // First remove all items that have been deleted in the + // configuration dialog: + QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList(); + + for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = list.begin(); it != list.end(); ++it ) + { + if ( !custom_list->findItem( (*it)->itemName(), Smb4KSambaOptions::ItemName ) ) + { + optionsHandler()->removeItem( (*it)->itemName(), false ); + + continue; + } + else + { + continue; + } + } + + // Now updated the remaining items: + QListViewItemIterator it( custom_list ); + + while ( it.current() ) + { + QListViewItem *item = it.current(); + + Smb4KSambaOptionsInfo *info = optionsHandler()->findItem( item->text( Smb4KSambaOptions::ItemName ) ); + + if ( info ) + { + switch( info->type() ) + { + case Smb4KSambaOptionsInfo::Host: + { + info->setProtocol( (QString::compare( item->text( Smb4KSambaOptions::Protocol ), "-" ) != 0 ? + item->text( Smb4KSambaOptions::Protocol ).lower() : + QString::null) ); + + info->setKerberos( (QString::compare( item->text( Smb4KSambaOptions::Kerberos ), i18n( "yes" ) ) == 0) ); + + info->setPort( item->text( Smb4KSambaOptions::Port ).toInt() ); + + break; + } + case Smb4KSambaOptionsInfo::Share: + { +#ifndef __FreeBSD__ + // FreeBSD does not know Kerberos for mounting + info->setKerberos( (QString::compare( item->text( Smb4KSambaOptions::Kerberos ), i18n( "yes" ) ) == 0) ); + + info->setFilesystem( (QString::compare( item->text( Smb4KSambaOptions::FileSystem ), "-" ) != 0 ? + item->text( Smb4KSambaOptions::FileSystem ).lower() : + QString::null) ); + + info->setWriteAccess( (QString::compare( item->text( Smb4KSambaOptions::WriteAccess ), + i18n( "read-write" ) ) == 0) ); +#endif + info->setUID( (QString::compare( item->text( Smb4KSambaOptions::UID ), i18n( "default" ) ) != 0 && + QString::compare( item->text( Smb4KSambaOptions::UID ), "-" ) != 0) ? + item->text( Smb4KSambaOptions::UID ) : + QString::null ); + + info->setGID( (QString::compare( item->text( Smb4KSambaOptions::GID ), i18n( "default" ) ) != 0 && + QString::compare( item->text( Smb4KSambaOptions::GID ), "-" ) != 0) ? + item->text( Smb4KSambaOptions::GID ) : + QString::null ); + + info->setPort( item->text( Smb4KSambaOptions::Port ).toInt() ); + + break; + } + default: + { + break; + } + } + } + else + { + // We do not have this case. + } + + ++it; + } + } + else + { + // Remove all items, if the list view is empty: + QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList(); + + for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = list.begin(); it != list.end(); ++it ) + { + if ( !(*it)->remount() ) + { + optionsHandler()->removeItem( (*it)->itemName(), false ); + + continue; + } + else + { + continue; + } + } + } + + optionsHandler()->sync(); +} + + +void Smb4KConfigDialog::loadAuthenticationData() +{ + // Load the default login info and put it into the configuration + // page: + Smb4KAuthInfo auth( QString::null, QString::null, QString::null ); + + (void) passwordHandler()->readDefaultAuth( &auth ); + + KLineEdit *default_user = static_cast<KLineEdit *>( child( "DefaultUserName", "KLineEdit", true ) ); + + if ( default_user ) + { + default_user->setText( auth.user() ); + } + + KLineEdit *default_pass = static_cast<KLineEdit *>( child( "DefaultPassword", "KLineEdit", true ) ); + + if ( default_pass ) + { + default_pass->setText( auth.password() ); + } +} + + +void Smb4KConfigDialog::saveAuthenticationData() +{ + // Read the default login info from the configuration page + // and pass it to the password handler, but only if the wallet + // is open at this time. Otherwise we could end up with empty + // entries: + if ( passwordHandler()->walletIsOpen() ) + { + Smb4KAuthInfo auth( QString::null, QString::null, QString::null ); + + KLineEdit *default_user = static_cast<KLineEdit *>( child( "DefaultUserName", "KLineEdit", true ) ); + + if ( default_user ) + { + auth.setUser( default_user->text() ); + } + + KLineEdit *default_pass = static_cast<KLineEdit *>( child( "DefaultPassword", "KLineEdit", true ) ); + + if ( default_pass ) + { + auth.setPassword( default_pass->text() ); + } + + passwordHandler()->writeDefaultAuth( &auth ); + } + else + { + // Do nothing + } +} + + +bool Smb4KConfigDialog::writeSuperUserEntries() +{ + QRadioButton *sudo = static_cast<QRadioButton *>( child( "SudoButton", "QRadioButton", true ) ); + QRadioButton *super = static_cast<QRadioButton *>( child( "SuperButton", "QRadioButton", true ) ); +#ifdef __linux__ + QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) ); +#endif + QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) ); + + // Check if we need to write anything at all: + Smb4KFileIO::Operation op = Smb4KFileIO::NoOperation; + bool success = true; + +#ifdef __linux__ + if ( sudo && super && force && full_use ) +#else + if ( sudo && super && full_use ) +#endif + { + if ( sudo->isChecked() ) + { +#ifdef __linux__ + if ( (!use_sudo && (force->isChecked() || full_use->isChecked())) || + (use_sudo && + ((force->isChecked() && force_unmount != force->isChecked()) || + (full_use->isChecked() && always_use_su != full_use->isChecked()))) ) +#else + if ( (!use_sudo && full_use->isChecked()) || + (use_sudo && + (full_use->isChecked() && always_use_su != full_use->isChecked())) ) +#endif + { + success = Smb4KCore::fileIO()->writeSudoers( (op = Smb4KFileIO::Insert) ); + } + } + else if ( super->isChecked() ) + { +#ifdef __linux__ + if ( (!use_super && (force->isChecked() || full_use->isChecked())) || + (use_super && + ((force->isChecked() && force_unmount != force->isChecked()) || + (full_use->isChecked() && always_use_su != full_use->isChecked()))) ) +#else + if ( (!use_super && full_use->isChecked()) || + (use_super && + (full_use->isChecked() && always_use_su != full_use->isChecked())) ) +#endif + { + success = Smb4KCore::fileIO()->writeSuperTab( (op = Smb4KFileIO::Insert) ); + } + } + else + { + // Do nothing + } + + use_sudo = sudo->isChecked(); + use_super = super->isChecked(); +#ifdef __linux__ + force_unmount = force->isChecked(); +#endif + always_use_su = full_use->isChecked(); + } + else + { + // Do nothing + } + + return (!success || op == Smb4KFileIO::NoOperation) ? false : true; +} + + +void Smb4KConfigDialog::removeSuperUserEntries() +{ + QRadioButton *sudo = static_cast<QRadioButton *>( child( "SudoButton", "QRadioButton", true ) ); + QRadioButton *super = static_cast<QRadioButton *>( child( "SuperButton", "QRadioButton", true ) ); +#ifdef __linux__ + QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) ); +#endif + QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) ); + +#ifdef __linux__ + if ( sudo && super && force && full_use ) +#else + if ( sudo && super && full_use ) +#endif + + { + if ( sudo->isChecked() ) + { + Smb4KCore::fileIO()->writeSudoers( Smb4KFileIO::Remove ); + } + else if ( super->isChecked() ) + { + Smb4KCore::fileIO()->writeSuperTab( Smb4KFileIO::Remove ); + } + else + { + // Do nothing + } + +#ifdef __linux__ + force->setChecked( false ); +#endif + full_use->setChecked( false ); + + use_sudo = sudo->isChecked(); + use_super = super->isChecked(); +#ifdef __linux__ + force_unmount = force->isChecked(); +#endif + always_use_su = full_use->isChecked(); + } + else + { + // Do nothing + } +} + + +bool Smb4KConfigDialog::checkSettings() +{ + bool ok = true; + QString issues = QString::null; + int index = 0; + + // If the user chose "Query custom master browser" in the + // "Network" tab, there must be a master browser present: + QRadioButton *query_custom_master = static_cast<QRadioButton *>( child( "CustomMasterBrowserLabel", "QRadioButton", true ) ); + KLineEdit *custom_master_input = static_cast<KLineEdit *>( child( "kcfg_CustomMasterBrowser", "KLineEdit", true ) ); + + if ( query_custom_master && custom_master_input && + query_custom_master->isChecked() && + custom_master_input->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Network] The custom master browser has not been entered.\n" ) ); + } + + // If the user chose "Scan broadcast areas" in the + // "Network" tab, there must broadcast areas present: + QRadioButton *scan_bcast_areas = static_cast<QRadioButton *>( child( "BroadcastAreasLabel", "QRadioButton", true ) ); + KLineEdit *bcast_areas_input = static_cast<KLineEdit *>( child( "kcfg_BroadcastAreas", "KLineEdit", true ) ); + + if ( scan_bcast_areas && bcast_areas_input && + scan_bcast_areas->isChecked() && + bcast_areas_input->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Network] The broadcast areas have not been entered.\n" ) ); + } + + // The mount prefix must not be empty: + KURLRequester *mount_prefix = static_cast<KURLRequester *>( child( "kcfg_MountPrefix", "KURLRequester", true ) ); + + if ( mount_prefix && mount_prefix->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Shares] The mount prefix is empty.\n" ) ); + } + + // If the user wants to use a default login, the user + // name must not be empty. + QCheckBox *use_default_login = static_cast<QCheckBox *>( child( "kcfg_UseDefaultLogin", "QCheckBox", true ) ); + KLineEdit *default_user_name = static_cast<KLineEdit *>( child( "kcfg_DefaultUserName", "KLineEdit", true ) ); + + if ( use_default_login && default_user_name && + use_default_login->isChecked() && + default_user_name->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Authentication] The default user name has not been entered.\n" ) ); + } + + // The file mask must not be empty. + KLineEdit *file_mask = static_cast<KLineEdit *>( child( "kcfg_FileMask", "KLineEdit", true ) ); + + if ( file_mask && file_mask->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Samba] The file mask is empty.\n" ) ); + } + + // The directory mask must not be empty. + KLineEdit *directory_mask = static_cast<KLineEdit *>( child( "kcfg_DirectoryMask", "KLineEdit", true ) ); + + if ( directory_mask && directory_mask->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Samba] The directory mask is empty.\n" ) ); + } + + // The UID must not be empty. + KLineEdit *user_id = static_cast<KLineEdit *>( child( "kcfg_UserID", "KLineEdit", true ) ); + + if ( user_id && user_id->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Samba] The UID is empty.\n" ) ); + } + + // The GID must not be empty. + KLineEdit *group_id = static_cast<KLineEdit *>( child( "kcfg_GroupID", "KLineEdit", true ) ); + + if ( group_id && group_id->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Samba] The GID is empty.\n" ) ); + } + + // The rsync prefix must not be empty. + KURLRequester *rsync_prefix = static_cast<KURLRequester *>( child( "kcfg_RsyncPrefix", "KURLRequester", true ) ); + + if ( rsync_prefix && rsync_prefix->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The rsync prefix is empty.\n" ) ); + } + + // The path where to store partial files must not be empty. + QCheckBox *use_partical_directory = static_cast<QCheckBox *>( child( "kcfg_UsePartialDirectory", "QCheckBox", true ) ); + KURLRequester *partial_directory = static_cast<KURLRequester *>( child( "kcfg_PartialDirectory", "KURLRequester", true ) ); + + if ( use_partical_directory && use_partical_directory->isChecked() && + partial_directory && partial_directory->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The directory where partially transferred files should be stored is empty.\n" ) ); + } + + // The the exclude patterns must not be empty. + QCheckBox *use_exclude_pattern = static_cast<QCheckBox *>( child( "kcfg_UseExcludePattern", "QCheckBox", true ) ); + KLineEdit *exclude_pattern = static_cast<KLineEdit *>( child( "kcfg_ExcludePattern", "KLineEdit", true ) ); + + if ( use_exclude_pattern && use_exclude_pattern->isChecked() && + exclude_pattern && exclude_pattern->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The exclude patterns have not been entered.\n" ) ); + } + + // The the path of the exclude file must not be empty. + QCheckBox *use_exclude_file = static_cast<QCheckBox *>( child( "kcfg_UseExcludeFrom", "QCheckBox", true ) ); + KURLRequester *exclude_file = static_cast<KURLRequester *>( child( "kcfg_ExcludeFrom", "KURLRequester", true ) ); + + if ( use_exclude_file && use_exclude_file->isChecked() && + exclude_file && exclude_file->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The path of the exclude file is empty.\n" ) ); + } + + // The the include patterns must not be empty. + QCheckBox *use_include_pattern = static_cast<QCheckBox *>( child( "kcfg_UseIncludePattern", "QCheckBox", true ) ); + KLineEdit *include_pattern = static_cast<KLineEdit *>( child( "kcfg_IncludePattern", "KLineEdit", true ) ); + + if ( use_include_pattern && use_include_pattern->isChecked() && + include_pattern && include_pattern->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The include patterns have not been entered.\n" ) ); + } + + // The the path of the exclude file must not be empty. + QCheckBox *use_include_file = static_cast<QCheckBox *>( child( "kcfg_UseIncludeFrom", "QCheckBox", true ) ); + KURLRequester *include_file = static_cast<KURLRequester *>( child( "kcfg_IncludeFrom", "KURLRequester", true ) ); + + if ( use_include_file && use_include_file->isChecked() && + include_file && include_file->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The path of the include file is empty.\n" ) ); + } + + // If you make backups, check that the suffix and that the + // backup directory is not empty. + QCheckBox *make_backups = static_cast<QCheckBox *>( child( "kcfg_MakeBackups", "QCheckBox", true ) ); + + if ( make_backups && make_backups->isChecked() ) + { + // The backup suffix must not be empty. + QCheckBox *use_backup_suffix = static_cast<QCheckBox *>( child( "kcfg_UseBackupSuffix", "QCheckBox", true ) ); + KLineEdit *backup_suffix = static_cast<KLineEdit *>( child( "kcfg_BackupSuffix", "KLineEdit", true ) ); + + if ( use_backup_suffix && use_backup_suffix->isChecked() && + backup_suffix && backup_suffix->text().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The backup suffix has not been defined.\n" ) ); + } + + // The the path for backups must not be empty. + QCheckBox *use_backup_dir = static_cast<QCheckBox *>( child( "kcfg_UseBackupDirectory", "QCheckBox", true ) ); + KURLRequester *backup_dir = static_cast<KURLRequester *>( child( "kcfg_BackupDirectory", "KURLRequester", true ) ); + + if ( use_backup_dir && use_backup_dir->isChecked() && + backup_dir && backup_dir->url().stripWhiteSpace().isEmpty() ) + { + ok = false; + index++; + + issues.append( "* "+i18n( "[Synchronization] The backup directory is empty.\n" ) ); + } + } + + if ( !ok ) + { + if ( index == 1 ) + { + KMessageBox::error( this, i18n( "The configuration could not be written, because one setting is incomplete:\n%1Please correct this issue." ).arg( issues ) ); + } + else + { + KMessageBox::error( this, i18n( "The configuration could not be written, because %1 settings are incomplete:\n%1Please correct these issues." ).arg( index ).arg( issues ) ); + } + } + + return ok; +} + + +void Smb4KConfigDialog::showEvent( QShowEvent *e ) +{ + // Spontaneous show events come from outside the application. + // We do not want to react on them. + if ( !e->spontaneous() ) + { + loadCustomSambaOptions(); + loadAuthenticationData(); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////////////// + +void Smb4KConfigDialog::slotApply() +{ + // If some settings are not complete, stop here and give + // the user the opportunity to fill in the needed string(s). + if ( !checkSettings() ) + { + return; + } + + saveCustomSambaOptions(); + saveAuthenticationData(); + + if ( writeSuperUserEntries() ) + { + // Disable this widget until Smb4KFileIO::finished() + // is received. + setEnabled( false ); + } + + // The 'Apply' button will be disabled by KConfigDialog, so we do not + // need to do it here. + + KConfigDialog::slotApply(); +} + + +void Smb4KConfigDialog::slotOk() +{ + // If some settings are not complete, stop here and give + // the user the opportunity to fill in the needed string(s). + if ( !checkSettings() ) + { + return; + } + + saveCustomSambaOptions(); + saveAuthenticationData(); + + saveDialogSize( *(Smb4KSettings::self()->config()), "ConfigDialog" ); + + // If the something needs to be written to either /etc/super.tab + // or /etc/sudoers, do not close the dialog but wait until the + // Smb4KFileIO::finished() signal is received. + if ( !writeSuperUserEntries() ) + { + KConfigDialog::slotOk(); + } + else + { + // Disable this widget until Smb4KFileIO::finished() + // is received. + setEnabled( false ); + + // Tell Smb4KConfigDialog::slotReceivedFileIOFinished() + // to close the dialog. + close_dialog = true; + } +} + + +void Smb4KConfigDialog::slotCancel() +{ + // Reset the custom Samba options tab: + Smb4KSambaOptions *samba_options = static_cast<Smb4KSambaOptions *>( child( "SambaOptions", "Smb4KSambaOptions", true ) ); + + if ( samba_options ) + { + samba_options->resetCustomTab(); + } + + KConfigDialog::slotCancel(); +} + + +void Smb4KConfigDialog::slotCustomSambaSettingsChanged() +{ + // Get the list view and all other input widgets: + KListView *view = static_cast<KListView *>( child( "CustomOptionsList", "KListView", true ) ); + + if ( !view ) + { + return; + } + + // Get the list of custom options: + QValueList<Smb4KSambaOptionsInfo *> list = optionsHandler()->customOptionsList(); + + bool changed = false; + + // Loop through the list view items to see what changed and if + // we need to enable the 'Apply' button: + for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = list.begin(); + it != list.end(); ++it ) + { + // Find the item in the list view: + QListViewItem *item = view->findItem( (*it)->itemName(), Smb4KSambaOptions::ItemName ); + + if ( item ) + { + if ( (*it)->type() == Smb4KSambaOptionsInfo::Host ) + { + // Check if the protocol changed. + if ( ((*it)->protocol().isEmpty() && + QString::compare( item->text( Smb4KSambaOptions::Protocol ).lower(), i18n( "auto" ) ) != 0) || + QString::compare( (*it)->protocol(), item->text( Smb4KSambaOptions::Protocol ).lower() ) != 0 ) + { + changed = true; + + break; + } + } + else if ( (*it)->type() == Smb4KSambaOptionsInfo::Share ) + { +#ifndef __FreeBSD__ + // Check if the file system changed. + if ( QString::compare( (*it)->filesystem(), item->text( Smb4KSambaOptions::FileSystem ).lower() ) != 0 ) + { + changed = true; + + break; + } + + // Check if the write access changed. + QString write_access = (*it)->writeAccess() ? + i18n( "read-write" ) : + i18n( "read-only" ); + + if ( QString::compare( write_access, item->text( Smb4KSambaOptions::WriteAccess ) ) != 0 ) + { + changed = true; + + break; + } +#endif + // Check if the UID changed. + if ( ((*it)->uid().isEmpty() && + QString::compare( i18n( "default" ), item->text( Smb4KSambaOptions::UID ) ) != 0) || + QString::compare( (*it)->uid(), item->text( Smb4KSambaOptions::UID ) ) != 0 ) + { + changed = true; + + break; + } + + // Check if the GID changed. + if ( ((*it)->gid().isEmpty() && + QString::compare( i18n( "default" ), item->text( Smb4KSambaOptions::GID ) ) != 0) || + QString::compare( (*it)->gid(), item->text( Smb4KSambaOptions::GID ) ) != 0 ) + { + changed = true; + + break; + } + } + else + { + // Something went wrong. Stop right here. + break; + } + + // Check if the Kerberos entry changed. + QString kerberos = (*it)->kerberos() ? + i18n( "yes" ) : + i18n( "no" ); + + if ( QString::compare( kerberos, item->text( Smb4KSambaOptions::Kerberos ) ) != 0 ) + { + changed = true; + + break; + } + + // Check if the port value changed. + if ( (*it)->port() != item->text( Smb4KSambaOptions::Port ).toInt() ) + { + changed = true; + + break; + } + } + else + { + break; + } + } + + enableButtonApply( changed ); +} + + +void Smb4KConfigDialog::slotRemoveSuperUserEntries() +{ + // Disable this widget until Smb4KFileIO::finished() + // is received. + setEnabled( false ); + + removeSuperUserEntries(); +} + + +void Smb4KConfigDialog::slotReceivedFileIOFailed() +{ +#ifdef __linux__ + QCheckBox *force = static_cast<QCheckBox *>( child( "kcfg_UseForceUnmount", "QCheckBox", true ) ); +#endif + QCheckBox *full_use = static_cast<QCheckBox *>( child( "kcfg_AlwaysUseSuperUser", "QCheckBox", true ) ); + +#ifdef __linux__ + if ( force && full_use ) + { + force->setChecked( false ); +#else + if ( full_use ) + { +#endif + full_use->setChecked( false ); + } +} + + +void Smb4KConfigDialog::slotReceivedFileIOFinished() +{ + // Enable the widget again. + setEnabled( true ); + + if ( close_dialog ) + { + KConfigDialog::slotOk(); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// FACTORY STUFF +///////////////////////////////////////////////////////////////////////////// + +Smb4KConfigDialogFactory::Smb4KConfigDialogFactory() +: KLibFactory() +{ +} + + +Smb4KConfigDialogFactory::~Smb4KConfigDialogFactory() +{ + delete m_instance; + delete m_about; + + m_instance = 0L; +} + + +KInstance *Smb4KConfigDialogFactory::instance() +{ + if( !m_instance ) + { + m_about = new KAboutData( "smb4kconfigdialog", I18N_NOOP( "Smb4KConfigDialog" ), "1.0" ); + m_about->addAuthor("Alexander Reinholdt", 0, "dustpuppy@users.berlios.de"); + m_about->setLicense( KAboutData::License_GPL ); + m_instance = new KInstance( m_about ); + } + + return m_instance; +} + + +QObject *Smb4KConfigDialogFactory::createObject( QObject *parent, const char *name, const char *, +const QStringList & ) +{ + return static_cast<QObject *>( new Smb4KConfigDialog( Smb4KSettings::self(), static_cast<QWidget *>( parent ), name ) ); +} + + +///////////////////////////////////////////////////////////////////////////// +// INIT +///////////////////////////////////////////////////////////////////////////// + + +extern "C" +{ + void *init_libsmb4kconfigdialog() + { + KGlobal::locale()->insertCatalogue( "smb4k" ); + return new Smb4KConfigDialogFactory; + } +} + +#include "smb4kconfigdialog.moc" |