kmail

archivefolderdialog.cpp
1 /* Copyright 2009 Klarälvdalens Datakonsult AB
2 
3  This program is free software; you can redistribute it and/or
4  modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation; either version 2 of
6  the License or (at your option) version 3 or any later version
7  accepted by the membership of KDE e.V. (or its successor approved
8  by the membership of KDE e.V.), which shall act as a proxy
9  defined in Section 14 of version 3 of the license.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "archivefolderdialog.h"
20 
21 #include "backupjob.h"
22 #include "kmkernel.h"
23 #include "kmfolder.h"
24 #include "kmmainwidget.h"
25 #include "folderrequester.h"
26 #include "util.h"
27 
28 #include <tdelocale.h>
29 #include <kcombobox.h>
30 #include <kurlrequester.h>
31 #include <tdemessagebox.h>
32 #include <tdefiledialog.h>
33 
34 #include <tqlabel.h>
35 #include <tqcheckbox.h>
36 #include <tqlayout.h>
37 
38 using namespace KMail;
39 
40 static TQString standardArchivePath( const TQString &folderName )
41 {
42  TQString currentPath = TDEGlobalSettings::documentPath();
43  TQDir dir( currentPath );
44  if( !dir.exists() ) {
45  currentPath = TQDir::homeDirPath() + '/';
46  }
47  return currentPath +
48  i18n( "Start of the filename for a mail archive file" , "Archive" ) + "_" + folderName +
49  "_" + TQDate::currentDate().toString( Qt::ISODate ) + ".tar.bz2";
50 }
51 
52 ArchiveFolderDialog::ArchiveFolderDialog( TQWidget *parent )
53  : KDialogBase( parent, "archive_folder_dialog", false, i18n( "Archive Folder" ),
54  KDialogBase::Ok | KDialogBase::Cancel,
55  KDialogBase::Ok, true ),
56  mParentWidget( parent )
57 {
58  TQWidget *mainWidget = new TQWidget( this );
59  TQGridLayout *mainLayout = new TQGridLayout( mainWidget );
60  mainLayout->setSpacing( KDialog::spacingHint() );
61  mainLayout->setMargin( KDialog::marginHint() );
62  setMainWidget( mainWidget );
63 
64  int row = 0;
65 
66  // TODO: better label for "Ok" button
67  // TODO: Explaination label
68  // TODO: Use TQFormLayout in KDE4
69 
70  TQLabel *folderLabel = new TQLabel( i18n( "&Folder:" ), mainWidget );
71  mainLayout->addWidget( folderLabel, row, 0 );
72  mFolderRequester = new FolderRequester( mainWidget, kmkernel->getKMMainWidget()->folderTree() );
73  mFolderRequester->setMustBeReadWrite( false );
74  connect( mFolderRequester, TQT_SIGNAL(folderChanged(KMFolder *)),
75  TQT_SLOT(slotFolderChanged(KMFolder *)) );
76  folderLabel->setBuddy( mFolderRequester );
77  mainLayout->addWidget( mFolderRequester, row, 1 );
78  row++;
79 
80  TQLabel *formatLabel = new TQLabel( i18n( "F&ormat:" ), mainWidget );
81  mainLayout->addWidget( formatLabel, row, 0 );
82  mFormatComboBox = new KComboBox( mainWidget );
83  formatLabel->setBuddy( mFormatComboBox );
84 
85  // These combobox values have to stay in sync with the ArchiveType enum from BackupJob!
86  mFormatComboBox->insertItem( i18n( "Compressed Zip Archive (.zip)" ) );
87  mFormatComboBox->insertItem( i18n( "Uncompressed Archive (.tar)" ) );
88  mFormatComboBox->insertItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) );
89  mFormatComboBox->insertItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) );
90  mFormatComboBox->setCurrentItem( 2 );
91  connect( mFormatComboBox, TQT_SIGNAL(activated(int)),
92  this, TQT_SLOT(slotFixFileExtension()) );
93  mainLayout->addWidget( mFormatComboBox, row, 1 );
94  row++;
95 
96  TQLabel *fileNameLabel = new TQLabel( i18n( "&Archive File:" ), mainWidget );
97  mainLayout->addWidget( fileNameLabel, row, 0 );
98  mUrlRequester = new KURLRequester( mainWidget );
99  mUrlRequester->setMode( KFile::LocalOnly );
100  mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" );
101  mUrlRequester->fileDialog()->setKeepLocation( true );
102  fileNameLabel->setBuddy( mUrlRequester );
103  connect( mUrlRequester->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)),
104  TQT_SLOT(slotUrlChanged(const TQString &)) );
105  connect( mUrlRequester, TQT_SIGNAL(urlSelected(const TQString&)),
106  this, TQT_SLOT(slotFixFileExtension()) );
107  mainLayout->addWidget( mUrlRequester, row, 1 );
108  row++;
109 
110  // TODO: Make this appear more dangerous!
111  mDeleteCheckBox = new TQCheckBox( i18n( "&Delete folders after completion" ), mainWidget );
112  mainLayout->addMultiCellWidget( mDeleteCheckBox, row, row, 0, 1, TQt::AlignLeft );
113  row++;
114 
115  // TODO: what's this, tooltips
116 
117  // TODO: Warn that user should do mail check for online IMAP and possibly cached IMAP as well
118 
119  mainLayout->setColStretch( 1, 1 );
120  mainLayout->addItem( new TQSpacerItem( 1, 1, TQSizePolicy::Expanding, TQSizePolicy::Expanding ), row, 0 );
121 
122  // Make it a bit bigger, else the folder requester cuts off the text too early
123  resize( 500, minimumSize().height() );
124 }
125 
126 void ArchiveFolderDialog::slotUrlChanged( const TQString &text )
127 {
128  enableButton( Ok, !text.isEmpty() );
129 }
130 
131 bool canRemoveFolder( KMFolder *folder )
132 {
133  return
134  folder &&
135  folder->canDeleteMessages() &&
136  !folder->noContent() &&
137  !folder->isSystemFolder();
138 }
139 
140 void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder )
141 {
142  mDeleteCheckBox->setEnabled( canRemoveFolder( folder ) );
143  enableButton( Ok, folder && !folder->noContent());
144 }
145 
146 void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder )
147 {
148  mFolderRequester->setFolder( defaultFolder );
149  // TODO: what if the file already exists?
150  mUrlRequester->setURL( standardArchivePath( defaultFolder->name() ) );
151  mDeleteCheckBox->setEnabled( canRemoveFolder( defaultFolder ) );
152 }
153 
154 void ArchiveFolderDialog::slotOk()
155 {
156  if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) {
157  return;
158  }
159 
160  if ( !mFolderRequester->folder() ) {
161  KMessageBox::information( this, i18n( "Please select the folder that should be archived." ),
162  i18n( "No folder selected" ) );
163  return;
164  }
165 
166  // TODO: check if url is empty. or better yet, disable ok button until file is chosen
167  KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget );
168  backupJob->setRootFolder( mFolderRequester->folder() );
169  backupJob->setSaveLocation( mUrlRequester->url() );
170  backupJob->setArchiveType( static_cast<BackupJob::ArchiveType>( mFormatComboBox->currentItem() ) );
171  backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isEnabled() &&
172  mDeleteCheckBox->isChecked() );
173  backupJob->start();
174  accept();
175 }
176 
177 void ArchiveFolderDialog::slotFixFileExtension()
178 {
179  // KDE4: use KMimeType::extractKnownExtension() here
180  const int numExtensions = 4;
181 
182  // These extensions are sorted differently, .tar has to come last, or it will match before giving
183  // the more specific ones time to match.
184  const char *sortedExtensions[numExtensions] = { ".zip", ".tar.bz2", ".tar.gz", ".tar" };
185 
186  // The extensions here are also sorted, like the enum order of BackupJob::ArchiveType
187  const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" };
188 
189  TQString fileName = mUrlRequester->url();
190  if ( fileName.isEmpty() ) {
191  fileName = standardArchivePath( mFolderRequester->folder() ?
192  mFolderRequester->folder()->name() : "" );
193  }
194 
195  // First, try to find the extension of the file name and remove it
196  for( int i = 0; i < numExtensions; i++ ) {
197  int index = fileName.lower().findRev( sortedExtensions[i] );
198  if ( index != -1 ) {
199  fileName = fileName.left( fileName.length() - TQString( sortedExtensions[i] ).length() );
200  break;
201  }
202  }
203 
204  // Now, we've got a filename without an extension, simply append the correct one
205  fileName += extensions[mFormatComboBox->currentItem()];
206  mUrlRequester->setURL( fileName );
207 }
208 
209 #include "archivefolderdialog.moc"
bool noContent() const
Returns, if the folder can't contain mails, but only subfolder.
Definition: kmfolder.cpp:301
A widget that contains a KLineEdit which shows the current folder and a button that fires a KMFolderS...
void setMustBeReadWrite(bool readwrite)
Set if readonly folders should be disabled Be aware that if you disable this the user can also select...
Writes an entire folder structure to an archive file.
Definition: backupjob.h:48
Mail folder.
Definition: kmfolder.h:68
The user rights/ACL have been fetched from the server sucessfully.
Definition: acljobs.h:66
void accept()
Evaluate the settings made and create the appropriate filter rules.
bool canDeleteMessages() const
Can messages in this folder be deleted?
Definition: kmfolder.cpp:576
bool isSystemFolder() const
Returns true if the folder is a kmail system folder.
Definition: kmfolder.h:369