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 "newfolderdialog.h"
00044 #include "kmfolder.h"
00045 #include "folderstorage.h"
00046 #include "kmfolderimap.h"
00047 #include "kmfoldercachedimap.h"
00048 #include "kmfoldermgr.h"
00049 #include "kmfolderdir.h"
00050 #include "folderstorage.h"
00051 #include "kmailicalifaceimpl.h"
00052 #include "kmacctimap.h"
00053 #include "kmacctcachedimap.h"
00054 
00055 using namespace KMail;
00056 
00057 NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
00058     : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
00059                    KDialogBase::Ok|KDialogBase::Cancel,
00060                    KDialogBase::Ok, true ),
00061       mContentsComboBox( 0 ),
00062       mFolder( folder )
00063 {
00064   setWFlags( getWFlags() | WDestructiveClose );
00065   if ( mFolder ) {
00066     setCaption( i18n("New Subfolder of %1").arg( mFolder->prettyURL() ) );
00067   }
00068   QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
00069   privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
00070   setMainWidget( privateLayoutWidget );
00071   mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 0, spacingHint(),
00072                                      "mTopLevelLayout");
00073 
00074   mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");
00075 
00076   mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
00077   mNameLabel->setText( i18n( "&Name:" ) );
00078   mNameHBox->addWidget( mNameLabel );
00079 
00080   mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
00081   mNameLabel->setBuddy( mNameLineEdit );
00082   QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
00083   mNameLineEdit->setFocus();
00084   mNameHBox->addWidget( mNameLineEdit );
00085   mTopLevelLayout->addLayout( mNameHBox );
00086   connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );
00087 
00088   if ( !mFolder ||
00089       ( mFolder->folderType() != KMFolderTypeImap &&
00090         mFolder->folderType() != KMFolderTypeCachedImap ) ) {
00091     mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
00092     mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
00093     mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
00094     mFormatHBox->addWidget( mMailboxFormatLabel );
00095 
00096     mFormatComboBox = new QComboBox( false, privateLayoutWidget, "mFormatComboBox" );
00097     mMailboxFormatLabel->setBuddy( mFormatComboBox );
00098     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." ) );
00099 
00100     mFormatComboBox->insertItem("mbox", 0);
00101     mFormatComboBox->insertItem("maildir", 1);
00102     // does the below make any sense?
00103     //  mFormatComboBox->insertItem("search", 2);
00104     {
00105       KConfig *config = KMKernel::config();
00106       KConfigGroupSaver saver(config, "General");
00107       int type = config->readNumEntry("default-mailbox-format", 1);
00108       if ( type < 0 || type > 1 ) type = 1;
00109       mFormatComboBox->setCurrentItem( type );
00110     }
00111     mFormatHBox->addWidget( mFormatComboBox );
00112     mTopLevelLayout->addLayout( mFormatHBox );
00113   }
00114 
00115   // --- contents -----
00116   if ( kmkernel->iCalIface().isEnabled() &&
00117        mFolder && mFolder->folderType() != KMFolderTypeImap ) {
00118     mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");
00119 
00120     mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
00121     mContentsLabel->setText( i18n( "Folder &contains:" ) );
00122     mContentsHBox->addWidget( mContentsLabel );
00123 
00124     mContentsComboBox = new QComboBox( false, privateLayoutWidget, "mContentsComboBox" );
00125     mContentsLabel->setBuddy( mContentsComboBox );
00126     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." ) );
00127     mContentsComboBox->insertItem( i18n( "Mail" ) );
00128     mContentsComboBox->insertItem( i18n( "Calendar" ) );
00129     mContentsComboBox->insertItem( i18n( "Contacts" ) );
00130     mContentsComboBox->insertItem( i18n( "Notes" ) );
00131     mContentsComboBox->insertItem( i18n( "Tasks" ) );
00132     mContentsComboBox->insertItem( i18n( "Journal" ) );
00133     if ( mFolder ) // inherit contents type from papa
00134       mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
00135     mContentsHBox->addWidget( mContentsComboBox );
00136     mTopLevelLayout->addLayout( mContentsHBox );
00137   }
00138 
00139   if ( mFolder &&
00140       ( mFolder->folderType() == KMFolderTypeImap ||
00141         mFolder->folderType() == KMFolderTypeCachedImap ) ) {
00142     bool rootFolder = false;
00143     QStringList namespaces;
00144     if ( mFolder->folderType() == KMFolderTypeImap ) {
00145       ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
00146       if ( mFolder->storage() == ai->rootFolder() ) {
00147         rootFolder = true;
00148         namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
00149       }
00150     }
00151     if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
00152       ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
00153       if ( ai && mFolder->storage() == ai->rootFolder() ) {
00154         rootFolder = true;
00155         namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
00156       }
00157     }
00158     if ( rootFolder && namespaces.count() > 1 ) {
00159       mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");
00160 
00161       mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
00162       mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
00163       mNamespacesHBox->addWidget( mNamespacesLabel );
00164 
00165       mNamespacesComboBox = new QComboBox( false, privateLayoutWidget, "mNamespacesComboBox" );
00166       mNamespacesLabel->setBuddy( mNamespacesComboBox );
00167       QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
00168       mNamespacesComboBox->insertStringList( namespaces );
00169       mNamespacesHBox->addWidget( mNamespacesComboBox );
00170       mTopLevelLayout->addLayout( mNamespacesHBox );
00171     } else {
00172       mNamespacesComboBox = 0;
00173     }
00174   }
00175 
00176   resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
00177   clearWState( WState_Polished );
00178   slotFolderNameChanged( mNameLineEdit->text());
00179 }
00180 
00181 void NewFolderDialog::slotFolderNameChanged( const QString & _text)
00182 {
00183   enableButtonOK( !_text.isEmpty() );
00184 }
00185 
00186 void NewFolderDialog::slotOk()
00187 {
00188   const QString fldName = mNameLineEdit->text();
00189   if ( fldName.isEmpty() ) {
00190      KMessageBox::error( this, i18n("Please specify a name for the new folder."),
00191         i18n( "No Name Specified" ) );
00192      return;
00193   }
00194 
00195   // names of local folders must not contain a '/'
00196   if ( fldName.find( '/' ) != -1 &&
00197        ( !mFolder ||
00198          ( mFolder->folderType() != KMFolderTypeImap &&
00199            mFolder->folderType() != KMFolderTypeCachedImap ) ) ) {
00200     KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
00201     return;
00202   }
00203 
00204   // folder names must not start with a '.'
00205   if ( fldName.startsWith( "." ) ) {
00206     KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
00207     return;
00208   }
00209 
00210   // names of IMAP folders must not contain the folder delimiter
00211   if ( mFolder &&
00212       ( mFolder->folderType() == KMFolderTypeImap ||
00213         mFolder->folderType() == KMFolderTypeCachedImap ) ) {
00214     QString delimiter;
00215     if ( mFolder->folderType() == KMFolderTypeImap ) {
00216       KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
00217       if ( ai )
00218         delimiter = ai->delimiterForFolder( mFolder->storage() );
00219     } else {
00220       KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
00221       if ( ai )
00222         delimiter = ai->delimiterForFolder( mFolder->storage() );
00223     }
00224     if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
00225       KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
00226       return;
00227     }
00228   }
00229 
00230   // default parent is Top Level local folders
00231   KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
00232   // we got a parent, let's use that
00233   if ( mFolder )
00234     selectedFolderDir = mFolder->createChildFolder();
00235 
00236   // check if the folder already exists
00237   if( selectedFolderDir->hasNamedFolder( fldName )
00238       && ( !( mFolder
00239           && ( selectedFolderDir == mFolder->parent() )
00240           && ( mFolder->storage()->name() == fldName ) ) ) )
00241   {
00242     const QString message = i18n( "<qt>Failed to create folder <b>%1</b>, folder already exists.</qt>" ).arg(fldName);
00243     KMessageBox::error( this, message );
00244     return;
00245   }
00246 
00247   /* Ok, obvious errors caught, let's try creating it for real. */
00248   const QString message = i18n( "<qt>Failed to create folder <b>%1</b>."
00249             "</qt> " ).arg(fldName);
00250   bool success = false;
00251   KMFolder *newFolder = 0;
00252 
00253    if ( mFolder && mFolder->folderType() == KMFolderTypeImap ) {
00254     KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mFolder->storage() );
00255     KMAcctImap *anAccount = selectedStorage->account();
00256     // check if a connection is available BEFORE creating the folder
00257     if (anAccount->makeConnection() == ImapAccountBase::Connected) {
00258       newFolder = kmkernel->imapFolderMgr()->createFolder( fldName, false, KMFolderTypeImap, selectedFolderDir );
00259       if ( newFolder ) {
00260         QString imapPath, parent;
00261         if ( mNamespacesComboBox ) {
00262           // create folder with namespace
00263           parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
00264           imapPath = anAccount->createImapPath( parent, fldName );
00265         } else {
00266           imapPath = anAccount->createImapPath( selectedStorage->imapPath(), fldName );
00267         }
00268         KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
00269         selectedStorage->createFolder(fldName, parent); // create it on the server
00270         newStorage->initializeFrom( selectedStorage, imapPath, QString::null );
00271         static_cast<KMFolderImap*>(mFolder->storage())->setAccount( selectedStorage->account() );
00272         success = true;
00273       }
00274     }
00275   } else if ( mFolder && mFolder->folderType() == KMFolderTypeCachedImap ) {
00276     newFolder = kmkernel->dimapFolderMgr()->createFolder( fldName, false, KMFolderTypeCachedImap, selectedFolderDir );
00277     if ( newFolder ) {
00278       KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
00279       KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( newFolder->storage() );
00280       newStorage->initializeFrom( selectedStorage );
00281       if ( mNamespacesComboBox ) {
00282         // create folder with namespace
00283         QString path = selectedStorage->account()->createImapPath(
00284             mNamespacesComboBox->currentText(), fldName );
00285         newStorage->setImapPathForCreation( path );
00286       }
00287       success = true;
00288     }
00289   } else {
00290     // local folder
00291     if (mFormatComboBox->currentItem() == 1)
00292       newFolder = kmkernel->folderMgr()->createFolder(fldName, false, KMFolderTypeMaildir, selectedFolderDir );
00293     else
00294       newFolder = kmkernel->folderMgr()->createFolder(fldName, false, KMFolderTypeMbox, selectedFolderDir );
00295     if ( newFolder )
00296       success = true;
00297   }
00298   if ( !success ) {
00299     KMessageBox::error( this, message );
00300     return;
00301   }
00302 
00303   // Set type field
00304   if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
00305     KMail::FolderContentsType type =
00306       static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
00307     newFolder->storage()->setContentsType( type );
00308     newFolder->storage()->writeConfig(); // connected slots will read it
00309   }
00310   KDialogBase::slotOk();
00311 }
00312 
00313 #include "newfolderdialog.moc"