kmail

newfolderdialog.cpp

00001 /*******************************************************************************
00002 **
00003 ** Filename   : newfolderdialog.cpp
00004 ** Created on : 30 January, 2005
00005 ** Copyright  : (c) 2005 Till Adam
00006 ** Email      : adam@kde.org
00007 **
00008 *******************************************************************************/
00009 
00010 /*******************************************************************************
00011 **
00012 **   This program is free software; you can redistribute it and/or modify
00013 **   it under the terms of the GNU General Public License as published by
00014 **   the Free Software Foundation; either version 2 of the License, or
00015 **   (at your option) any later version.
00016 **
00017 **   In addition, as a special exception, the copyright holders give
00018 **   permission to link the code of this program with any edition of
00019 **   the Qt library by Trolltech AS, Norway (or with modified versions
00020 **   of Qt that use the same license as Qt), and distribute linked
00021 **   combinations including the two.  You must obey the GNU General
00022 **   Public License in all respects for all of the code used other than
00023 **   Qt.  If you modify this file, you may extend this exception to
00024 **   your version of the file, but you are not obligated to do so.  If
00025 **   you do not wish to do so, delete this exception statement from
00026 **   your version.
00027 *******************************************************************************/
00028 
00029 #include <qvariant.h>
00030 #include <qpushbutton.h>
00031 #include <qlabel.h>
00032 #include <qlineedit.h>
00033 #include <qcombobox.h>
00034 #include <qlayout.h>
00035 #include <qtooltip.h>
00036 #include <qwhatsthis.h>
00037 #include <qregexp.h>
00038 
00039 #include <klocale.h>
00040 #include <kdialogbase.h>
00041 #include <kmessagebox.h>
00042 
00043 #include "folderutil.h"
00044 #include "newfolderdialog.h"
00045 #include "kmfolder.h"
00046 #include "folderstorage.h"
00047 #include "kmfolderimap.h"
00048 #include "kmfoldercachedimap.h"
00049 #include "kmfoldermgr.h"
00050 #include "kmfolderdir.h"
00051 #include "folderstorage.h"
00052 #include "kmailicalifaceimpl.h"
00053 #include "kmacctimap.h"
00054 #include "kmacctcachedimap.h"
00055 
00056 using namespace KMail;
00057 
00058 NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
00059     : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
00060                    KDialogBase::Ok|KDialogBase::Cancel,
00061                    KDialogBase::Ok, true ),
00062       mFormatComboBox( 0 ),
00063       mContentsComboBox( 0 ),
00064       mNamespacesComboBox( 0 ),
00065       mFolder( folder )
00066 {
00067   setWFlags( getWFlags() | WDestructiveClose );
00068   if ( mFolder ) {
00069     setCaption( i18n("New Subfolder of %1").arg( mFolder->prettyURL() ) );
00070   }
00071   QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
00072   privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
00073   setMainWidget( privateLayoutWidget );
00074   mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 0, spacingHint(),
00075                                      "mTopLevelLayout");
00076 
00077   mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");
00078 
00079   mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
00080   mNameLabel->setText( i18n( "&Name:" ) );
00081   mNameHBox->addWidget( mNameLabel );
00082 
00083   mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
00084   mNameLabel->setBuddy( mNameLineEdit );
00085   QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
00086   mNameLineEdit->setFocus();
00087   mNameHBox->addWidget( mNameLineEdit );
00088   mTopLevelLayout->addLayout( mNameHBox );
00089   connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );
00090 
00091   if ( !mFolder ||
00092       ( mFolder->folderType() != KMFolderTypeImap &&
00093         mFolder->folderType() != KMFolderTypeCachedImap ) ) {
00094     mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
00095     mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
00096     mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
00097     mFormatHBox->addWidget( mMailboxFormatLabel );
00098 
00099     mFormatComboBox = new QComboBox( false, privateLayoutWidget, "mFormatComboBox" );
00100     mMailboxFormatLabel->setBuddy( mFormatComboBox );
00101     QWhatsThis::add( mFormatComboBox, i18n( "Select whether you want to store the messages in this folder as one file per  message (maildir) or as one big file (mbox). KMail uses maildir by default and this only needs to be changed in rare circumstances. If you are unsure, leave this option as-is." ) );
00102 
00103     mFormatComboBox->insertItem("mbox", 0);
00104     mFormatComboBox->insertItem("maildir", 1);
00105     // does the below make any sense?
00106     //  mFormatComboBox->insertItem("search", 2);
00107     {
00108       KConfig *config = KMKernel::config();
00109       KConfigGroupSaver saver(config, "General");
00110       int type = config->readNumEntry("default-mailbox-format", 1);
00111       if ( type < 0 || type > 1 ) type = 1;
00112       mFormatComboBox->setCurrentItem( type );
00113     }
00114     mFormatHBox->addWidget( mFormatComboBox );
00115     mTopLevelLayout->addLayout( mFormatHBox );
00116   }
00117 
00118   // --- contents -----
00119   if ( kmkernel->iCalIface().isEnabled() &&
00120        mFolder && mFolder->folderType() != KMFolderTypeImap ) {
00121     mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");
00122 
00123     mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
00124     mContentsLabel->setText( i18n( "Folder &contains:" ) );
00125     mContentsHBox->addWidget( mContentsLabel );
00126 
00127     mContentsComboBox = new QComboBox( false, privateLayoutWidget, "mContentsComboBox" );
00128     mContentsLabel->setBuddy( mContentsComboBox );
00129     QWhatsThis::add( mContentsComboBox, i18n( "Select whether you want the new folder to be used for mail storage of for storage of groupware items such as tasks or notes. The default is mail. If you are unsure, leave this option as-is." ) );
00130     mContentsComboBox->insertItem( i18n( "Mail" ) );
00131     mContentsComboBox->insertItem( i18n( "Calendar" ) );
00132     mContentsComboBox->insertItem( i18n( "Contacts" ) );
00133     mContentsComboBox->insertItem( i18n( "Notes" ) );
00134     mContentsComboBox->insertItem( i18n( "Tasks" ) );
00135     mContentsComboBox->insertItem( i18n( "Journal" ) );
00136     if ( mFolder ) // inherit contents type from papa
00137       mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
00138     mContentsHBox->addWidget( mContentsComboBox );
00139     mTopLevelLayout->addLayout( mContentsHBox );
00140   }
00141 
00142   if ( mFolder &&
00143       ( mFolder->folderType() == KMFolderTypeImap ||
00144         mFolder->folderType() == KMFolderTypeCachedImap ) ) {
00145     bool rootFolder = false;
00146     QStringList namespaces;
00147     if ( mFolder->folderType() == KMFolderTypeImap ) {
00148       ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
00149       if ( mFolder->storage() == ai->rootFolder() ) {
00150         rootFolder = true;
00151         namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
00152       }
00153     }
00154     if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
00155       ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
00156       if ( ai && mFolder->storage() == ai->rootFolder() ) {
00157         rootFolder = true;
00158         namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
00159       }
00160     }
00161     if ( rootFolder && namespaces.count() > 1 ) {
00162       mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");
00163 
00164       mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
00165       mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
00166       mNamespacesHBox->addWidget( mNamespacesLabel );
00167 
00168       mNamespacesComboBox = new QComboBox( false, privateLayoutWidget, "mNamespacesComboBox" );
00169       mNamespacesLabel->setBuddy( mNamespacesComboBox );
00170       QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
00171       mNamespacesComboBox->insertStringList( namespaces );
00172       mNamespacesHBox->addWidget( mNamespacesComboBox );
00173       mTopLevelLayout->addLayout( mNamespacesHBox );
00174     } else {
00175       mNamespacesComboBox = 0;
00176     }
00177   }
00178 
00179   resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
00180   clearWState( WState_Polished );
00181   slotFolderNameChanged( mNameLineEdit->text());
00182 }
00183 
00184 void NewFolderDialog::slotFolderNameChanged( const QString & _text)
00185 {
00186   enableButtonOK( !_text.isEmpty() );
00187 }
00188 
00189 void NewFolderDialog::slotOk()
00190 {
00191   const QString fldName = mNameLineEdit->text();
00192   if ( fldName.isEmpty() ) {
00193      KMessageBox::error( this, i18n("Please specify a name for the new folder."),
00194         i18n( "No Name Specified" ) );
00195      return;
00196   }
00197 
00198   // names of local folders must not contain a '/'
00199   if ( fldName.find( '/' ) != -1 &&
00200        ( !mFolder ||
00201          ( mFolder->folderType() != KMFolderTypeImap &&
00202            mFolder->folderType() != KMFolderTypeCachedImap ) ) ) {
00203     KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
00204     return;
00205   }
00206 
00207   // folder names must not start with a '.'
00208   if ( fldName.startsWith( "." ) ) {
00209     KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
00210     return;
00211   }
00212 
00213   // names of IMAP folders must not contain the folder delimiter
00214   if ( mFolder &&
00215       ( mFolder->folderType() == KMFolderTypeImap ||
00216         mFolder->folderType() == KMFolderTypeCachedImap ) ) {
00217     QString delimiter;
00218     if ( mFolder->folderType() == KMFolderTypeImap ) {
00219       KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
00220       if ( ai )
00221         delimiter = ai->delimiterForFolder( mFolder->storage() );
00222     } else {
00223       KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
00224       if ( ai )
00225         delimiter = ai->delimiterForFolder( mFolder->storage() );
00226     }
00227     if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
00228       KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
00229       return;
00230     }
00231   }
00232 
00233   // default parent is Top Level local folders
00234   KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
00235   // we got a parent, let's use that
00236   if ( mFolder )
00237     selectedFolderDir = mFolder->createChildFolder();
00238 
00239   // check if the folder already exists
00240   if( selectedFolderDir->hasNamedFolder( fldName )
00241       && ( !( mFolder
00242           && ( selectedFolderDir == mFolder->parent() )
00243           && ( mFolder->storage()->name() == fldName ) ) ) )
00244   {
00245     const QString message = i18n( "<qt>Failed to create folder <b>%1</b>, folder already exists.</qt>" ).arg(fldName);
00246     KMessageBox::error( this, message );
00247     return;
00248   }
00249 
00250   /* Ok, obvious errors caught, let's try creating it for real. */
00251   const QString message = i18n( "<qt>Failed to create folder <b>%1</b>."
00252             "</qt> " ).arg(fldName);
00253 
00254   QString namespaceName;
00255   if ( mNamespacesComboBox ) {
00256     namespaceName = mNamespacesComboBox->currentText();
00257   }
00258 
00259   KMFolderType folderType = KMFolderTypeUnknown;
00260   if ( mFormatComboBox && mFormatComboBox->currentItem() == 1 )
00261     folderType = KMFolderTypeMaildir;
00262   else if ( mFormatComboBox )
00263     folderType = KMFolderTypeMbox;
00264 
00265   KMFolder *newFolder = KMail::FolderUtil::createSubFolder( mFolder, selectedFolderDir, fldName,
00266                                                             namespaceName, folderType );
00267   if ( !newFolder ) {
00268     KMessageBox::error( this, message );
00269     return;
00270   }
00271 
00272   // Set type field
00273   if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
00274     KMail::FolderContentsType type =
00275       static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
00276     newFolder->storage()->setContentsType( type );
00277     newFolder->storage()->writeConfig(); // connected slots will read it
00278   }
00279   KDialogBase::slotOk();
00280 }
00281 
00282 #include "newfolderdialog.moc"