/******************************************************************************* ** ** Filename : kmmessagetag.cpp ** Created on : 29 June 2007 ** Copyright : (c) 2007 Ismail Onur Filiz ** Email : onurf@su.sabanciuniv.edu ** *******************************************************************************/ /******************************************************************************* ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** In addition, as a special exception, the copyright holders give ** permission to link the code of this program with any edition of ** the Qt library by Trolltech AS, Norway (or with modified versions ** of Qt that use the same license as Qt), and distribute linked ** combinations including the two. You must obey the GNU General ** Public License in all respects for all of the code used other than ** Qt. If you modify this file, you may extend this exception to ** your version of the file, but you are not obligated to do so. If ** you do not wish to do so, delete this exception statement from ** your version. ** *******************************************************************************/ #include "kmmessagetag.h" #include #include "kmkernel.h" #include #include #include #include #include #include #include #include #ifdef Nepomuk_FOUND #include #endif //----------------------------KMMessageTagDescription------------------------------------ KMMessageTagDescription::KMMessageTagDescription( const QString &aLabel, const QString &aName, const int aPriority, const QColor &aTextColor, const QColor &aBackgroundColor, const QFont &aTextFont, const bool aInToolbar, const QString &aIconName, const KShortcut &aShortcut ) { if ( aLabel.isEmpty() || aName.isEmpty() ) { mEmpty = true; return; } mLabel = aLabel; mName = aName; mPriority = aPriority; mTextColor = aTextColor; mBackgroundColor = aBackgroundColor; mTextFont = aTextFont; mInToolbar = aInToolbar; mIconName = aIconName; mShortcut = aShortcut; mEmpty = false; } KMMessageTagDescription::KMMessageTagDescription( const KConfigGroup& aGroup ) : mPriority( -1 ), mEmpty( false ) { readConfig(aGroup); } void KMMessageTagDescription::setLabel( const QString& aLabel ) { mLabel = aLabel; } void KMMessageTagDescription::setName( const QString& aName ) { mName = aName; } /*void KMMessageTagDescription::setBackgroundColor( const QColor& aBackgroundColor ) { mBackgroundColor = aBackgroundColor; }*/ void KMMessageTagDescription::setTextColor( const QColor& aTextColor ) { mTextColor = aTextColor; } void KMMessageTagDescription::setTextFont( const QFont& aTextFont ) { mTextFont = aTextFont; } void KMMessageTagDescription::setIconName( const QString& aIconName ) { mIconName = aIconName; } void KMMessageTagDescription::setShortcut( const KShortcut &aShortcut ) { mShortcut = aShortcut; } void KMMessageTagDescription::readConfig( const KConfigGroup& group ) { mEmpty = true; mLabel = group.readEntry( "Label", QString() ); if ( mLabel.isEmpty() ) return; mName = group.readEntry( "Name", QString() ); if ( mName.isEmpty() ) return; mEmpty = false; //Empty is fine, uses default color mTextColor = group.readEntry( "text-color", QColor()); mBackgroundColor = group.readEntry( "background-color", QColor() ); //Empty uses current standard font mTextFont = group.readEntry( "text-font", QFont() ); mInToolbar = group.readEntry( "toolbar", false ); mIconName = group.readEntry( "icon", "mail-tagged" ); QString shortcut( group.readEntry( "shortcut", QString() ) ); if ( !shortcut.isEmpty() ) mShortcut = KShortcut( shortcut ); purify(); } void KMMessageTagDescription::writeConfig( KConfigGroup &group ) const { group.writeEntry( "Label", mLabel ); group.writeEntry( "Name", mName ); if ( mTextColor.isValid() ) group.writeEntry( "text-color", mTextColor ); if ( mTextFont != QFont() ) group.writeEntry( "text-font", mTextFont ); //Try to use isCopyOf later for the standard font. An alternative //which doesn't work: //if (! mTextFont.isCopyOf(KGlobalSettings::generalFont())) if ( !mShortcut.isEmpty() ) group.writeEntry( "shortcut", mShortcut.toString() ); group.writeEntry( "toolbar", mInToolbar ); group.writeEntry( "icon", mIconName ); } void KMMessageTagDescription::purify() { //fill as necessary } //---------------------------EO KMMessageTagDescription----------------------------------- //-----------------------------KMMessageTagMgr------------------------------------- KMMessageTagMgr::KMMessageTagMgr() : mDirty( 0 ) { mTagDict = new QHash(); mTagList = new QList(); #ifdef Nepomuk_FOUND Nepomuk::ResourceManager::instance()->init(); #endif } KMMessageTagMgr::~KMMessageTagMgr() { writeConfig( false ); clear(); delete mTagDict; delete mTagList; } const KMMessageTagDescription *KMMessageTagMgr::find( const QString &aLabel ) const { QHash< QString, KMMessageTagDescription* >::iterator it = mTagDict->find( aLabel ); return it != mTagDict->end() ? it.value() : 0; } void KMMessageTagMgr::clear() { //Technically we are safe with true always, since there //is supposed to be only one Manager hence dictionary qDeleteAll(*mTagDict); mTagDict->clear(); //TODO: Should I delete the items as well? mTagList->clear(); mDirty = true; } void KMMessageTagMgr::fillTagsFromList( const QList *aTagList ) { clear(); //Assumes the list is ordered if ( aTagList ) { int i = 0; QListIterator it ( *aTagList ); while ( it.hasNext() ) { KMMessageTagDescription *tmp_ptr = new KMMessageTagDescription( *it.next() ); tmp_ptr->setPriority( i ); addTag( tmp_ptr, false ); ++i; } } emit msgTagListChanged(); } void KMMessageTagMgr::createInitialTags() { //Some predefined structures for the very first initialization of tags static const struct { QString name; QString color; } TagNames[] = { { i18n("Friend"), "blue" }, { i18n("Business"), "green" }, { i18n("Later"), "darkCyan"} }; const int n = sizeof TagNames / sizeof *TagNames; for ( int i = 0; i < n; ++i ) { KMMessageTagDescription* tmp_ptr = new KMMessageTagDescription( KRandom::randomString(10), TagNames[i].name, i, TagNames[i].color ); addTag( tmp_ptr, false ); } } void KMMessageTagMgr::addTag( KMMessageTagDescription *aDesc, bool emitChange ) { if (! aDesc) return; mTagDict->insert( aDesc->label(), aDesc ); QList::iterator it = mTagList->begin(); while ( it != mTagList->end() && (*it)->priority() < aDesc->priority() ) it++; mTagList->insert( it, aDesc ); if ( emitChange ) emit msgTagListChanged(); mDirty = true; } void KMMessageTagMgr::readConfig() { KConfig *config = KMKernel::config(); int numTags = 0; QString grpName; clear(); KConfigGroup group( config, "General" ); numTags = group.readEntry( "messagetags", -1 ); if ( numTags < 0 ) { //Key doesn't exist, which probably means first run with the tag feature //Create some tags, put them into dictionary, set dirty createInitialTags(); } else { //j used to handle priorities properly, in case a tag definition is missing int j = 0; for ( int i=0; i < numTags; ++i ) { grpName.sprintf( "MessageTag #%d", i ); if (! config->hasGroup( grpName ) ) { //Something wrong, set dirty so the tag set is correctly written back mDirty = true; continue; } KConfigGroup group( config, grpName ); KMMessageTagDescription *tag = new KMMessageTagDescription( group ); if ( tag->isEmpty() ) { delete tag; } else { tag->setPriority(j); addTag( tag, false ); ++j; } } } } void KMMessageTagMgr::writeConfig( bool withSync ) { KConfig *config = KMKernel::config(); //first, delete all groups: QStringList tagGroups = config->groupList().filter( QRegExp( "MessageTag #\\d+" ) ); foreach ( const QString& group, tagGroups ) config->deleteGroup( group ); // Now, write out the new stuff: int i = 0; foreach ( KMMessageTagDescription *description, *mTagList ) { if ( ! description->isEmpty() ) { QString grpName; grpName.sprintf( "MessageTag #%d", i ); KConfigGroup group( config, grpName ); description->writeConfig( group ); ++i; } } KConfigGroup group( config, "General" ); group.writeEntry( "messagetags", i ); if (withSync) config->sync(); //mDirty = false; } //---------------------------EO KMMessageTagMgr------------------------------------ //-----------------------------KMMessageTagList------------------------------------ KMMessageTagList::KMMessageTagList() : QStringList() { } KMMessageTagList::KMMessageTagList( const QStringList &aList ): QStringList( aList ) { } bool KMMessageTagList::compareTags( const QString &lhs, const QString &rhs) { //Implement less than or equal to const KMMessageTagDescription *lhsptr = kmkernel->msgTagMgr()->find( lhs ); if ( !lhsptr ) return false; const KMMessageTagDescription *rhsptr = kmkernel->msgTagMgr()->find( rhs ); if ( !rhsptr ) return true; return lhsptr->priority() < rhsptr->priority(); } void KMMessageTagList::prioritySort() { //Use bubble sort for now int n = size(); if ( !n ) return; QString tmp, lhs, rhs; for ( int i=0; i< n-1; i++ ) { for ( int j=0; j< n-1-i; j++ ) { lhs = operator[]( j+1 ); rhs = operator[]( j ); if ( compareTags(lhs, rhs) ) { /* compare the two neighbors */ tmp = rhs; /* swap a[j] and a[j+1] */ operator[]( j ) = lhs; operator[]( j+1 ) = tmp; } } } } const KMMessageTagList KMMessageTagList::split( const QString &aSep, const QString &aStr ) { return KMMessageTagList( aStr.split( aSep, QString::SkipEmptyParts ) ); } //----------------------------EO KMMessageTagList---------------------------------- #include "kmmessagetag.moc"