kmail

newfolderdialog.cpp

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