2 KNode, the KDE newsreader
3 Copyright (c) 1999-2005 the KNode authors.
4 See file AUTHORS for details
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 You should have received a copy of the GNU General Public License
11 along with this program; if not, write to the Free Software Foundation,
12 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
19 #include <QProgressBar>
20 #include <QVBoxLayout>
21 #include <QApplication>
23 #include <QTextStream>
24 #include <QCloseEvent>
27 #include <kmessagebox.h>
28 #include <kseparator.h>
32 #include "knglobals.h"
33 #include "kncleanup.h"
35 #include "knfoldermanager.h"
36 #include "kngroupmanager.h"
37 #include "knarticlemanager.h"
38 #include "knnntpaccount.h"
41 KNCleanUp::KNCleanUp() : d_lg(0)
46 KNCleanUp::~KNCleanUp()
52 void KNCleanUp::start()
54 if ( mColList
.isEmpty() )
57 d_lg
= new ProgressDialog( mColList
.count() );
60 for ( QList
<KNArticleCollection
*>::Iterator it
= mColList
.begin(); it
!= mColList
.end(); ++it
) {
61 if ( (*it
)->type() == KNCollection::CTgroup
) {
62 d_lg
->showMessage( i18n("Deleting expired articles in <b>%1</b>", (*it
)->name() ) );
63 qApp
->processEvents();
64 expireGroup( static_cast<KNGroup
*>( (*it
) ) );
67 else if ( (*it
)->type() == KNCollection::CTfolder
) {
68 d_lg
->showMessage( i18n("Compacting folder <b>%1</b>", (*it
)->name() ) );
69 qApp
->processEvents();
70 compactFolder( static_cast<KNFolder
*>( (*it
) ) );
80 void KNCleanUp::reset()
90 void KNCleanUp::expireGroup( KNGroup
*g
, bool showResult
)
92 int expDays
=0, idRef
=0, foundId
=-1, delCnt
=0, leftCnt
=0, newCnt
=0, firstArtNr
=g
->firstNr(), firstNew
=-1;
93 bool unavailable
=false;
94 KNRemoteArticle
*art
, *ref
;
96 KNode::Cleanup
*conf
= g
->activeCleanupConfig();
98 g
->setNotUnloadable(true);
100 if (!g
->isLoaded() && !knGlobals
.groupManager()->loadHeaders(g
)) {
101 g
->setNotUnloadable(false);
106 for(int i
=0; i
<g
->length(); i
++) {
109 expDays
= conf
->maxAgeForRead();
111 expDays
= conf
->maxAgeForUnread();
114 if ((art
->articleNumber() != -1) && conf
->removeUnavailable())
115 unavailable
= (art
->articleNumber() < firstArtNr
);
117 art
->setExpired( (art
->date()->ageInDays() >= expDays
) || unavailable
);
121 if (conf
->preserveThreads()) {
122 for(int i
=0; i
<g
->length(); i
++) {
124 if(!art
->isExpired()) {
128 ref
->setExpired(false);
136 for(int i
=0; i
<g
->length(); i
++) {
138 if(!art
->isExpired()) {
141 while(foundId
==0 && idRef
!=0) {
143 if(!ref
->isExpired()) foundId
=ref
->id();
146 art
->setIdRef(foundId
);
151 for(int i
=0; i
<g
->length(); i
++) {
153 if(art
->isExpired()) {
157 if (art
->hasContent())
158 knGlobals
.articleManager()->unloadArticle(art
, true);
160 else if(art
->isNew() && !art
->isRead()) {
167 g
->setNotUnloadable(false);
170 g
->saveStaticData(g
->length(), true);
171 g
->saveDynamicData(g
->length(), true);
173 g
->setNewCount(newCnt
);
174 g
->setFirstNewIndex(firstNew
);
176 knGlobals
.groupManager()->unloadHeaders(g
, true);
179 g
->syncDynamicData();
181 conf
->setLastExpireDate();
185 kDebug(5003) <<"KNCleanUp::expireGroup() :" << g
->groupname() <<":"
186 << delCnt
<< "deleted ," << leftCnt
<< "left";
189 KMessageBox::information(knGlobals
.topWidget
,
190 i18n("<b>%1</b><br />expired: %2<br />left: %3", g
->groupname(), delCnt
, leftCnt
));
194 void KNCleanUp::compactFolder(KNFolder
*f
)
206 f
->setNotUnloadable(true);
208 if (!f
->isLoaded() && !knGlobals
.folderManager()->loadHeaders(f
)) {
209 f
->setNotUnloadable(false);
214 QFileInfo
info(f
->m_boxFile
);
215 QString oldName
=info
.fileName();
216 QString newName
=oldName
+".new";
217 QFile
newMBoxFile( info
.absolutePath() + '/' + newName
);
219 if( (f
->m_boxFile
.open(QIODevice::ReadOnly
)) && (newMBoxFile
.open(QIODevice::WriteOnly
)) ) {
220 QTextStream
ts(&newMBoxFile
);
221 ts
.setCodec( "ISO 8859-1" );
222 for(int idx
=0; idx
<f
->length(); idx
++) {
224 if ( f
->m_boxFile
.seek( art
->startOffset() ) ) {
225 ts
<< "From aaa@aaa Mon Jan 01 00:00:00 1997\n";
227 art
->setStartOffset( newMBoxFile
.pos() );
228 while ( f
->m_boxFile
.pos() < (uint
)art
->endOffset() && !f
->m_boxFile
.atEnd() )
229 ts
<< f
->m_boxFile
.readLine();
231 art
->setEndOffset( newMBoxFile
.pos() );
232 newMBoxFile
.putChar('\n');
241 dir
.rename(newName
, oldName
);
244 f
->setNotUnloadable(false);
248 //===============================================================================================
251 KNCleanUp::ProgressDialog::ProgressDialog( int steps
, QWidget
*parent
) :
257 setCaption(i18n("Cleaning Up"));
258 setButtons( KDialog::None
);
261 QFrame
*top
= new QFrame( this );
262 top
->setGeometry(0,0, w
,h
);
264 QVBoxLayout
*topL
=new QVBoxLayout(top
);
265 topL
->setSpacing(10);
267 QLabel
*l
=new QLabel(i18n("Cleaning up. Please wait..."),top
);
270 KSeparator
*sep
=new KSeparator(top
);
271 topL
->addWidget(sep
);
273 m_sg
=new QLabel(top
);
274 topL
->addWidget(m_sg
);
276 mProgressBar
= new QProgressBar( top
);
277 topL
->addWidget( mProgressBar
);
278 mProgressBar
->setRange( 0, steps
);
279 mProgressBar
->setValue( 0 );
282 if(knGlobals
.topWidget
->isVisible()) {
284 x
=(knGlobals
.topWidget
->width()-w
)/2;
285 y
=(knGlobals
.topWidget
->height()-h
)/2;
290 x
+=knGlobals
.topWidget
->x();
291 y
+=knGlobals
.topWidget
->y();
297 KNCleanUp::ProgressDialog::~ProgressDialog()
302 void KNCleanUp::ProgressDialog::showMessage(const QString
&s
)
308 void KNCleanUp::ProgressDialog::doProgress()
310 mProgressBar
->setValue( mProgressBar
->value() + 1 );
314 void KNCleanUp::ProgressDialog::closeEvent(QCloseEvent
*)
316 // do nothing => prevent that the user closes the window