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 ( KNArticleCollection::List::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() ) ); // krazy:exclude=qmethods
63 qApp
->processEvents();
64 expireGroup( boost::static_pointer_cast
<KNGroup
>( (*it
) ) );
67 else if ( (*it
)->type() == KNCollection::CTfolder
) {
68 d_lg
->showMessage( i18n("Compacting folder <b>%1</b>", (*it
)->name() ) ); // krazy:exclude=qmethods
69 qApp
->processEvents();
70 compactFolder( boost::static_pointer_cast
<KNFolder
>( (*it
) ) );
80 void KNCleanUp::reset()
88 void KNCleanUp::expireGroup( KNGroup::Ptr g
, bool showResult
)
90 int expDays
=0, idRef
=0, foundId
=-1, delCnt
=0, leftCnt
=0, newCnt
=0, firstArtNr
=g
->firstNr(), firstNew
=-1;
91 bool unavailable
=false;
92 KNRemoteArticle::Ptr art
, ref
;
94 KNode::Cleanup
*conf
= g
->activeCleanupConfig();
96 g
->setNotUnloadable(true);
98 if (!g
->isLoaded() && !knGlobals
.groupManager()->loadHeaders(g
)) {
99 g
->setNotUnloadable(false);
104 for(int i
=0; i
<g
->length(); ++i
) {
107 expDays
= conf
->maxAgeForRead();
109 expDays
= conf
->maxAgeForUnread();
112 if ((art
->articleNumber() != -1) && conf
->removeUnavailable())
113 unavailable
= (art
->articleNumber() < firstArtNr
);
115 art
->setExpired( (art
->date()->ageInDays() >= expDays
) || unavailable
);
119 if (conf
->preserveThreads()) {
120 for(int i
=0; i
<g
->length(); ++i
) {
122 if(!art
->isExpired()) {
126 ref
->setExpired(false);
134 for(int i
=0; i
<g
->length(); ++i
) {
136 if(!art
->isExpired()) {
139 while(foundId
==0 && idRef
!=0) {
141 if(!ref
->isExpired()) foundId
=ref
->id();
144 art
->setIdRef(foundId
);
149 for(int i
=0; i
<g
->length(); ++i
) {
151 if(art
->isExpired()) {
155 if (art
->hasContent())
156 knGlobals
.articleManager()->unloadArticle(art
, true);
158 else if(art
->isNew() && !art
->isRead()) {
165 g
->setNotUnloadable(false);
168 g
->saveStaticData(g
->length(), true);
169 g
->saveDynamicData(g
->length(), true);
171 g
->setNewCount(newCnt
);
172 g
->setFirstNewIndex(firstNew
);
174 knGlobals
.groupManager()->unloadHeaders(g
, true);
177 g
->syncDynamicData();
179 conf
->setLastExpireDate();
183 kDebug(5003) <<"KNCleanUp::expireGroup() :" << g
->groupname() <<":"
184 << delCnt
<< "deleted ," << leftCnt
<< "left";
187 KMessageBox::information(knGlobals
.topWidget
,
188 i18n("<b>%1</b><br />expired: %2<br />left: %3", g
->groupname(), delCnt
, leftCnt
));
192 void KNCleanUp::compactFolder( KNFolder::Ptr f
)
194 KNLocalArticle::Ptr art
;
204 f
->setNotUnloadable(true);
206 if (!f
->isLoaded() && !knGlobals
.folderManager()->loadHeaders(f
)) {
207 f
->setNotUnloadable(false);
212 QFileInfo
info(f
->m_boxFile
);
213 QString oldName
=info
.fileName();
214 QString newName
=oldName
+".new";
215 QFile
newMBoxFile( info
.absolutePath() + '/' + newName
);
217 if( (f
->m_boxFile
.open(QIODevice::ReadOnly
)) && (newMBoxFile
.open(QIODevice::WriteOnly
)) ) {
218 QTextStream
ts(&newMBoxFile
);
219 ts
.setCodec( "ISO 8859-1" );
220 for(int idx
=0; idx
<f
->length(); idx
++) {
222 if ( f
->m_boxFile
.seek( art
->startOffset() ) ) {
223 ts
<< "From aaa@aaa Mon Jan 01 00:00:00 1997\n";
225 art
->setStartOffset( newMBoxFile
.pos() );
226 while ( f
->m_boxFile
.pos() < (uint
)art
->endOffset() && !f
->m_boxFile
.atEnd() )
227 ts
<< f
->m_boxFile
.readLine();
229 art
->setEndOffset( newMBoxFile
.pos() );
230 newMBoxFile
.putChar('\n');
239 dir
.rename(newName
, oldName
);
242 f
->setNotUnloadable(false);
246 //===============================================================================================
249 KNCleanUp::ProgressDialog::ProgressDialog( int steps
, QWidget
*parent
) :
255 setCaption(i18n("Cleaning Up"));
256 setButtons( KDialog::None
);
259 QFrame
*top
= new QFrame( this );
260 top
->setGeometry(0,0, w
,h
);
262 QVBoxLayout
*topL
=new QVBoxLayout(top
);
263 topL
->setSpacing(10);
265 QLabel
*l
=new QLabel(i18n("Cleaning up. Please wait..."),top
);
268 KSeparator
*sep
=new KSeparator(top
);
269 topL
->addWidget(sep
);
271 m_sg
=new QLabel(top
);
272 topL
->addWidget(m_sg
);
274 mProgressBar
= new QProgressBar( top
);
275 topL
->addWidget( mProgressBar
);
276 mProgressBar
->setRange( 0, steps
);
277 mProgressBar
->setValue( 0 );
280 if(knGlobals
.topWidget
->isVisible()) {
282 x
=(knGlobals
.topWidget
->width()-w
)/2;
283 y
=(knGlobals
.topWidget
->height()-h
)/2;
288 x
+=knGlobals
.topWidget
->x();
289 y
+=knGlobals
.topWidget
->y();
295 KNCleanUp::ProgressDialog::~ProgressDialog()
300 void KNCleanUp::ProgressDialog::showMessage(const QString
&s
)
306 void KNCleanUp::ProgressDialog::doProgress()
308 mProgressBar
->setValue( mProgressBar
->value() + 1 );
312 void KNCleanUp::ProgressDialog::closeEvent(QCloseEvent
*)
314 // do nothing => prevent that the user closes the window