blokkalentry.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "blokkalentry.h"
00021 #include "blokkalentry.moc"
00022
00023 #include "blokkalblog.h"
00024 #include "blokkalaccount.h"
00025 #include "blokkalaccountmanager.h"
00026 #include "blokkalprotocol.h"
00027 #include "blokkalpluginmanager.h"
00028 #include "blokkalui/viewmanager.h"
00029 #include "blokkalui/blogchooser.h"
00030 #include "blokkalui/globalsettings.h"
00031
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034
00035 #include <QDomElement>
00036 #include <QFile>
00037
00038 class Blokkal::Entry::Private
00039 {
00040 public:
00041 Private( void ) :
00042 internalDocument( QDomDocument( "BlokkalEntry" ) ),
00043 refcount( 0 ),
00044 isDirty( FALSE )
00045 {
00046 internalDocument.appendChild( internalDocument.createElement( "entry" ) );
00047 }
00048
00049 QDomDocument internalDocument;
00050 Blokkal::Blog * blog;
00051 int refcount;
00052 bool isDirty;
00053 };
00054
00055 Blokkal::Entry::Entry( Blog * parentBlog, const QString & id, const KUrl & url ) :
00056 QObject( parentBlog ),
00057 Blokkal::ConfigBase(),
00058 d( new Private() )
00059 {
00060 setNode( d->internalDocument.firstChild().toElement() );
00061
00062 d->blog = parentBlog;
00063
00064 node().setAttribute( "blog", parentBlog->id() );
00065 node().setAttribute( "account", parentBlog->account()->id() );
00066 node().setAttribute( "protocol", parentBlog->account()->protocol()->pluginName() );
00067 node().setAttribute( "id", id );
00068 node().setAttribute( "url", url.url() );
00069 }
00070
00071 Blokkal::Entry::~Entry( void )
00072 {
00073 emit entryDestroyed( this );
00074 delete d;
00075 }
00076
00077 QString Blokkal::Entry::id( void ) const
00078 {
00079 return node().attribute( "id" );
00080 }
00081
00082 Blokkal::Blog * Blokkal::Entry::blog( void ) const
00083 {
00084 return d->blog;
00085 }
00086
00087 KIcon Blokkal::Entry::icon( void ) const
00088 {
00089 return blog()->icon();
00090 }
00091
00092 QString Blokkal::Entry::text( void ) const
00093 {
00094 return node().namedItem( "text" ).firstChild().nodeValue();
00095 }
00096
00097 void Blokkal::Entry::setText( const QString & text )
00098 {
00099 QDomElement textParent = d->internalDocument.firstChild().namedItem( "text" ).toElement();
00100 if( textParent.isNull() ) {
00101 textParent = d->internalDocument.createElement( "text" );
00102 d->internalDocument.firstChild().appendChild( textParent );
00103 textParent.appendChild( d->internalDocument.createTextNode( 0 ) );
00104 }
00105
00106 textParent.firstChild().toText().setData( text );
00107 }
00108
00109 QString Blokkal::Entry::subject( void ) const
00110 {
00111 return d->internalDocument.firstChild().namedItem( "subject" ).firstChild().nodeValue();
00112 }
00113
00114
00115 QString Blokkal::Entry::preview( void ) const
00116 {
00117 QString preview = subject();
00118
00119 if( !preview.isEmpty() ) {
00120 return preview;
00121 }
00122
00123 preview = text();
00124
00125 if( preview.isEmpty() ) {
00126 return i18n( "<No Subject>" );
00127 }
00128
00129 if( preview.length() > 100 ) {
00130 preview = preview.left( 100 );
00131 preview.replace( 97, 3, i18n( "..." ) );
00132 }
00133
00134 return preview;
00135 }
00136
00137 void Blokkal::Entry::setSubject( const QString & subject )
00138 {
00139 QDomElement subjectParent = d->internalDocument.firstChild().namedItem( "subject" ).toElement();
00140
00141 if( subjectParent.isNull() ) {
00142 subjectParent = d->internalDocument.createElement( "subject" );
00143 d->internalDocument.firstChild().appendChild( subjectParent );
00144 subjectParent.appendChild( d->internalDocument.createTextNode( 0 ) );
00145 }
00146
00147 subjectParent.firstChild().toText().setData( subject );
00148 }
00149
00150 QDateTime Blokkal::Entry::date( void ) const
00151 {
00152 QDateTime entryDate;
00153 QDomElement entryElement = d->internalDocument.firstChild().toElement();
00154
00155 if( entryElement.hasAttribute( "date" ) ) {
00156 entryDate.setTime_t( entryElement.attribute( "date" ).toUInt() );
00157 }
00158
00159 return entryDate;
00160 }
00161
00162 void Blokkal::Entry::setDate( const QDateTime & date )
00163 {
00164 d->internalDocument.firstChild().toElement().setAttribute( "date", date.toTime_t() );
00165 }
00166
00167 Blokkal::Ui::View * Blokkal::Entry::view( void )
00168 {
00169 return Ui::ViewManager::self()->view( this );
00170 }
00171
00172 void Blokkal::Entry::ref( void )
00173 {
00174 d->refcount++;
00175 }
00176
00177 void Blokkal::Entry::deref( void )
00178 {
00179 d->refcount--;
00180 if( d->refcount < 1 && !Blokkal::Ui::ViewManager::hasView( this ) ) {
00181 deleteLater();
00182 }
00183 }
00184
00185 QString Blokkal::Entry::fileName( bool check ) const
00186 {
00187 QString fileName = node().attribute( "filename" );
00188 if( check && !QFile::exists( fileName) ) {
00189 fileName = QString::null;
00190 setFileName( fileName );
00191
00192 }
00193 return fileName;
00194 }
00195
00196 void Blokkal::Entry::setFileName( const QString & fileName ) const
00197 {
00198 node().setAttribute( "filename", fileName );
00199 }
00200
00201 bool Blokkal::Entry::saveAs( const QString & fileName )
00202 {
00203 QFile file( fileName );
00204 if( !file.open( QIODevice::WriteOnly ) ) {
00205 kError() << "error opening file for reading" << file.fileName() << endl;
00206 return FALSE;
00207 }
00208
00209 saveProperties();
00210 setFileName( QString::null );
00211
00212 QTextStream fileStream( &file );
00213 node().ownerDocument().save( fileStream, 3 );
00214 file.close();
00215
00216 setFileName( fileName );
00217 return TRUE;
00218 }
00219
00220 Blokkal::Entry * Blokkal::Entry::open( const QString & fileName, bool * canceled, bool neverAsk )
00221 {
00222 bool error = FALSE;
00223
00224 if( canceled ) {
00225 *canceled = FALSE;
00226 }
00227
00228 QDomDocument document( "BlokkalEntry" );
00229
00230
00231 QFile file( fileName );
00232 if( file.open( QIODevice::ReadOnly ) ) {
00233 if( !document.setContent( &file ) ) {
00234 kError() << "error parsing file " << file.fileName() << endl;
00235 error = TRUE;
00236 }
00237 file.close();
00238 }
00239 else {
00240 kError() << "error opening file " << file.fileName() << endl;
00241 error = TRUE;
00242 }
00243
00244 if( error ) {
00245 return 0;
00246 }
00247
00248
00249 QDomElement entryNode = document.firstChild().toElement();
00250 if( entryNode.isNull() ) {
00251 kError() << "malformed file " << file.fileName() << endl;
00252 return 0;
00253 }
00254
00255 const QString blogId = entryNode.attribute( "blog" );
00256 const QString accountId = entryNode.attribute( "account" );
00257 const QString protocolName = entryNode.attribute( "protocol" );
00258
00259 QString message;
00260 Blog * blog = 0;
00261 Account * account = AccountManager::self()->account( accountId );
00262 if( !account ) {
00263 message = i18n( "No account could be found for this entry. Please select the correct account and blog manually." );
00264 }
00265 else {
00266 blog = account->blog( blogId );
00267 if( !blog || account->protocol()->pluginName() != protocolName ) {
00268 if( blog ) {
00269 message = i18n( "An account and a blog for the entry have been found. However, the protocol does not match. Please review the selection." );
00270 }
00271 else {
00272 message = i18n( "An account for the entry has been found. However, the account does not contain the blog this entry belongs to. Please select the correct blog manually.");
00273 }
00274 }
00275 }
00276
00277 if( !message.isEmpty() ) {
00278 if( neverAsk ) {
00279 return 0;
00280 }
00281
00282 Ui::BlogChooserDialog * dialog = new Ui::BlogChooserDialog( message, Ui::GlobalSettings::self()->mainWidget() );
00283 dialog->blogChooser()->setAccount( account );
00284 dialog->blogChooser()->setBlog( blog );
00285 blog = 0;
00286
00287 if( dialog->exec() ) {
00288 blog = dialog->blogChooser()->blog();
00289 }
00290 else if( canceled ) {
00291 *canceled = TRUE;
00292 }
00293
00294 delete dialog;
00295 }
00296
00297 if( !blog ) {
00298 return 0;
00299 }
00300
00301 Entry * entry = blog->createEntry();
00302 entry->d->internalDocument = document;
00303 entry->setNode( entryNode );
00304 entry->setFileName( fileName );
00305
00306 entry->node().setAttribute( "blog", blog->id() );
00307 entry->node().setAttribute( "account", blog->account()->id() );
00308 entry->node().setAttribute( "protocol", blog->account()->protocol()->pluginName() );
00309 entry->readProperties();
00310
00311 return entry;
00312 }
00313
00314 Blokkal::Ui::EntryExtensionWidget * Blokkal::Entry::createExtensionWidget( Ui::EntryExtensionWidget::ExtensionWidget , Blokkal::Ui::EditEntryWidget * )
00315 {
00316 return 0;
00317 }
00318
00319 QStringList Blokkal::Entry::categories( void ) const
00320 {
00321 QStringList ids;
00322
00323
00324 for( QDomNode currentNode = node().firstChild();
00325 !currentNode.isNull();
00326 currentNode = currentNode.nextSibling()
00327 )
00328 {
00329 if( currentNode.isElement()
00330 && currentNode.nodeName() == "category" )
00331 {
00332 ids.append( currentNode.toElement().attribute( "id" ) );
00333 }
00334 }
00335
00336 return ids;
00337 }
00338
00339 void Blokkal::Entry::setCategories( const QStringList & ids )
00340 {
00341 for( QDomNode currentNode = node().firstChild();
00342 !currentNode.isNull();)
00343 {
00344 if( currentNode.isElement()
00345 && currentNode.nodeName() == "category" )
00346 {
00347 QDomNode obsoleteNode = currentNode;
00348 currentNode = currentNode.nextSibling();
00349 node().removeChild( obsoleteNode );
00350 }
00351 else {
00352 currentNode = currentNode.nextSibling();
00353 }
00354 }
00355
00356
00357 for( QStringList::ConstIterator it = ids.begin();
00358 it != ids.end();
00359 ++it )
00360 {
00361 QDomElement categoryElement = node().ownerDocument().createElement( "category" );
00362 node().appendChild( categoryElement );
00363 categoryElement.setAttribute( "id", *it );
00364 }
00365 }
00366
00367 void Blokkal::Entry::merge( const Blokkal::Entry * entry )
00368 {
00369 setDate( entry->date() );
00370 setSubject( entry->subject() );
00371 setText( entry->text() );
00372 }
00373
00374 bool Blokkal::Entry::isDirty( void ) const
00375 {
00376 return d->isDirty;
00377 }
00378
00379 void Blokkal::Entry::setDirty( bool dirty )
00380 {
00381 d->isDirty = dirty;
00382 }
00383
00384 KUrl Blokkal::Entry::url( void ) const
00385 {
00386 return node().attribute( "url" );
00387 }
00388
00389 void Blokkal::Entry::saveProperties( void )
00390 {
00391 }
00392
00393 void Blokkal::Entry::readProperties( void )
00394 {
00395 }