From cc29364f06178f8f6b457384f2ec37a042bd9d43 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 1 Sep 2010 00:37:02 +0000 Subject: * Massive set of changes to bring in all fixes and enhancements from the Enterprise PIM branch * Ensured that the Trinity changes were applied on top of those enhancements, and any redundancy removed * Added journal read support to the CalDAV resource * Fixed CalDAV resource to use events URL for tasks and journals when separate URL checkbox unchecked git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1170461 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- libkdepim/addresseelineedit.cpp | 354 +++++++++++++++------ libkdepim/addresseelineedit.h | 13 +- libkdepim/addressesdialog.cpp | 123 +++++-- libkdepim/calendardiffalgo.h | 3 +- libkdepim/completionordereditor.cpp | 23 +- libkdepim/csshelper.cpp | 14 + libkdepim/csshelper.h | 2 + libkdepim/distributionlist.cpp | 8 +- libkdepim/htmldiffalgodisplay.h | 3 +- libkdepim/kabcresourcecached.cpp | 22 ++ libkdepim/kaddrbook.cpp | 61 ++-- libkdepim/kaddrbook.h | 15 + libkdepim/kcmdesignerfields.cpp | 1 + libkdepim/kdepimprotocols.h | 32 ++ libkdepim/kfoldertree.h | 11 +- libkdepim/kincidencechooser.cpp | 58 ++-- libkdepim/kincidencechooser.h | 53 ++- libkdepim/komposer/core/komposerconfig.desktop | 2 - libkdepim/komposer/core/komposereditor.desktop | 1 - libkdepim/komposer/core/komposerplugin.desktop | 1 - .../komposer/plugins/default/defaulteditor.desktop | 2 - libkdepim/kprefsdialog.cpp | 2 +- libkdepim/ktimeedit.cpp | 2 +- libkdepim/kvcarddrag.cpp | 39 ++- libkdepim/kvcarddrag.h | 14 +- libkdepim/ldapclient.cpp | 32 +- libkdepim/ldapclient.h | 2 + libkdepim/ldapsearchdialog.cpp | 22 +- libkdepim/ldapsearchdialog.h | 2 +- libkdepim/progressdialog.cpp | 18 ++ libkdepim/progressdialog.h | 2 + libkdepim/progressmanager.cpp | 17 +- libkdepim/progressmanager.h | 27 ++ libkdepim/statusbarprogresswidget.cpp | 13 +- libkdepim/statusbarprogresswidget.h | 1 + libkdepim/tests/Makefile.am | 11 +- libkdepim/tests/testkincidencechooser.cpp | 45 +++ libkdepim/tests/testutf7encoder2.cpp | 6 +- 38 files changed, 787 insertions(+), 270 deletions(-) create mode 100644 libkdepim/kdepimprotocols.h create mode 100644 libkdepim/tests/testkincidencechooser.cpp (limited to 'libkdepim') diff --git a/libkdepim/addresseelineedit.cpp b/libkdepim/addresseelineedit.cpp index 7031a83eb..5e3d0cf39 100644 --- a/libkdepim/addresseelineedit.cpp +++ b/libkdepim/addresseelineedit.cpp @@ -70,12 +70,23 @@ KPIM::LdapSearch* AddresseeLineEdit::s_LDAPSearch = 0L; TQString* AddresseeLineEdit::s_LDAPText = 0L; AddresseeLineEdit* AddresseeLineEdit::s_LDAPLineEdit = 0L; +// The weights associated with the completion sources in s_completionSources. +// Both are maintained by addCompletionSource(), don't attempt to modifiy those yourself. +TQMap* s_completionSourceWeights = 0; + +// maps LDAP client indices to completion source indices +// the assumption that they are always the first n indices in s_completion +// does not hold when clients are added later on +TQMap* AddresseeLineEdit::s_ldapClientToCompletionSourceMap = 0; + static KStaticDeleter completionDeleter; static KStaticDeleter completionItemsDeleter; static KStaticDeleter ldapTimerDeleter; static KStaticDeleter ldapSearchDeleter; static KStaticDeleter ldapTextDeleter; static KStaticDeleter completionSourcesDeleter; +static KStaticDeleter > completionSourceWeightsDeleter; +static KStaticDeleter > ldapClientToCompletionSourceMapDeleter; // needs to be unique, but the actual name doesn't matter much static TQCString newLineEditDCOPObjectName() @@ -100,7 +111,8 @@ static bool itemIsHeader( const TQListBoxItem* item ) AddresseeLineEdit::AddresseeLineEdit( TQWidget* parent, bool useCompletion, const char *name ) - : ClickLineEdit( parent, TQString::null, name ), DCOPObject( newLineEditDCOPObjectName() ) + : ClickLineEdit( parent, TQString::null, name ), DCOPObject( newLineEditDCOPObjectName() ), + m_useSemiColonAsSeparator( false ), m_allowDistLists( true ) { m_useCompletion = useCompletion; m_completionInitialized = false; @@ -114,6 +126,18 @@ AddresseeLineEdit::AddresseeLineEdit( TQWidget* parent, bool useCompletion, s_addressesDirty = true; } +void AddresseeLineEdit::updateLDAPWeights() +{ + /* Add completion sources for all ldap server, 0 to n. Added first so + * that they map to the ldapclient::clientNumber() */ + s_LDAPSearch->updateCompletionWeights(); + TQValueList< LdapClient* > clients = s_LDAPSearch->clients(); + int clientIndex = 0; + for ( TQValueList::iterator it = clients.begin(); it != clients.end(); ++it, ++clientIndex ) { + const int sourceIndex = addCompletionSource( "LDAP server: " + (*it)->server().host(), (*it)->completionWeight() ); + s_ldapClientToCompletionSourceMap->insert( clientIndex, sourceIndex ); + } +} void AddresseeLineEdit::init() { @@ -124,8 +148,9 @@ void AddresseeLineEdit::init() completionItemsDeleter.setObject( s_completionItemMap, new KPIM::CompletionItemsMap() ); completionSourcesDeleter.setObject( s_completionSources, new TQStringList() ); + completionSourceWeightsDeleter.setObject( s_completionSourceWeights, new TQMap ); + ldapClientToCompletionSourceMapDeleter.setObject( s_ldapClientToCompletionSourceMap, new TQMap ); } - // connect( s_completion, TQT_SIGNAL( match( const TQString& ) ), // this, TQT_SLOT( slotMatched( const TQString& ) ) ); @@ -134,14 +159,10 @@ void AddresseeLineEdit::init() ldapTimerDeleter.setObject( s_LDAPTimer, new TQTimer( 0, "ldapTimerDeleter" ) ); ldapSearchDeleter.setObject( s_LDAPSearch, new KPIM::LdapSearch ); ldapTextDeleter.setObject( s_LDAPText, new TQString ); - - /* Add completion sources for all ldap server, 0 to n. Added first so - * that they map to the ldapclient::clientNumber() */ - TQValueList< LdapClient* > clients = s_LDAPSearch->clients(); - for ( TQValueList::iterator it = clients.begin(); it != clients.end(); ++it ) { - addCompletionSource( "LDAP server: " + (*it)->server().host() ); - } } + + updateLDAPWeights(); + if ( !m_completionInitialized ) { setCompletionObject( s_completion, false ); connect( this, TQT_SIGNAL( completion( const TQString& ) ), @@ -187,6 +208,11 @@ void AddresseeLineEdit::allowSemiColonAsSeparator( bool useSemiColonAsSeparator m_useSemiColonAsSeparator = useSemiColonAsSeparator; } +void AddresseeLineEdit::allowDistributionLists( bool allowDistLists ) +{ + m_allowDistLists = allowDistLists; +} + void AddresseeLineEdit::keyPressEvent( TQKeyEvent *e ) { bool accept = false; @@ -206,9 +232,15 @@ void AddresseeLineEdit::keyPressEvent( TQKeyEvent *e ) } } + const TQString oldContent = text(); if ( !accept ) KLineEdit::keyPressEvent( e ); + // if the text didn't change (eg. because a cursor navigation key was pressed) + // we don't need to trigger a new search + if ( oldContent == text() ) + return; + if ( e->isAccepted() ) { updateSearchString(); TQString searchString( m_searchString ); @@ -264,24 +296,25 @@ void AddresseeLineEdit::insert( const TQString &t ) TQString contents = text(); int start_sel = 0; - int end_sel = 0; int pos = cursorPosition( ); - if ( getSelection( &start_sel, &end_sel ) ) { + + if ( hasSelectedText() ) { // Cut away the selection. - if ( pos > end_sel ) - pos -= (end_sel - start_sel); - else if ( pos > start_sel ) - pos = start_sel; - contents = contents.left( start_sel ) + contents.right( end_sel + 1 ); + start_sel = selectionStart(); + pos = start_sel; + contents = contents.left( start_sel ) + contents.mid( start_sel + selectedText().length() ); } int eot = contents.length(); - while ((eot > 0) && contents[ eot - 1 ].isSpace() ) eot--; - if ( eot == 0 ) + while ( ( eot > 0 ) && contents[ eot - 1 ].isSpace() ) { + eot--; + } + if ( eot == 0 ) { contents = TQString::null; - else if ( pos >= eot ) { - if ( contents[ eot - 1 ] == ',' ) + } else if ( pos >= eot ) { + if ( contents[ eot - 1 ] == ',' ) { eot--; + } contents.truncate( eot ); contents += ", "; pos = eot + 2; @@ -324,35 +357,45 @@ void AddresseeLineEdit::mouseReleaseEvent( TQMouseEvent *e ) void AddresseeLineEdit::dropEvent( TQDropEvent *e ) { KURL::List uriList; - if ( !isReadOnly() - && KURLDrag::canDecode(e) && KURLDrag::decode( e, uriList ) ) { - TQString contents = text(); - // remove trailing white space and comma - int eot = contents.length(); - while ( ( eot > 0 ) && contents[ eot - 1 ].isSpace() ) - eot--; - if ( eot == 0 ) - contents = TQString::null; - else if ( contents[ eot - 1 ] == ',' ) { - eot--; - contents.truncate( eot ); - } - bool mailtoURL = false; - // append the mailto URLs - for ( KURL::List::Iterator it = uriList.begin(); - it != uriList.end(); ++it ) { - if ( !contents.isEmpty() ) - contents.append( ", " ); - KURL u( *it ); - if ( u.protocol() == "mailto" ) { - mailtoURL = true; - contents.append( (*it).path() ); + if ( !isReadOnly() ) { + if ( KURLDrag::canDecode(e) && KURLDrag::decode( e, uriList ) ) { + TQString contents = text(); + // remove trailing white space and comma + int eot = contents.length(); + while ( ( eot > 0 ) && contents[ eot - 1 ].isSpace() ) + eot--; + if ( eot == 0 ) + contents = TQString::null; + else if ( contents[ eot - 1 ] == ',' ) { + eot--; + contents.truncate( eot ); + } + bool mailtoURL = false; + // append the mailto URLs + for ( KURL::List::Iterator it = uriList.begin(); + it != uriList.end(); ++it ) { + if ( !contents.isEmpty() ) + contents.append( ", " ); + KURL u( *it ); + if ( u.protocol() == "mailto" ) { + mailtoURL = true; + contents.append( (*it).path() ); + } + } + if ( mailtoURL ) { + setText( contents ); + setEdited( true ); + return; + } + } else { + // Let's see if this drop contains a comma separated list of emails + TQString dropData = TQString::fromUtf8( e->encodedData( "text/plain" ) ); + TQStringList addrs = splitEmailAddrList( dropData ); + if ( addrs.count() > 0 ) { + setText( normalizeAddressesAndDecodeIDNs( dropData ) ); + setEdited( true ); + return; } - } - if ( mailtoURL ) { - setText( contents ); - setEdited( true ); - return; } } @@ -526,21 +569,19 @@ void AddresseeLineEdit::loadContacts() TQString uid = (*it).uid(); TQMap::const_iterator wit = uidToResourceMap.find( uid ); const TQString subresourceLabel = resabc->subresourceLabel( *wit ); - int idx = s_completionSources->findIndex( subresourceLabel ); - if ( idx == -1 ) { - s_completionSources->append( subresourceLabel ); - idx = s_completionSources->size() -1; - } - int weight = ( wit != uidToResourceMap.end() ) ? resabc->subresourceCompletionWeight( *wit ) : 80; + const int weight = ( wit != uidToResourceMap.end() ) ? resabc->subresourceCompletionWeight( *wit ) : 80; + const int idx = addCompletionSource( subresourceLabel, weight ); + //kdDebug(5300) << (*it).fullEmail() << " subres=" << *wit << " weight=" << weight << endl; addContact( *it, weight, idx ); } } else { // KABC non-imap resource int weight = config.readNumEntry( resource->identifier(), 60 ); - s_completionSources->append( resource->resourceName() ); + int sourceIndex = addCompletionSource( resource->resourceName(), weight ); KABC::Resource::Iterator it; - for ( it = resource->begin(); it != resource->end(); ++it ) - addContact( *it, weight, s_completionSources->size()-1 ); + for ( it = resource->begin(); it != resource->end(); ++it ) { + addContact( *it, weight, sourceIndex ); + } } } @@ -577,12 +618,14 @@ void AddresseeLineEdit::addContact( const KABC::Addressee& addr, int weight, int if ( KPIM::DistributionList::isDistributionList( addr ) ) { //kdDebug(5300) << "AddresseeLineEdit::addContact() distribution list \"" << addr.formattedName() << "\" weight=" << weight << endl; - //for CompletionAuto - addCompletionItem( addr.formattedName(), weight, source ); + if ( m_allowDistLists ) { + //for CompletionAuto + addCompletionItem( addr.formattedName(), weight, source ); - //for CompletionShell, CompletionPopup - TQStringList sl( addr.formattedName() ); - addCompletionItem( addr.formattedName(), weight, source, &sl ); + //for CompletionShell, CompletionPopup + TQStringList sl( addr.formattedName() ); + addCompletionItem( addr.formattedName(), weight, source, &sl ); + } return; } @@ -730,6 +773,11 @@ void AddresseeLineEdit::addCompletionItem( const TQString& string, int weight, i void AddresseeLineEdit::slotStartLDAPLookup() { + KGlobalSettings::Completion mode = completionMode(); + + if ( mode == KGlobalSettings::CompletionNone ) + return; + if ( !s_LDAPSearch->isAvailable() ) { return; } @@ -765,7 +813,7 @@ void AddresseeLineEdit::startLoadingLDAPEntries() void AddresseeLineEdit::slotLDAPSearchData( const KPIM::LdapResultList& adrs ) { - if ( s_LDAPLineEdit != this ) + if ( adrs.isEmpty() || s_LDAPLineEdit != this ) return; for ( KPIM::LdapResultList::ConstIterator it = adrs.begin(); it != adrs.end(); ++it ) { @@ -773,14 +821,20 @@ void AddresseeLineEdit::slotLDAPSearchData( const KPIM::LdapResultList& adrs ) addr.setNameFromString( (*it).name ); addr.setEmails( (*it).email ); - addContact( addr, (*it).completionWeight, (*it ).clientNumber ); + if ( !s_ldapClientToCompletionSourceMap->contains( (*it).clientNumber ) ) + updateLDAPWeights(); // we got results from a new source, so update the completion sources + + addContact( addr, (*it).completionWeight, (*s_ldapClientToCompletionSourceMap)[ (*it ).clientNumber ] ); } if ( (hasFocus() || completionBox()->hasFocus() ) && completionMode() != KGlobalSettings::CompletionNone - && completionMode() != KGlobalSettings::CompletionShell) { + && completionMode() != KGlobalSettings::CompletionShell ) { setText( m_previousAddresses + m_searchString ); - doCompletion( m_lastSearchMode ); + // only complete again if the user didn't change the selection while we were waiting + // otherwise the completion box will be closed + if ( m_searchString.stripWhiteSpace() != completionBox()->currentText().stripWhiteSpace() ) + doCompletion( m_lastSearchMode ); } } @@ -881,6 +935,10 @@ void AddresseeLineEdit::slotEditCompletionOrder() init(); // for s_LDAPSearch CompletionOrderEditor editor( s_LDAPSearch, this ); editor.exec(); + if ( m_useCompletion ) { + updateLDAPWeights(); + s_addressesDirty = true; + } } void KPIM::AddresseeLineEdit::slotIMAPCompletionOrderChanged() @@ -902,15 +960,23 @@ void AddresseeLineEdit::updateSearchString() int n = -1; bool inQuote = false; - for ( uint i = 0; i < m_searchString.length(); ++i ) { - if ( m_searchString[ i ] == '"' ) + uint searchStringLength = m_searchString.length(); + for ( uint i = 0; i < searchStringLength; ++i ) { + if ( m_searchString[ i ] == '"' ) { inQuote = !inQuote; - if ( m_searchString[ i ] == '\\' && (i + 1) < m_searchString.length() && m_searchString[ i + 1 ] == '"' ) + } + if ( m_searchString[ i ] == '\\' && + (i + 1) < searchStringLength && m_searchString[ i + 1 ] == '"' ) { ++i; - if ( inQuote ) + } + if ( inQuote ) { continue; - if ( m_searchString[ i ] == ',' || ( m_useSemiColonAsSeparator && m_searchString[ i ] == ';' ) ) + } + if ( i < searchStringLength && + ( m_searchString[ i ] == ',' || + ( m_useSemiColonAsSeparator && m_searchString[ i ] == ';' ) ) ) { n = i; + } } if ( n >= 0 ) { @@ -924,9 +990,7 @@ void AddresseeLineEdit::updateSearchString() m_previousAddresses = m_searchString.left( n ); m_searchString = m_searchString.mid( n ).stripWhiteSpace(); - } - else - { + } else { m_previousAddresses = TQString::null; } } @@ -954,18 +1018,30 @@ KCompletion::CompOrder KPIM::AddresseeLineEdit::completionOrder() return KCompletion::Sorted; } -int KPIM::AddresseeLineEdit::addCompletionSource( const TQString &source ) +int KPIM::AddresseeLineEdit::addCompletionSource( const TQString &source, int weight ) { - s_completionSources->append( source ); - return s_completionSources->size()-1; + TQMap::iterator it = s_completionSourceWeights->find( source ); + if ( it == s_completionSourceWeights->end() ) + s_completionSourceWeights->insert( source, weight ); + else + (*s_completionSourceWeights)[source] = weight; + + int sourceIndex = s_completionSources->findIndex( source ); + if ( sourceIndex == -1 ) { + s_completionSources->append( source ); + return s_completionSources->size() - 1; + } + else + return sourceIndex; } bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) { if ( obj == completionBox() ) { - if ( e->type() == TQEvent::MouseButtonPress - || e->type() == TQEvent::MouseMove - || e->type() == TQEvent::MouseButtonRelease ) { + if ( e->type() == TQEvent::MouseButtonPress || + e->type() == TQEvent::MouseMove || + e->type() == TQEvent::MouseButtonRelease || + e->type() == TQEvent::MouseButtonDblClick ) { TQMouseEvent* me = static_cast( e ); // find list box item at the event position TQListBoxItem *item = completionBox()->itemAt( me->pos() ); @@ -1003,26 +1079,35 @@ bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) } } if ( ( obj == this ) && - ( e->type() == TQEvent::KeyPress ) && - completionBox()->isVisible() ) { + ( e->type() == TQEvent::KeyPress || e->type() == TQEvent::KeyRelease ) && + completionBox()->isVisible() ) { TQKeyEvent *ke = static_cast( e ); - unsigned int currentIndex = completionBox()->currentItem(); + int currentIndex = completionBox()->currentItem(); + if ( currentIndex < 0 ) { + return true; + } + if ( ke->key() == Key_Up ) { //kdDebug() << "EVENTFILTER: Key_Up currentIndex=" << currentIndex << endl; // figure out if the item we would be moving to is one we want // to ignore. If so, go one further - TQListBoxItem *itemAbove = completionBox()->item( currentIndex - 1 ); + TQListBoxItem *itemAbove = completionBox()->item( currentIndex ); if ( itemAbove && itemIsHeader(itemAbove) ) { // there is a header above us, check if there is even further up // and if so go one up, so it'll be selected - if ( currentIndex > 1 && completionBox()->item( currentIndex - 2 ) ) { + if ( currentIndex > 0 && completionBox()->item( currentIndex - 1 ) ) { //kdDebug() << "EVENTFILTER: Key_Up -> skipping " << currentIndex - 1 << endl; completionBox()->setCurrentItem( itemAbove->prev() ); - completionBox()->setSelected( currentIndex - 2, true ); - } else if ( currentIndex == 1 ) { + completionBox()->setSelected( currentIndex - 1, true ); + } else if ( currentIndex == 0 ) { // nothing to skip to, let's stay where we are, but make sure the // first header becomes visible, if we are the first real entry completionBox()->ensureVisible( 0, 0 ); + //Kolab issue 2941: be sure to add email even if it's the only element. + if ( itemIsHeader( completionBox()->item( currentIndex ) ) ) { + currentIndex++; + } + completionBox()->setCurrentItem( itemAbove ); completionBox()->setSelected( currentIndex, true ); } return true; @@ -1030,14 +1115,15 @@ bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) } else if ( ke->key() == Key_Down ) { // same strategy for downwards //kdDebug() << "EVENTFILTER: Key_Down. currentIndex=" << currentIndex << endl; - TQListBoxItem *itemBelow = completionBox()->item( currentIndex + 1 ); + TQListBoxItem *itemBelow = completionBox()->item( currentIndex ); if ( itemBelow && itemIsHeader( itemBelow ) ) { - if ( completionBox()->item( currentIndex + 2 ) ) { + if ( completionBox()->item( currentIndex + 1 ) ) { //kdDebug() << "EVENTFILTER: Key_Down -> skipping " << currentIndex+1 << endl; completionBox()->setCurrentItem( itemBelow->next() ); - completionBox()->setSelected( currentIndex + 2, true ); + completionBox()->setSelected( currentIndex + 1, true ); } else { // nothing to skip to, let's stay where we are + completionBox()->setCurrentItem( itemBelow ); completionBox()->setSelected( currentIndex, true ); } return true; @@ -1052,11 +1138,14 @@ bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) TQListBoxItem *item = completionBox()->item( currentIndex ); if ( item && itemIsHeader(item) ) { completionBox()->setSelected( currentIndex, true ); - } - } else if ( ke->key() == Key_Tab || ke->key() == Key_Backtab ) { - /// first, find the header of teh current section + } + } else if ( e->type() == TQEvent::KeyRelease && + ( ke->key() == Key_Tab || ke->key() == Key_Backtab ) ) { + //kdDebug() << "EVENTFILTER: Key_Tab. currentIndex=" << currentIndex << endl; + /// first, find the header of the current section TQListBoxItem *myHeader = 0; - int i = currentIndex; + const int iterationstep = ke->key() == Key_Tab ? 1 : -1; + int i = QMIN( QMAX( currentIndex - iterationstep, 0 ), completionBox()->count() - 1 ); while ( i>=0 ) { if ( itemIsHeader( completionBox()->item(i) ) ) { myHeader = completionBox()->item( i ); @@ -1066,22 +1155,31 @@ bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) } Q_ASSERT( myHeader ); // we should always be able to find a header - // find the next header (searching backwards, for Key_Backtab + // find the next header (searching backwards, for Key_Backtab) TQListBoxItem *nextHeader = 0; - const int iterationstep = ke->key() == Key_Tab ? 1 : -1; // when iterating forward, start at the currentindex, when backwards, // one up from our header, or at the end - uint j = ke->key() == Key_Tab ? currentIndex : i==0 ? completionBox()->count()-1 : (i-1) % completionBox()->count(); + uint j; + if ( ke->key() == Key_Tab ) { + j = currentIndex; + } else { + i = completionBox()->index( myHeader ); + if ( i == 0 ) { + j = completionBox()->count() - 1; + } else { + j = ( i - 1 ) % completionBox()->count(); + } + } while ( ( nextHeader = completionBox()->item( j ) ) && nextHeader != myHeader ) { if ( itemIsHeader(nextHeader) ) { - break; + break; } j = (j + iterationstep) % completionBox()->count(); } if ( nextHeader && nextHeader != myHeader ) { TQListBoxItem *item = completionBox()->item( j + 1 ); if ( item && !itemIsHeader(item) ) { - completionBox()->setSelected( j+1, true ); + completionBox()->setSelected( item, true ); completionBox()->setCurrentItem( item ); completionBox()->ensureCurrentVisible(); } @@ -1092,20 +1190,49 @@ bool KPIM::AddresseeLineEdit::eventFilter(TQObject *obj, TQEvent *e) return ClickLineEdit::eventFilter( obj, e ); } +class SourceWithWeight { + public: + int weight; // the weight of the source + TQString sourceName; // the name of the source, e.g. "LDAP Server" + int index; // index into s_completionSources + + bool operator< ( const SourceWithWeight &other ) { + if ( weight > other.weight ) + return true; + if ( weight < other.weight ) + return false; + return sourceName < other.sourceName; + } +}; + const TQStringList KPIM::AddresseeLineEdit::getAdjustedCompletionItems( bool fullSearch ) { TQStringList items = fullSearch ? s_completion->allMatches( m_searchString ) : s_completion->substringCompletion( m_searchString ); + // For weighted mode, the algorithm is the following: + // In the first loop, we add each item to its section (there is one section per completion source) + // We also add spaces in front of the items. + // The sections are appended to the items list. + // In the second loop, we then walk through the sections and add all the items in there to the + // sorted item list, which is the final result. + // + // The algo for non-weighted mode is different. + int lastSourceIndex = -1; unsigned int i = 0; + + // Maps indices of the items list, which are section headers/source items, + // to a TQStringList which are the items of that section/source. TQMap sections; TQStringList sortedItems; for ( TQStringList::Iterator it = items.begin(); it != items.end(); ++it, ++i ) { CompletionItemsMap::const_iterator cit = s_completionItemMap->find(*it); - if ( cit == s_completionItemMap->end() )continue; + if ( cit == s_completionItemMap->end() ) + continue; int idx = (*cit).second; + if ( s_completion->order() == KCompletion::Weighted ) { if ( lastSourceIndex == -1 || lastSourceIndex != idx ) { const TQString sourceLabel( (*s_completionSources)[idx] ); @@ -1124,11 +1251,30 @@ const TQStringList KPIM::AddresseeLineEdit::getAdjustedCompletionItems( bool ful sortedItems.append( *it ); } } + if ( s_completion->order() == KCompletion::Weighted ) { - for ( TQMap::Iterator it( sections.begin() ), end( sections.end() ); it != end; ++it ) { - sortedItems.append( (*s_completionSources)[it.key()] ); - for ( TQStringList::Iterator sit( (*it).begin() ), send( (*it).end() ); sit != send; ++sit ) { - sortedItems.append( *sit ); + + // Sort the sections + TQValueList sourcesAndWeights; + for ( uint i = 0; i < s_completionSources->size(); i++ ) { + SourceWithWeight sww; + sww.sourceName = (*s_completionSources)[i]; + sww.weight = (*s_completionSourceWeights)[sww.sourceName]; + sww.index = i; + sourcesAndWeights.append( sww ); + } + qHeapSort( sourcesAndWeights ); + + // Add the sections and their items to the final sortedItems result list + for( uint i = 0; i < sourcesAndWeights.size(); i++ ) { + TQStringList sectionItems = sections[sourcesAndWeights[i].index]; + if ( !sectionItems.isEmpty() ) { + sortedItems.append( sourcesAndWeights[i].sourceName ); + TQStringList sectionItems = sections[sourcesAndWeights[i].index]; + for ( TQStringList::Iterator sit( sectionItems.begin() ), send( sectionItems.end() ); + sit != send; ++sit ) { + sortedItems.append( *sit ); + } } } } else { diff --git a/libkdepim/addresseelineedit.h b/libkdepim/addresseelineedit.h index 5f8d2f496..86d8d8db2 100644 --- a/libkdepim/addresseelineedit.h +++ b/libkdepim/addresseelineedit.h @@ -63,6 +63,12 @@ class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject virtual void setFont( const TQFont& ); void allowSemiColonAsSeparator( bool ); + /// Sets if distribution lists will be used for completion. + /// This is true by default. + /// Call this right after the constructor, before anything calls loadContacts(), + /// otherwise this has no effect. + void allowDistributionLists( bool allowDistLists ); + public slots: void cursorAtEnd(); void enableCompletion( bool enable ); @@ -96,8 +102,10 @@ class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject * Adds the name of a completion source to the internal list of * such sources and returns its index, such that that can be used * for insertion of items associated with that source. + * + * If the source already exists, the weight will be updated. */ - int addCompletionSource( const TQString& ); + int addCompletionSource( const TQString&, int weight ); /** return whether we are using sorted or weighted display */ static KCompletion::CompOrder completionOrder(); @@ -120,6 +128,7 @@ class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject void init(); void startLoadingLDAPEntries(); void stopLDAPLookup(); + void updateLDAPWeights(); void setCompletedItems( const TQStringList& items, bool autoSuggest ); void addCompletionItem( const TQString& string, int weight, int source, const TQStringList * keyWords=0 ); @@ -136,6 +145,7 @@ class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject bool m_lastSearchMode; bool m_searchExtended; //has \" been added? bool m_useSemiColonAsSeparator; + bool m_allowDistLists; //TQMap m_contactMap; @@ -147,6 +157,7 @@ class KDE_EXPORT AddresseeLineEdit : public ClickLineEdit, public DCOPObject static TQString *s_LDAPText; static AddresseeLineEdit *s_LDAPLineEdit; static TQStringList *s_completionSources; + static TQMap *s_ldapClientToCompletionSourceMap; class AddresseeLineEditPrivate; AddresseeLineEditPrivate *d; diff --git a/libkdepim/addressesdialog.cpp b/libkdepim/addressesdialog.cpp index 8a33d7999..14feafb67 100644 --- a/libkdepim/addressesdialog.cpp +++ b/libkdepim/addressesdialog.cpp @@ -67,7 +67,7 @@ struct AddresseeViewItem::AddresseeViewItemPrivate { }; struct AddressesDialog::AddressesDialogPrivate { - AddressesDialogPrivate() : + AddressesDialogPrivate() : ui(0), personal(0), recent(0), toItem(0), ccItem(0), bccItem(0), ldapSearchDialog(0) @@ -77,6 +77,8 @@ struct AddressesDialog::AddressesDialogPrivate { AddresseeViewItem *personal; AddresseeViewItem *recent; + AddresseeViewItem *topdist; + TQPtrList dists; AddresseeViewItem *toItem; AddresseeViewItem *ccItem; @@ -181,11 +183,11 @@ void AddresseeViewItem::setSelected(bool selected) { if (selected == isSelected()) { - return; + return; } - emit addressSelected( this, selected ); - TQListViewItem::setSelected(selected); + emit addressSelected( this, selected ); + TQListViewItem::setSelected(selected); } int @@ -223,6 +225,9 @@ AddressesDialog::AddressesDialog( TQWidget *widget, const char *name ) initConnections(); d->ui->mAvailableView->setFocus(); + + setMainWidget( page ); + page->setMinimumSize( 750, 400 ); } AddressesDialog::~AddressesDialog() @@ -331,6 +336,7 @@ AddressesDialog::updateRecentAddresses() addAddresseeToAvailable( *it, d->recent ); if ( d->recent->childCount() > 0 ) { + d->recent->setOpen( true ); d->recent->setVisible( true ); } } @@ -472,8 +478,10 @@ AddressesDialog::updateAvailableAddressees() d->recent = 0; updateRecentAddresses(); + d->topdist = 0; addDistributionLists(); if ( d->personal->childCount() > 0 ) { + d->personal->setOpen( true ); d->personal->setVisible( true ); } @@ -724,10 +732,9 @@ AddressesDialog::addSelectedTo() addAddresseesToSelected( d->toItem, selectedAvailableAddresses ); selectedAvailableAddresses.clear(); - if ( d->toItem->childCount() > 0 ) + if ( d->toItem->childCount() > 0 ) { d->toItem->setVisible( true ); - else - { + } else { delete d->toItem; d->toItem = 0; } @@ -746,10 +753,9 @@ AddressesDialog::addSelectedCC() addAddresseesToSelected( d->ccItem, selectedAvailableAddresses ); selectedAvailableAddresses.clear(); - if ( d->ccItem->childCount() > 0 ) + if ( d->ccItem->childCount() > 0 ) { d->ccItem->setVisible( true ); - else - { + } else { delete d->ccItem; d->ccItem = 0; } @@ -768,10 +774,9 @@ AddressesDialog::addSelectedBCC() addAddresseesToSelected( d->bccItem, selectedAvailableAddresses ); selectedAvailableAddresses.clear(); - if ( d->bccItem->childCount() > 0 ) + if ( d->bccItem->childCount() > 0 ) { d->bccItem->setVisible( true ); - else - { + } else { delete d->bccItem; d->bccItem = 0; } @@ -950,7 +955,7 @@ AddressesDialog::searchLdap() void AddressesDialog::ldapSearchResult() { - TQStringList emails = TQStringList::split(',', d->ldapSearchDialog->selectedEMails() ); + TQStringList emails = KPIM::splitEmailAddrList( d->ldapSearchDialog->selectedEMails() ); TQStringList::iterator it( emails.begin() ); TQStringList::iterator end( emails.end() ); for ( ; it != end; ++it ){ @@ -979,22 +984,81 @@ AddressesDialog::filterChanged( const TQString& txt ) if ( txt.isEmpty() ) showAll = true; + int personalVisible = 0; + int recentVisible = 0; while ( it.current() ) { AddresseeViewItem* item = static_cast( it.current() ); ++it; + if ( showAll ) { + item->setOpen( true ); item->setVisible( true ); - if ( item->category() == AddresseeViewItem::Group ) - item->setOpen( false );//close to not have too many entries + // allen: I do not like the following behavior. comment out and see if anyone screams + //if ( item->category() == AddresseeViewItem::Group ) + // item->setOpen( false );//close to not have too many entries continue; } + if ( item->category() == AddresseeViewItem::Entry ) { - bool matches = item->matches( txt ) ; + bool matches = item->matches( txt ); item->setVisible( matches ); - if ( matches && static_cast(item)->parent() ) { - static_cast(item)->parent()->setOpen( true );//open the parents with found entries + TQListViewItem *parent = static_cast( item )->parent(); + if ( matches && parent ) { + if ( parent == d->personal ) { + personalVisible++; + } else if ( parent == d->recent ) { + recentVisible++; + } } } + if ( item->category() == AddresseeViewItem::Group ) { + item->setOpen( true ); + item->setVisible( true ); + } + } + + if ( !showAll && personalVisible == 0 ) { + d->personal->setOpen( false ); + d->personal->setVisible( false ); + } + if ( !showAll && recentVisible == 0 ) { + d->recent->setOpen( false ); + d->recent->setVisible( false ); + } + + int distlistgroupVisible = 0; + if ( !showAll ) { + TQPtrListIterator it( d->dists ); + for ( ; it.current(); ++it ) { + TQListViewItem *p = *it; + p->setVisible( true ); + AddresseeViewItem *p2 = static_cast( p->firstChild() ); + int pcount = 0; + while ( p2 ) { + if ( p2->matches( txt ) ) { + p2->setVisible( true ); + pcount++; + } else { + p2->setVisible( false ); + } + p2 = static_cast( p2->nextSibling() ); + } + if ( !pcount && !p->text( 0 ).contains( txt, false ) ) { + p->setVisible( false ); + } + distlistgroupVisible += pcount; + if ( p->text( 0 ).contains( txt, false ) ) { + distlistgroupVisible++; + } + } + } + if ( d->topdist ) { + if ( showAll || distlistgroupVisible > 0 ) { + d->topdist->setOpen( true ); + } else { + d->topdist->setOpen( false ); + d->topdist->setVisible( false ); + } } } @@ -1084,14 +1148,16 @@ AddressesDialog::addDistributionLists() if ( distLists.isEmpty() ) return; - AddresseeViewItem *topItem = new AddresseeViewItem( d->ui->mAvailableView, - i18n( "Distribution Lists" ) ); + if ( !d->topdist ) { + d->topdist = new AddresseeViewItem( d->ui->mAvailableView, i18n( "Distribution Lists" ) ); + } #ifdef KDEPIM_NEW_DISTRLISTS TQValueList::ConstIterator listIt; #else TQStringList::Iterator listIt; #endif + int total = 0; for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) { #ifdef KDEPIM_NEW_DISTRLISTS KPIM::DistributionList dlist = *listIt; @@ -1101,7 +1167,8 @@ AddressesDialog::addDistributionLists() KABC::DistributionList::Entry::List entries = dlist.entries(); #endif - AddresseeViewItem *item = new AddresseeViewItem( topItem, dlist.name() ); + AddresseeViewItem *item = new AddresseeViewItem( d->topdist, dlist.name() ); + d->dists.append( item ); connect( item, TQT_SIGNAL( addressSelected( AddresseeViewItem*, bool ) ), this, TQT_SLOT( availableAddressSelected( AddresseeViewItem*, bool ) ) ); @@ -1110,8 +1177,18 @@ AddressesDialog::addDistributionLists() #else KABC::DistributionList::Entry::List::Iterator itemIt; #endif - for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt ) + for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt ) { addAddresseeToAvailable( (*itemIt).addressee, item, false ); + } + if ( item->childCount() > 0 ) { + item->setOpen( true ); + item->setVisible( true ); + } + total += item->childCount(); + } + if ( total > 0 ) { + d->topdist->setOpen( true ); + d->topdist->setVisible( true ); } } diff --git a/libkdepim/calendardiffalgo.h b/libkdepim/calendardiffalgo.h index 43d855134..47e5efd4c 100644 --- a/libkdepim/calendardiffalgo.h +++ b/libkdepim/calendardiffalgo.h @@ -22,9 +22,10 @@ #ifndef KPIM_CALENDARDIFFALGO_H #define KPIM_CALENDARDIFFALGO_H +#include "diffalgo.h" + #include #include -#include namespace KPIM { diff --git a/libkdepim/completionordereditor.cpp b/libkdepim/completionordereditor.cpp index b507d9b97..9fd4950aa 100644 --- a/libkdepim/completionordereditor.cpp +++ b/libkdepim/completionordereditor.cpp @@ -27,6 +27,7 @@ * you do not wish to do so, delete this exception statement from * your version. */ +#include // FOR KDEPIM_NEW_DISTRLISTS #include "completionordereditor.h" #include "ldapclient.h" @@ -54,11 +55,11 @@ Several items are used in addresseelineedit's completion object: LDAP servers, KABC resources (imap and non-imap), Recent addresses (in kmail only). The default completion weights are as follow: + Recent addresses (kmail) : 10 (see kmail/kmlineeditspell.cpp) LDAP: 50, 49, 48 etc. (see ldapclient.cpp) KABC non-imap resources: 60 (see addresseelineedit.cpp and SimpleCompletionItem here) Distribution lists: 60 (see addresseelineedit.cpp and SimpleCompletionItem here) KABC imap resources: 80 (see kresources/imap/kabc/resourceimap.cpp) - Recent addresses (kmail) : 120 (see kmail/kmcomposewin.cpp) This dialog allows to change those weights, by showing one item per: - LDAP server @@ -99,21 +100,21 @@ private: void LDAPCompletionItem::save( CompletionOrderEditor* ) { - KConfig config( "kabldaprc" ); - config.setGroup( "LDAP" ); - config.writeEntry( TQString( "SelectedCompletionWeight%1" ).arg( mLdapClient->clientNumber() ), - mWeight ); - config.sync(); + KConfig * config = LdapSearch::config(); + config->setGroup( "LDAP" ); + config->writeEntry( TQString( "SelectedCompletionWeight%1" ).arg( mLdapClient->clientNumber() ), + mWeight ); + config->sync(); } // A simple item saved into kpimcompletionorder (no subresources, just name/identifier/weight) class SimpleCompletionItem : public CompletionItem { public: - SimpleCompletionItem( CompletionOrderEditor* editor, const TQString& label, const TQString& identifier ) + SimpleCompletionItem( CompletionOrderEditor* editor, const TQString& label, const TQString& identifier, int weight ) : mLabel( label ), mIdentifier( identifier ) { KConfigGroup group( editor->configFile(), "CompletionWeights" ); - mWeight = group.readNumEntry( mIdentifier, 60 ); + mWeight = group.readNumEntry( mIdentifier, weight ); } virtual TQString label() const { return mLabel; } virtual int completionWeight() const { return mWeight; } @@ -195,15 +196,17 @@ CompletionOrderEditor::CompletionOrderEditor( KPIM::LdapSearch* ldapSearch, } } else { // non-IMAP KABC resource mItems.append( new SimpleCompletionItem( this, (*resit)->resourceName(), - (*resit)->identifier() ) ); + (*resit)->identifier(), 60 ) ); } } #ifndef KDEPIM_NEW_DISTRLISTS // new distr lists are normal contact, so no separate item if using them // Add an item for distribution lists - mItems.append( new SimpleCompletionItem( this, i18n( "Distribution Lists" ), "DistributionLists" ) ); + mItems.append( new SimpleCompletionItem( this, i18n( "Distribution Lists" ), "DistributionLists" ), 60 ); #endif + mItems.append( new SimpleCompletionItem( this, i18n( "Recent Addresses" ), "Recent Addresses", 10 ) ); + // Now sort the items, then create the GUI mItems.sort(); diff --git a/libkdepim/csshelper.cpp b/libkdepim/csshelper.cpp index b65713dd2..6b37fbf13 100644 --- a/libkdepim/csshelper.cpp +++ b/libkdepim/csshelper.cpp @@ -238,6 +238,7 @@ namespace KPIM { TQString::number( printFont.pointSize() ) ) + TQString( "tr.textAtmH,\n" + "tr.signInProgressH,\n" "tr.rfc822H,\n" "tr.encrH,\n" "tr.signOkKeyOkH,\n" @@ -367,6 +368,10 @@ namespace KPIM { " color: white ! important;\n" "}\n\n" + "a.black {\n" + " color: black ! important;\n" + "}\n\n" + "table.textAtm { background-color: %2 ! important; }\n\n" "tr.textAtmH {\n" @@ -378,10 +383,12 @@ namespace KPIM { " background-color: %3 ! important;\n" "}\n\n" + "table.signInProgress,\n" "table.rfc822 {\n" " background-color: %3 ! important;\n" "}\n\n" + "tr.signInProgressH,\n" "tr.rfc822H {\n" "%4" "}\n\n" ) @@ -538,6 +545,7 @@ namespace KPIM { " font-weight: normal ! important;\n" "}\n\n" + "tr.signInProgressH,\n" "tr.rfc822H,\n" "tr.encrH,\n" "tr.signOkKeyOkH,\n" @@ -565,6 +573,7 @@ namespace KPIM { "table.signErr,\n" "table.signOkKeyBad,\n" "table.signOkKeyOk,\n" + "table.signInProgress,\n" "div.fancy.header table {\n" " width: 100% ! important;\n" " border-width: 0px ! important;\n" @@ -630,4 +639,9 @@ namespace KPIM { mPrintFont = font; } + TQColor CSSHelper::pgpWarnColor() const + { + return cPgpWarnH; + } + } // namespace KPIM diff --git a/libkdepim/csshelper.h b/libkdepim/csshelper.h index 5d668713c..3dbc80c03 100644 --- a/libkdepim/csshelper.h +++ b/libkdepim/csshelper.h @@ -67,6 +67,8 @@ class CSSHelper { void setBodyFont( const TQFont& font ); void setPrintFont( const TQFont& font ); + TQColor pgpWarnColor() const; + protected: /** Recalculate PGP frame and body colors (should be called after changing color settings) */ diff --git a/libkdepim/distributionlist.cpp b/libkdepim/distributionlist.cpp index e70b77b57..2ccdeb525 100644 --- a/libkdepim/distributionlist.cpp +++ b/libkdepim/distributionlist.cpp @@ -37,15 +37,13 @@ static ParseList parseCustom( const TQString& str ) if ( (*it).isEmpty() ) continue; // parse "uid,email" - TQStringList helpList = TQStringList::split( ',', (*it) ); + TQStringList helpList = TQStringList::split( ',', (*it), true ); Q_ASSERT( !helpList.isEmpty() ); if ( helpList.isEmpty() ) continue; - const TQString uid = helpList.first(); - TQString email; Q_ASSERT( helpList.count() < 3 ); // 1 or 2 items, but not more - if ( helpList.count() == 2 ) - email = helpList.last(); + const TQString uid = helpList.first(); + const TQString email = helpList.last(); res.append( qMakePair( uid, email ) ); } return res; diff --git a/libkdepim/htmldiffalgodisplay.h b/libkdepim/htmldiffalgodisplay.h index 23da21f4c..4495e2003 100644 --- a/libkdepim/htmldiffalgodisplay.h +++ b/libkdepim/htmldiffalgodisplay.h @@ -22,8 +22,9 @@ #ifndef KPIM_HTMLDIFFALGODISPLAY_H #define KPIM_HTMLDIFFALGODISPLAY_H +#include "diffalgo.h" + #include -#include #include namespace KPIM { diff --git a/libkdepim/kabcresourcecached.cpp b/libkdepim/kabcresourcecached.cpp index 26648e762..d46156f6d 100644 --- a/libkdepim/kabcresourcecached.cpp +++ b/libkdepim/kabcresourcecached.cpp @@ -214,7 +214,11 @@ void ResourceCached::loadCache() KABC::VCardConverter converter; +#if defined(KABC_VCARD_ENCODING_FIX) + KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); +#else KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); +#endif KABC::Addressee::List::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { @@ -239,8 +243,13 @@ void ResourceCached::saveCache() KABC::Addressee::List list = mAddrMap.values(); KABC::VCardConverter converter; +#if defined(KABC_VCARD_ENCODING_FIX) + TQCString vCard = converter.createVCardsRaw( list ); + file.writeBlock( vCard, vCard.length() ); +#else TQString vCard = converter.createVCards( list ); file.writeBlock( vCard.utf8(), vCard.utf8().length() ); +#endif file.close(); } @@ -259,7 +268,11 @@ void ResourceCached::cleanUpCache( const KABC::Addressee::List &addrList ) KABC::VCardConverter converter; +#if defined(KABC_VCARD_ENCODING_FIX) + KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); +#else KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); +#endif KABC::Addressee::List::Iterator cacheIt; KABC::Addressee::List::ConstIterator it; @@ -351,9 +364,14 @@ void ResourceCached::saveChangesCache( const TQMap &m } KABC::VCardConverter converter; +#if defined(KABC_VCARD_ENCODING_FIX) + const TQCString vCards = converter.createVCardsRaw( list ); + file.writeBlock( vCards, vCards.length() ); +#else const TQString vCards = converter.createVCards( list ); TQCString content = vCards.utf8(); file.writeBlock( content, content.length() ); +#endif } } @@ -372,7 +390,11 @@ void ResourceCached::loadChangesCache( TQMap &map, co KABC::VCardConverter converter; +#if defined(KABC_VCARD_ENCODING_FIX) + const KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); +#else const KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); +#endif KABC::Addressee::List::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) map.insert( (*it).uid(), *it ); diff --git a/libkdepim/kaddrbook.cpp b/libkdepim/kaddrbook.cpp index ade6ef706..e5ef47e6f 100644 --- a/libkdepim/kaddrbook.cpp +++ b/libkdepim/kaddrbook.cpp @@ -207,34 +207,9 @@ bool KAddrBookExternal::addVCard( const KABC::Addressee& addressee, TQWidget *pa bool KAddrBookExternal::addAddressee( const KABC::Addressee& addr ) { KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true ); - -#if KDE_IS_VERSION(3,4,89) - // This ugly hack will be removed in 4.0 - while ( !addressBook->loadingHasFinished() ) { - TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput ); - - // use sleep here to reduce cpu usage - usleep( 100 ); - } -#endif - - // Select a resource - TQPtrList kabcResources = addressBook->resources(); - - TQPtrList kresResources; - TQPtrListIterator resIt( kabcResources ); - KABC::Resource *kabcResource; - while ( ( kabcResource = resIt.current() ) != 0 ) { - ++resIt; - if ( !kabcResource->readOnly() ) { - KRES::Resource *res = static_cast( kabcResource ); - if ( res ) - kresResources.append( res ); - } - } - - kabcResource = static_cast( KRES::SelectDialog::getResource( kresResources, 0 ) ); - + KABC::Resource *kabcResource = selectResourceForSaving( addressBook ); + if( !kabcResource ) + return false; KABC::Ticket *ticket = addressBook->requestSaveTicket( kabcResource ); bool saved = false; if ( ticket ) { @@ -278,3 +253,33 @@ TQString KAddrBookExternal::expandDistributionList( const TQString& listName ) #endif return TQString::null; } + +KABC::Resource* KAddrBookExternal::selectResourceForSaving( KABC::AddressBook *addressBook ) +{ +#if KDE_IS_VERSION(3,4,89) + // This ugly hack will be removed in 4.0 + while ( !addressBook->loadingHasFinished() ) { + TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput ); + + // use sleep here to reduce cpu usage + usleep( 100 ); + } +#endif + + // Select a resource + TQPtrList kabcResources = addressBook->resources(); + + TQPtrList kresResources; + TQPtrListIterator resIt( kabcResources ); + KABC::Resource *kabcResource; + while ( ( kabcResource = resIt.current() ) != 0 ) { + ++resIt; + if ( !kabcResource->readOnly() ) { + KRES::Resource *res = static_cast( kabcResource ); + if ( res ) + kresResources.append( res ); + } + } + + return static_cast( KRES::SelectDialog::getResource( kresResources, 0 ) ); +} diff --git a/libkdepim/kaddrbook.h b/libkdepim/kaddrbook.h index dfa65823f..374753e54 100644 --- a/libkdepim/kaddrbook.h +++ b/libkdepim/kaddrbook.h @@ -11,6 +11,10 @@ #include #include +namespace KABC { + class AddressBook; +} + class TQWidget; class KDE_EXPORT KAddrBookExternal { @@ -23,6 +27,17 @@ public: static bool addVCard( const KABC::Addressee& addressee, TQWidget *parent ); static TQString expandDistributionList( const TQString& listName ); + + /** + * Pops up a dialog to ask the user to select a resource for saving something, and + * returns the selected resource or 0 on failure or if the user cancelled. + * + * The addressbook used to get the resource list from. If the addressbook was loaded + * async and loading is not yet finished, this method will run an eventloop until the + * addressbook is loaded. + */ + static KABC::Resource* selectResourceForSaving( KABC::AddressBook *addressBook ); + private: static bool addAddressee( const KABC::Addressee& addressee ); }; diff --git a/libkdepim/kcmdesignerfields.cpp b/libkdepim/kcmdesignerfields.cpp index 79a570ae5..330d8b84b 100644 --- a/libkdepim/kcmdesignerfields.cpp +++ b/libkdepim/kcmdesignerfields.cpp @@ -163,6 +163,7 @@ void KCMDesignerFields::delayedInit() // Install a dirwatcher that will detect newly created or removed designer files KDirWatch *dw = new KDirWatch( this ); + KStandardDirs::makeDir(localUiDir()); dw->addDir( localUiDir(), true ); connect( dw, TQT_SIGNAL( created(const TQString&) ), TQT_SLOT( rebuildList() ) ); connect( dw, TQT_SIGNAL( deleted(const TQString&) ), TQT_SLOT( rebuildList() ) ); diff --git a/libkdepim/kdepimprotocols.h b/libkdepim/kdepimprotocols.h new file mode 100644 index 000000000..462fafda8 --- /dev/null +++ b/libkdepim/kdepimprotocols.h @@ -0,0 +1,32 @@ +/* + This file is part of libkdepim. + + Copyright (c) 2005 Rafal Rzepecki + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KDEPIM_KDEPIMPROTOCOLS_H +#define KDEPIM_KDEPIMPROTOCOLS_H + +/* a central place to store protocol strings to avoid knowledge duplication */ + +#define KDEPIMPROTOCOL_CONTACT "uid:" +#define KDEPIMPROTOCOL_EMAIL "kmail:" +#define KDEPIMPROTOCOL_INCIDENCE "urn:x-ical" +#define KDEPIMPROTOCOL_NEWSARTICLE "news:" + +#endif diff --git a/libkdepim/kfoldertree.h b/libkdepim/kfoldertree.h index e09cd7833..2d2805846 100644 --- a/libkdepim/kfoldertree.h +++ b/libkdepim/kfoldertree.h @@ -39,6 +39,7 @@ struct KPaintInfo { { COL_SIZE, COL_ATTACHMENT, + COL_INVITATION, COL_IMPORTANT, COL_TODO, COL_SPAM_HAM, @@ -55,8 +56,9 @@ struct KPaintInfo { showSize(false), showAttachment(false), + showInvitation(false), showImportant(false), - showTodo( false ), + showTodo(false), showSpamHam(false), showWatchedIgnored(false), showStatus(false), @@ -73,6 +75,7 @@ struct KPaintInfo { dateCol(-1), sizeCol(-1), attachmentCol(-1), + invitationCol(-1), importantCol(-1), todoCol(-1), spamHamCol(-1), @@ -84,7 +87,8 @@ struct KPaintInfo { orderOfArrival(false), status(false), showCryptoIcons(false), - showAttachmentIcon(false) + showAttachmentIcon(false), + showInvitationIcon(false) {} bool pixmapOn; @@ -99,6 +103,7 @@ struct KPaintInfo { bool showSize; bool showAttachment; + bool showInvitation; bool showImportant; bool showTodo; bool showSpamHam; @@ -117,6 +122,7 @@ struct KPaintInfo { int dateCol; int sizeCol; int attachmentCol; + int invitationCol; int importantCol; int todoCol; int spamHamCol; @@ -129,6 +135,7 @@ struct KPaintInfo { bool status; bool showCryptoIcons; bool showAttachmentIcon; + bool showInvitationIcon; }; //========================================================================== diff --git a/libkdepim/kincidencechooser.cpp b/libkdepim/kincidencechooser.cpp index 53f72c886..2cef98f3a 100644 --- a/libkdepim/kincidencechooser.cpp +++ b/libkdepim/kincidencechooser.cpp @@ -77,9 +77,9 @@ KIncidenceChooser::KIncidenceChooser(TQWidget *parent, char *name) : topLayout->addWidget( new TQLabel ( i18n("Last modified:"), topFrame) ,iii,0); mMod1lab = new TQLabel ( "Set Last modified", topFrame); topLayout->addWidget(mMod1lab,iii,1); - showDetails1 = new TQPushButton( i18n("Show Details"),topFrame ); - connect ( showDetails1, TQT_SIGNAL( clicked()), this, TQT_SLOT (showIncidence1() ) ); - topLayout->addWidget(showDetails1,iii,2); + mShowDetails1 = new TQPushButton( i18n("Show Details"),topFrame ); + connect ( mShowDetails1, TQT_SIGNAL( clicked()), this, TQT_SLOT (showIncidence1() ) ); + topLayout->addWidget(mShowDetails1,iii,2); ++iii; mInc2lab = new TQLabel ( "Local incidence", topFrame); @@ -90,19 +90,19 @@ KIncidenceChooser::KIncidenceChooser(TQWidget *parent, char *name) : topLayout->addWidget( new TQLabel ( i18n("Last modified:"), topFrame) ,iii,0); mMod2lab = new TQLabel ( "Set Last modified", topFrame); topLayout->addWidget(mMod2lab,iii,1); - showDetails2 = new TQPushButton( i18n("Show Details"), topFrame); - connect ( showDetails2, TQT_SIGNAL( clicked()), this, TQT_SLOT (showIncidence2() ) ); - topLayout->addWidget(showDetails2,iii,2); + mShowDetails2 = new TQPushButton( i18n("Show Details"), topFrame); + connect ( mShowDetails2, TQT_SIGNAL( clicked()), this, TQT_SLOT (showIncidence2() ) ); + topLayout->addWidget(mShowDetails2,iii,2); ++iii; // #if 0 // commented out for now, because the diff code has too many bugs - diffBut = new TQPushButton( i18n("Show Differences"), topFrame ); - connect ( diffBut, TQT_SIGNAL( clicked()), this, TQT_SLOT ( showDiff() ) ); - topLayout->addMultiCellWidget(diffBut, iii,iii,0,2); + mDiffBut = new TQPushButton( i18n("Show Differences"), topFrame ); + connect ( mDiffBut, TQT_SIGNAL( clicked()), this, TQT_SLOT ( showDiff() ) ); + topLayout->addMultiCellWidget(mDiffBut, iii,iii,0,2); ++iii; #else - diffBut = 0; + mDiffBut = 0; #endif mBg = new TQButtonGroup ( 1, Qt::Horizontal, i18n("Sync Preferences"), topFrame); topLayout->addMultiCellWidget(mBg, iii,iii,0,2); @@ -116,7 +116,7 @@ KIncidenceChooser::KIncidenceChooser(TQWidget *parent, char *name) : mTbL = 0; mTbN = 0; mDisplayDiff = 0; - choosedIncidence = 0; + mSelIncidence = 0; button = new TQPushButton( i18n("Apply This to All Conflicts of This Sync"), topFrame ); connect ( button, TQT_SIGNAL( clicked()), this, TQT_SLOT ( setSyncMode() ) ); topLayout->addMultiCellWidget(button, iii,iii,0,2); @@ -142,7 +142,7 @@ void KIncidenceChooser::setIncidence( KCal::Incidence* local ,KCal::Incidence* r KCal::Incidence* KIncidenceChooser::getIncidence( ) { - KCal::Incidence* retval = choosedIncidence; + KCal::Incidence* retval = mSelIncidence; if ( chooseMode == KIncidenceChooser::local ) retval = mInc1; else if ( chooseMode == KIncidenceChooser::remote ) @@ -185,21 +185,21 @@ void KIncidenceChooser::setLabels() if ( inc->type() == "Event" ) { des->setText( i18n( "Local Event") ); sum->setText( inc->summary().left( 30 )); - if ( diffBut ) - diffBut->setEnabled( true ); + if ( mDiffBut ) + mDiffBut->setEnabled( true ); } else if ( inc->type() == "Todo" ) { des->setText( i18n( "Local Todo") ); sum->setText( inc->summary().left( 30 )); - if ( diffBut ) - diffBut->setEnabled( true ); + if ( mDiffBut ) + mDiffBut->setEnabled( true ); } else if ( inc->type() == "Journal" ) { des->setText( i18n( "Local Journal") ); sum->setText( inc->description().left( 30 )); - if ( diffBut ) - diffBut->setEnabled( false ); + if ( mDiffBut ) + mDiffBut->setEnabled( false ); } mMod1lab->setText( KGlobal::locale()->formatDateTime(inc->lastModified() )); inc = mInc2; @@ -226,10 +226,10 @@ void KIncidenceChooser::showIncidence1() { if ( mTbL ) { if ( mTbL->isVisible() ) { - showDetails1->setText( i18n("Show Details")); + mShowDetails1->setText( i18n("Show Details")); mTbL->hide(); } else { - showDetails1->setText( i18n("Hide Details")); + mShowDetails1->setText( i18n("Hide Details")); mTbL->show(); mTbL->raise(); } @@ -242,7 +242,7 @@ void KIncidenceChooser::showIncidence1() mTbL->setMainWidget( textBrowser ); textBrowser->setText( KCal::IncidenceFormatter::extensiveDisplayString( mInc1 ) ); mTbL->setMinimumSize( 400, 400 ); - showDetails1->setText( i18n("Hide Details")); + mShowDetails1->setText( i18n("Hide Details")); mTbL->show(); mTbL->raise(); } @@ -251,9 +251,9 @@ void KIncidenceChooser::detailsDialogClosed() { KDialogBase* dialog = static_cast( const_cast( sender() ) ); if ( dialog == mTbL ) - showDetails1->setText( i18n( "Show details..." ) ); + mShowDetails1->setText( i18n( "Show details..." ) ); else - showDetails2->setText( i18n( "Show details..." ) ); + mShowDetails2->setText( i18n( "Show details..." ) ); } void KIncidenceChooser::showDiff() @@ -282,10 +282,10 @@ void KIncidenceChooser::showIncidence2() { if ( mTbN ) { if ( mTbN->isVisible() ) { - showDetails2->setText( i18n("Show Details")); + mShowDetails2->setText( i18n("Show Details")); mTbN->hide(); } else { - showDetails2->setText( i18n("Hide Details")); + mShowDetails2->setText( i18n("Hide Details")); mTbN->show(); mTbN->raise(); } @@ -298,27 +298,27 @@ void KIncidenceChooser::showIncidence2() mTbN->setMainWidget( textBrowser ); textBrowser->setText( KCal::IncidenceFormatter::extensiveDisplayString( mInc2 ) ); mTbN->setMinimumSize( 400, 400 ); - showDetails2->setText( i18n("Hide Details")); + mShowDetails2->setText( i18n("Hide Details")); mTbN->show(); mTbN->raise(); } void KIncidenceChooser::takeIncidence1() { - choosedIncidence = mInc1; + mSelIncidence = mInc1; TQDialog::accept(); } void KIncidenceChooser::takeIncidence2() { - choosedIncidence = mInc2; + mSelIncidence = mInc2; TQDialog::accept(); } void KIncidenceChooser::takeBoth() { - choosedIncidence = 0; + mSelIncidence = 0; TQDialog::accept(); } diff --git a/libkdepim/kincidencechooser.h b/libkdepim/kincidencechooser.h index 8c569e33e..9d9e016ad 100644 --- a/libkdepim/kincidencechooser.h +++ b/libkdepim/kincidencechooser.h @@ -24,44 +24,40 @@ #ifndef _KINCIDENCECHOOSER_H #define _KINCIDENCECHOOSER_H +#include "calendardiffalgo.h" +#include "htmldiffalgodisplay.h" #include -#include -#include -#include - -#include -#include "htmldiffalgodisplay.h" -#include "calendardiffalgo.h" +namespace KCal { + class Incidence; +} +using namespace KCal; -class TQRadioButton; class TQButtonGroup; -class TQVBox; -class TQStringList; -class TQTextBrowser; -class KDialogBase; /** Dialog to change the korganizer configuration. */ class KDE_EXPORT KIncidenceChooser : public KDialog { - Q_OBJECT -public: - enum mode { local, remote, newest, ask, both }; + Q_OBJECT + public: + enum mode { + local, remote, newest, ask, both + }; /** Initialize dialog and pages */ - KIncidenceChooser(TQWidget *parent=0,char *name=0); + KIncidenceChooser( TQWidget *parent=0, char *name=0 ); ~KIncidenceChooser(); //void setChooseText( TQString ); - void setIncidence( KCal::Incidence*,KCal::Incidence*); - KCal::Incidence* getIncidence(); + void setIncidence( KCal::Incidence *, KCal::Incidence * ); + KCal::Incidence *getIncidence(); static int chooseMode; -public slots: + public slots: void useGlobalMode(); -protected slots: + protected slots: void showIncidence1(); void showIncidence2(); void showDiff(); @@ -72,16 +68,15 @@ protected slots: void setSyncMode(); void detailsDialogClosed(); -protected: -private: - KPIM::HTMLDiffAlgoDisplay* mDisplayDiff; - KPIM::CalendarDiffAlgo* diff; - KDialogBase* mTbL, *mTbN; - KCal::Incidence* choosedIncidence; - KCal::Incidence* mInc1, *mInc2; + private: + KPIM::HTMLDiffAlgoDisplay *mDisplayDiff; + KPIM::CalendarDiffAlgo *diff; + KDialogBase *mTbL, *mTbN; + KCal::Incidence *mSelIncidence; + KCal::Incidence *mInc1, *mInc2; TQButtonGroup *mBg; - TQPushButton *diffBut,*showDetails1,*showDetails2; - TQLabel* mInc1lab, *mInc2lab,* mInc1Sumlab, *mInc2Sumlab,*mMod1lab,*mMod2lab; + TQPushButton *mDiffBut,*mShowDetails1,*mShowDetails2; + TQLabel *mInc1lab, *mInc2lab,* mInc1Sumlab, *mInc2Sumlab,*mMod1lab,*mMod2lab; }; diff --git a/libkdepim/komposer/core/komposerconfig.desktop b/libkdepim/komposer/core/komposerconfig.desktop index 9076759d5..58c8bd765 100644 --- a/libkdepim/komposer/core/komposerconfig.desktop +++ b/libkdepim/komposer/core/komposerconfig.desktop @@ -27,7 +27,6 @@ Comment[de]=KDE-Komposer Comment[fr]=Komposer KDE Comment[ga]=Komposer KDE Comment[hi]=केडीई कम्पोज़र -Comment[ka]=KDE კომპოზიტორი Comment[ms]=Penggubah KDE Comment[nds]=Nettbreef-Editor vun KDE Comment[ne]=केडीई कम्पोजर @@ -46,7 +45,6 @@ Keywords[da]=brevskriver Keywords[de]=Komposer Keywords[fy]=komposer,opstellen, opsteller Keywords[hi]=कम्पोज़र -Keywords[ka]=komposer,ნოტები Keywords[nds]=Komposer Keywords[ne]=कम्पोजर Keywords[nl]=komposer,opstellen diff --git a/libkdepim/komposer/core/komposereditor.desktop b/libkdepim/komposer/core/komposereditor.desktop index 2e84bd17c..fd1c1341e 100644 --- a/libkdepim/komposer/core/komposereditor.desktop +++ b/libkdepim/komposer/core/komposereditor.desktop @@ -26,7 +26,6 @@ Comment[hu]=Komposer Comment[is]=Komposer ritill Comment[it]=Komposer editor Comment[ja]=Komposer,エディタ -Comment[ka]=Komposer-ის რედაქტორი Comment[kk]=Komposer өңдегіші Comment[km]=កម្មវិធី​និពន្ធ Komposer Comment[ko]=Komposer 편집기 diff --git a/libkdepim/komposer/core/komposerplugin.desktop b/libkdepim/komposer/core/komposerplugin.desktop index 08b450d6d..b398e1c67 100644 --- a/libkdepim/komposer/core/komposerplugin.desktop +++ b/libkdepim/komposer/core/komposerplugin.desktop @@ -29,7 +29,6 @@ Name[hu]=Komposer bővítőmodul Name[is]=Komposer íforrit Name[it]=Plugin Komposer Name[ja]=Komposer プラグイン -Name[ka]=Komposer მოდული Name[kk]=Komposer плагин модулі Name[km]=កម្មវិធី​ជំនួយ Komposer Name[ko]=Komposer 플러그인 diff --git a/libkdepim/komposer/plugins/default/defaulteditor.desktop b/libkdepim/komposer/plugins/default/defaulteditor.desktop index b0fd5a651..910f7d89c 100644 --- a/libkdepim/komposer/plugins/default/defaulteditor.desktop +++ b/libkdepim/komposer/plugins/default/defaulteditor.desktop @@ -38,7 +38,6 @@ Name[hu]=Komposer szerkesztő Name[is]=Komposer ritill Name[it]=Editor Komposer Name[ja]=Komposer エディタ -Name[ka]=Komposer რედაქტორი Name[kk]=Komposer өңдегіші Name[km]=កម្មវិធី​និពន្ធ Komposer Name[lt]=Komposer redaktorius @@ -84,7 +83,6 @@ Comment[hu]=A Komposer alapértelmezett szerkesztője Comment[is]=Sjálfgefinn ritill Komposer Comment[it]=Editor di default per Komposer Comment[ja]=Komposer 標準エディタ -Comment[ka]=Komposer ნაგულისხმევი რედაქტორი Comment[kk]=Komposer әдетті өңдегіші Comment[km]=កម្មវិធី​និពន្ធ​លំនាំដើម​របស់ Komposer Comment[ko]=Komposer 기본 편집기 diff --git a/libkdepim/kprefsdialog.cpp b/libkdepim/kprefsdialog.cpp index 9aef645e6..1af04fd46 100644 --- a/libkdepim/kprefsdialog.cpp +++ b/libkdepim/kprefsdialog.cpp @@ -376,7 +376,7 @@ KPrefsWidDate::KPrefsWidDate( KConfigSkeleton::ItemDateTime *item, void KPrefsWidDate::readConfig() { - mDateEdit->setDate( mItem->value().date() ); + mDateEdit->setDate( mItem->value().date().isValid() ? mItem->value().date() : TQDate::currentDate() ); } void KPrefsWidDate::writeConfig() diff --git a/libkdepim/ktimeedit.cpp b/libkdepim/ktimeedit.cpp index 15d318418..2e82b7dfb 100644 --- a/libkdepim/ktimeedit.cpp +++ b/libkdepim/ktimeedit.cpp @@ -161,7 +161,7 @@ TQTime KTimeEdit::getTime() const ok = false; } } - kdDebug(5300) << "KTimeEdit::getTime(): " << time.toString() << endl; + // kdDebug(5300) << "KTimeEdit::getTime(): " << time.toString() << endl; return time; } diff --git a/libkdepim/kvcarddrag.cpp b/libkdepim/kvcarddrag.cpp index 2008f7a92..b8057367a 100644 --- a/libkdepim/kvcarddrag.cpp +++ b/libkdepim/kvcarddrag.cpp @@ -25,8 +25,11 @@ static const char vcard_mime_string[] = "text/x-vcard"; -KVCardDrag::KVCardDrag( const TQString &content, TQWidget *dragsource, - const char *name ) +#if defined(KABC_VCARD_ENCODING_FIX) +KVCardDrag::KVCardDrag( const TQByteArray &content, TQWidget *dragsource, const char *name ) +#else +KVCardDrag::KVCardDrag( const TQString &content, TQWidget *dragsource, const char *name ) +#endif : TQStoredDrag( vcard_mime_string, dragsource, name ) { setVCard( content ); @@ -35,28 +38,60 @@ KVCardDrag::KVCardDrag( const TQString &content, TQWidget *dragsource, KVCardDrag::KVCardDrag( TQWidget *dragsource, const char *name ) : TQStoredDrag( vcard_mime_string, dragsource, name ) { +#if defined(KABC_VCARD_ENCODING_FIX) + setVCard( TQByteArray() ); +#else setVCard( TQString::null ); +#endif } +#if defined(KABC_VCARD_ENCODING_FIX) +void KVCardDrag::setVCard( const TQByteArray &content ) +{ + setEncodedData( content ); +} +#else void KVCardDrag::setVCard( const TQString &content ) { setEncodedData( content.utf8() ); } +#endif bool KVCardDrag::canDecode( TQMimeSource *e ) { return e->provides( vcard_mime_string ); } +#if defined(KABC_VCARD_ENCODING_FIX) +bool KVCardDrag::decode( TQMimeSource *e, TQByteArray &content ) +{ + if ( !canDecode( e ) ) { + return false; + } + content = e->encodedData( vcard_mime_string ); + return true; +} +#else bool KVCardDrag::decode( TQMimeSource *e, TQString &content ) { + if ( !canDecode( e ) ) { + return false; + } content = TQString::fromUtf8( e->encodedData( vcard_mime_string ) ); return true; } +#endif bool KVCardDrag::decode( TQMimeSource *e, KABC::Addressee::List& addressees ) { + if ( !canDecode( e ) ) { + return false; + } +#if defined(KABC_VCARD_ENCODING_FIX) + addressees = KABC::VCardConverter().parseVCardsRaw( e->encodedData( vcard_mime_string ).data() ); +#else addressees = KABC::VCardConverter().parseVCards( e->encodedData( vcard_mime_string ) ); +#endif return true; } diff --git a/libkdepim/kvcarddrag.h b/libkdepim/kvcarddrag.h index 55b3ef188..30d8dd742 100644 --- a/libkdepim/kvcarddrag.h +++ b/libkdepim/kvcarddrag.h @@ -26,6 +26,7 @@ #include #include +#include // for KABC_VCARD_ENCODING_FIX define #include class KVCardDragPrivate; @@ -49,14 +50,21 @@ class KDE_EXPORT KVCardDrag : public QStoredDrag /** * Constructs a vcard drag with the @p addressee. */ +#if defined(KABC_VCARD_ENCODING_FIX) + KVCardDrag( const TQByteArray &content, TQWidget *dragsource = 0, const char *name = 0 ); +#else KVCardDrag( const TQString &content, TQWidget *dragsource = 0, const char *name = 0 ); +#endif virtual ~KVCardDrag() {} /** * Sets the vcard of the drag to @p content. */ +#if defined(KABC_VCARD_ENCODING_FIX) + void setVCard( const TQByteArray &content ); +#else void setVCard( const TQString &content ); - +#endif /** * Returns true if the MIME source @p e contains a vcard object. */ @@ -65,7 +73,11 @@ class KDE_EXPORT KVCardDrag : public QStoredDrag /** * Decodes the MIME source @p e and puts the resulting vcard into @p content. */ +#if defined(KABC_VCARD_ENCODING_FIX) + static bool decode( TQMimeSource *e, TQByteArray &content ); +#else static bool decode( TQMimeSource *e, TQString &content ); +#endif /** * Decodes the MIME source @p e and puts the resulting vcard into @p addresseess. diff --git a/libkdepim/ldapclient.cpp b/libkdepim/ldapclient.cpp index 359e03568..39d384e83 100644 --- a/libkdepim/ldapclient.cpp +++ b/libkdepim/ldapclient.cpp @@ -349,6 +349,22 @@ LdapSearch::LdapSearch() TQT_SLOT(slotFileChanged(const TQString&))); } +void LdapSearch::readWeighForClient( LdapClient *client, KConfig *config, int clientNumber ) +{ + const int completionWeight = config->readNumEntry( TQString( "SelectedCompletionWeight%1" ).arg( clientNumber ), -1 ); + if ( completionWeight != -1 ) + client->setCompletionWeight( completionWeight ); +} + +void LdapSearch::updateCompletionWeights() +{ + KConfig *config = KPIM::LdapSearch::config(); + config->setGroup( "LDAP" ); + for ( uint i = 0; i < mClients.size(); i++ ) { + readWeighForClient( mClients[i], config, i ); + } +} + void LdapSearch::readConfig() { cancelSearch(); @@ -371,9 +387,7 @@ void LdapSearch::readConfig() if ( !server.host().isEmpty() ) mNoLDAPLookup = false; ldapClient->setServer( server ); - int completionWeight = config->readNumEntry( TQString( "SelectedCompletionWeight%1" ).arg( j ), -1 ); - if ( completionWeight != -1 ) - ldapClient->setCompletionWeight( completionWeight ); + readWeighForClient( ldapClient, config, j ); TQStringList attrs; // note: we need "objectClass" to detect distribution lists @@ -499,7 +513,7 @@ void LdapSearch::makeSearchData( TQStringList& ret, LdapResultList& resList ) bool wasCN = false; bool wasDC = false; - kdDebug(5300) << "\n\nLdapSearch::makeSearchData()\n\n" << endl; + //kdDebug(5300) << "\n\nLdapSearch::makeSearchData()\n\n" << endl; LdapAttrMap::ConstIterator it2; for ( it2 = (*it1).attrs.begin(); it2 != (*it1).attrs.end(); ++it2 ) { @@ -508,7 +522,7 @@ void LdapSearch::makeSearchData( TQStringList& ret, LdapResultList& resList ) if( len > 0 && '\0' == val[len-1] ) --len; const TQString tmp = TQString::fromUtf8( val, len ); - kdDebug(5300) << " key: \"" << it2.key() << "\" value: \"" << tmp << "\"" << endl; + //kdDebug(5300) << " key: \"" << it2.key() << "\" value: \"" << tmp << "\"" << endl; if ( it2.key() == "cn" ) { name = tmp; if( mail.isEmpty() ) @@ -551,7 +565,7 @@ void LdapSearch::makeSearchData( TQStringList& ret, LdapResultList& resList ) if( mails.isEmpty()) { if ( !mail.isEmpty() ) mails.append( mail ); if( isDistributionList ) { - kdDebug(5300) << "\n\nLdapSearch::makeSearchData() found a list: " << name << "\n\n" << endl; + //kdDebug(5300) << "\n\nLdapSearch::makeSearchData() found a list: " << name << "\n\n" << endl; ret.append( name ); // following lines commented out for bugfixing kolab issue #177: // @@ -568,14 +582,14 @@ void LdapSearch::makeSearchData( TQStringList& ret, LdapResultList& resList ) //mail.prepend( name ); //mail = name; } else { - kdDebug(5300) << "LdapSearch::makeSearchData() found BAD ENTRY: \"" << name << "\"" << endl; + //kdDebug(5300) << "LdapSearch::makeSearchData() found BAD ENTRY: \"" << name << "\"" << endl; continue; // nothing, bad entry } } else if ( name.isEmpty() ) { - kdDebug(5300) << "LdapSearch::makeSearchData() mail: \"" << mail << "\"" << endl; + //kdDebug(5300) << "LdapSearch::makeSearchData() mail: \"" << mail << "\"" << endl; ret.append( mail ); } else { - kdDebug(5300) << "LdapSearch::makeSearchData() name: \"" << name << "\" mail: \"" << mail << "\"" << endl; + //kdDebug(5300) << "LdapSearch::makeSearchData() name: \"" << name << "\" mail: \"" << mail << "\"" << endl; ret.append( TQString( "%1 <%2>" ).arg( name ).arg( mail ) ); } diff --git a/libkdepim/ldapclient.h b/libkdepim/ldapclient.h index 5167660e2..cf3f55827 100644 --- a/libkdepim/ldapclient.h +++ b/libkdepim/ldapclient.h @@ -256,6 +256,7 @@ class KDE_EXPORT LdapSearch : public QObject void startSearch( const TQString& txt ); void cancelSearch(); bool isAvailable() const; + void updateCompletionWeights(); TQValueList< LdapClient* > clients() const { return mClients; } @@ -276,6 +277,7 @@ class KDE_EXPORT LdapSearch : public QObject void slotFileChanged( const TQString& ); private: + void readWeighForClient( LdapClient *client, KConfig *config, int clientNumber ); void readConfig(); void finish(); void makeSearchData( TQStringList& ret, LdapResultList& resList ); diff --git a/libkdepim/ldapsearchdialog.cpp b/libkdepim/ldapsearchdialog.cpp index 72011966a..a51ccfb9d 100644 --- a/libkdepim/ldapsearchdialog.cpp +++ b/libkdepim/ldapsearchdialog.cpp @@ -1,5 +1,5 @@ /* ldapsearchdialogimpl.cpp - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klar�vdalens Datakonsult AB * * Author: Steffen Hansen * @@ -21,6 +21,8 @@ #include "ldapsearchdialog.h" #include "ldapclient.h" +#include + #include #include #include @@ -94,12 +96,20 @@ static TQMap& adrbookattr2ldap() return keys; } -class ContactListItem : public QListViewItem +namespace KPIM { + +class ContactListItem : public TQListViewItem { public: ContactListItem( TQListView* parent, const KPIM::LdapAttrMap& attrs ) : TQListViewItem( parent ), mAttrs( attrs ) - { } + { + const KPIM::LdapAttrValue &mailAttrs = attrs[ "mail" ]; + if ( mailAttrs.isEmpty() ) { + setSelectable( false ); + setEnabled( false ); + } + } KPIM::LdapAttrMap mAttrs; @@ -112,6 +122,8 @@ class ContactListItem : public QListViewItem } }; +} + LDAPSearchDialog::LDAPSearchDialog( TQWidget* parent, const char* name ) : KDialogBase( Plain, i18n( "Search for Addresses in Directory" ), Help | User1 | User2 | User3 | Cancel, Default, parent, name, false, true ) @@ -248,7 +260,7 @@ void LDAPSearchDialog::restoreSettings() KPIM::LdapClient* ldapClient = new KPIM::LdapClient( 0, this, "ldapclient" ); ldapClient->setServer( ldapServer ); - + TQStringList attrs; for ( TQMap::Iterator it = adrbookattr2ldap().begin(); it != adrbookattr2ldap().end(); ++it ) @@ -435,7 +447,7 @@ TQString LDAPSearchDialog::selectedEMails() const if ( name.isEmpty() ) { result << email; } else { - result << name + " <" + email + ">"; + result << KPIM::quoteNameIfNecessary( name ) + " <" + email + ">"; } } } diff --git a/libkdepim/ldapsearchdialog.h b/libkdepim/ldapsearchdialog.h index 1b3a7cc0e..9b19e5246 100644 --- a/libkdepim/ldapsearchdialog.h +++ b/libkdepim/ldapsearchdialog.h @@ -1,5 +1,5 @@ /* ldapsearchdialogimpl.h - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klar�vdalens Datakonsult AB * * Author: Steffen Hansen * diff --git a/libkdepim/progressdialog.cpp b/libkdepim/progressdialog.cpp index f35f23909..227e73766 100644 --- a/libkdepim/progressdialog.cpp +++ b/libkdepim/progressdialog.cpp @@ -224,6 +224,11 @@ void TransactionItem::setCrypto( bool on ) mSSLLabel->setState( mSSLLabel->lastState() ); } +void TransactionItem::setTotalSteps( int totalSteps ) +{ + mProgress->setTotalSteps( totalSteps ); +} + void TransactionItem::slotItemCanceled() { if ( mItem ) @@ -279,6 +284,8 @@ ProgressDialog::ProgressDialog( TQWidget* alignWidget, TQWidget* parent, const c this, TQT_SLOT( slotTransactionLabel( KPIM::ProgressItem*, const TQString& ) ) ); connect ( pm, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ), this, TQT_SLOT( slotTransactionUsesCrypto( KPIM::ProgressItem*, bool ) ) ); + connect ( pm, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ), + this, TQT_SLOT( slotTransactionUsesBusyIndicator( KPIM::ProgressItem*, bool ) ) ); connect ( pm, TQT_SIGNAL( showProgressDialog() ), this, TQT_SLOT( slotShow() ) ); } @@ -374,6 +381,17 @@ void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item, } } +void ProgressDialog::slotTransactionUsesBusyIndicator( KPIM::ProgressItem *item, bool value ) +{ + if ( mTransactionsToListviewItems.contains( item ) ) { + TransactionItem *ti = mTransactionsToListviewItems[ item ]; + if ( value ) + ti->setTotalSteps( 0 ); + else + ti->setTotalSteps( 100 ); + } +} + void ProgressDialog::slotShow() { setVisible( true ); diff --git a/libkdepim/progressdialog.h b/libkdepim/progressdialog.h index dc0e67949..cabcb69a2 100644 --- a/libkdepim/progressdialog.h +++ b/libkdepim/progressdialog.h @@ -90,6 +90,7 @@ public: void setLabel( const TQString& ); void setStatus( const TQString& ); void setCrypto( bool ); + void setTotalSteps( int totalSteps ); ProgressItem* item() const { return mItem; } @@ -132,6 +133,7 @@ void slotTransactionAdded( KPIM::ProgressItem *item ); void slotTransactionStatus( KPIM::ProgressItem *item, const TQString& ); void slotTransactionLabel( KPIM::ProgressItem *item, const TQString& ); void slotTransactionUsesCrypto( KPIM::ProgressItem *item, bool ); + void slotTransactionUsesBusyIndicator( KPIM::ProgressItem*, bool ); void slotClose(); void slotShow(); diff --git a/libkdepim/progressmanager.cpp b/libkdepim/progressmanager.cpp index 0c73e0c55..2e5f4d6eb 100644 --- a/libkdepim/progressmanager.cpp +++ b/libkdepim/progressmanager.cpp @@ -41,7 +41,7 @@ ProgressItem::ProgressItem( :mId( id ), mLabel( label ), mStatus( status ), mParent( parent ), mCanBeCanceled( canBeCanceled ), mProgress( 0 ), mTotal( 0 ), mCompleted( 0 ), mWaitingForKids( false ), mCanceled( false ), - mUsesCrypto( usesCrypto ) + mUsesCrypto( usesCrypto ), mUsesBusyIndicator( false ) {} ProgressItem::~ProgressItem() @@ -123,6 +123,12 @@ void ProgressItem::setUsesCrypto( bool v ) emit progressItemUsesCrypto( this, v ); } +void ProgressItem::setUsesBusyIndicator( bool useBusyIndicator ) +{ + mUsesBusyIndicator = useBusyIndicator; + emit progressItemUsesBusyIndicator( this, useBusyIndicator ); +} + // ====================================== ProgressManager::ProgressManager() :TQObject() { @@ -170,6 +176,8 @@ ProgressItem* ProgressManager::createProgressItemImpl( this, TQT_SIGNAL( progressItemLabel(KPIM::ProgressItem*, const TQString&) ) ); connect ( t, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ), this, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ) ); + connect ( t, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ), + this, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ) ); emit progressItemAdded( t ); } else { @@ -212,7 +220,12 @@ ProgressItem* ProgressManager::singleItem() const ProgressItem *item = 0; TQDictIterator< ProgressItem > it( mTransactions ); for ( ; it.current(); ++it ) { - if ( !(*it)->parent() ) { // if it's a top level one, only those count + + // No single item for progress possible, as one of them is a busy indicator one. + if ( (*it)->usesBusyIndicator() ) + return 0; + + if ( !(*it)->parent() ) { // if it's a top level one, only those count if ( item ) return 0; // we found more than one else diff --git a/libkdepim/progressmanager.h b/libkdepim/progressmanager.h index b4233f8df..bf2842716 100644 --- a/libkdepim/progressmanager.h +++ b/libkdepim/progressmanager.h @@ -95,6 +95,18 @@ class KDE_EXPORT ProgressItem : public QObject */ void setUsesCrypto( bool v ); + /** + * @return whether this item uses a busy indicator instead of real progress display + */ + bool usesBusyIndicator() const { return mUsesBusyIndicator; } + + /** + * Sets whether this item uses a busy indicator instead of real progress for its progress bar. + * If it uses a busy indicator, you are still responsible for calling setProgress() from time to + * time to update the busy indicator. + */ + void setUsesBusyIndicator( bool useBusyIndicator ); + /** * @return The current progress value of this item in percent. */ @@ -192,6 +204,15 @@ signals: */ void progressItemUsesCrypto( KPIM::ProgressItem*, bool ); + /** + * Emitted when the busy indicator state of an item changes. Should be used + * by progress dialogs so that they can adjust the display of the progress bar + * to the new mode. + * @param item The updated item + * @param value True if the item uses a busy indicator now, false otherwise + */ + void progressItemUsesBusyIndicator( KPIM::ProgressItem *item, bool value ); + protected: /* Only to be used by our good friend the ProgressManager */ @@ -217,6 +238,7 @@ signals: bool mWaitingForKids; bool mCanceled; bool mUsesCrypto; + bool mUsesBusyIndicator; }; /** @@ -335,6 +357,9 @@ class KDE_EXPORT ProgressManager : public QObject /** * @return the only top level progressitem when there's only one. * Returns 0 if there is no item, or more than one top level item. + * Since this is used to calculate the overall progress, it will also return + * 0 if there is an item which uses a busy indicator, since that will invalidate + * the overall progress. */ ProgressItem* singleItem() const; @@ -361,6 +386,8 @@ class KDE_EXPORT ProgressManager : public QObject void progressItemLabel( KPIM::ProgressItem*, const TQString& ); /** @see ProgressItem::progressItemUsesCrypto() */ void progressItemUsesCrypto( KPIM::ProgressItem*, bool ); + /** @see ProgressItem::progressItemUsesBusyIndicator */ + void progressItemUsesBusyIndicator( KPIM::ProgressItem*, bool ); /** * Emitted when an operation requests the listeners to be shown. diff --git a/libkdepim/statusbarprogresswidget.cpp b/libkdepim/statusbarprogresswidget.cpp index c6fa807a2..a7b240ea0 100644 --- a/libkdepim/statusbarprogresswidget.cpp +++ b/libkdepim/statusbarprogresswidget.cpp @@ -105,6 +105,8 @@ StatusbarProgressWidget::StatusbarProgressWidget( ProgressDialog* progressDialog this, TQT_SLOT( slotProgressItemAdded( KPIM::ProgressItem * ) ) ); connect ( ProgressManager::instance(), TQT_SIGNAL( progressItemCompleted( KPIM::ProgressItem * ) ), this, TQT_SLOT( slotProgressItemCompleted( KPIM::ProgressItem * ) ) ); + connect ( ProgressManager::instance(), TQT_SIGNAL(progressItemUsesBusyIndicator(KPIM::ProgressItem*,bool)), + this, TQT_SLOT( updateBusyMode() ) ); connect ( progressDialog, TQT_SIGNAL( visibilityChanged( bool )), this, TQT_SLOT( slotProgressDialogVisible( bool ) ) ); @@ -119,9 +121,8 @@ StatusbarProgressWidget::StatusbarProgressWidget( ProgressDialog* progressDialog // In slot..Added we can only end up in 1 or N. // In slot..Removed we can end up in 0, 1, or we can stay in N if we were already. -void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item ) +void StatusbarProgressWidget::updateBusyMode() { - if ( item->parent() ) return; // we are only interested in top level items connectSingleItem(); // if going to 1 item if ( mCurrentItem ) { // Exactly one item delete mBusyTimer; @@ -138,6 +139,14 @@ void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item ) } } +void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item ) +{ + if ( item->parent() ) + return; // we are only interested in top level items + + updateBusyMode(); +} + void StatusbarProgressWidget::slotProgressItemCompleted( ProgressItem *item ) { if ( item->parent() ) return; // we are only interested in top level items diff --git a/libkdepim/statusbarprogresswidget.h b/libkdepim/statusbarprogresswidget.h index d32a37b84..a35943013 100644 --- a/libkdepim/statusbarprogresswidget.h +++ b/libkdepim/statusbarprogresswidget.h @@ -72,6 +72,7 @@ protected slots: void slotProgressDialogVisible( bool ); void slotShowItemDelayed(); void slotBusyIndicator(); + void updateBusyMode(); protected: void setMode(); diff --git a/libkdepim/tests/Makefile.am b/libkdepim/tests/Makefile.am index 5adc2e1c4..2e0d081ba 100644 --- a/libkdepim/tests/Makefile.am +++ b/libkdepim/tests/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_builddir)/libkdepim -I$(top_srcdir)/libemailfunctions $(all_includes) +AM_CPPFLAGS = -I$(top_builddir)/libkdepim -I$(top_srcdir)/libkdepim -I$(top_srcdir)/libemailfunctions $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) LDADD = ../libkdepim.la $(LIB_KDECORE) @@ -9,8 +9,10 @@ check_PROGRAMS = testwizard testaddresseelineedit \ test_kregexp \ testdateedit \ testlinklocator \ - testdistrlist + testkincidencechooser +# disabled because of X dependency +# testdistrlist testwizard_SOURCES = testwizard.cpp myconfig.kcfgc testaddresseelineedit_SOURCES = testaddresseelineedit.cpp @@ -20,9 +22,10 @@ testutf7decoder_SOURCES = testutf7decoder.cpp test_kregexp_SOURCES = test_kregexp.cpp testdateedit_SOURCES = testdateedit.cpp testlinklocator_SOURCES = testlinklocator.cpp -testdistrlist_SOURCES = testdistrlist.cpp +#testdistrlist_SOURCES = testdistrlist.cpp +testkincidencechooser_SOURCES = testkincidencechooser.cpp -TESTS = testdistrlist +#TESTS = testdistrlist METASOURCES = AUTO diff --git a/libkdepim/tests/testkincidencechooser.cpp b/libkdepim/tests/testkincidencechooser.cpp new file mode 100644 index 000000000..1204f8dc2 --- /dev/null +++ b/libkdepim/tests/testkincidencechooser.cpp @@ -0,0 +1,45 @@ +/* + Copyright (C) 2009 Allen Winter + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +using namespace KCal; + +#include "kincidencechooser.h" +using namespace KPIM; + +int main( int argc, char **argv ) +{ + KCmdLineArgs::init( argc, argv, "testkincidencechooser", 0, + "KIncidenceChooserTest", "1.0", + "kincidencechooser test app" ); + KApplication app; + KIncidenceChooser *chooser = new KIncidenceChooser(); + + Event event; + event.setSummary( i18n( "Meeting" ) ); + event.setDescription( i18n( "Discuss foo" ) ); + chooser->setIncidence( &event, &event ); + chooser->resize( 600, 600 ); + chooser->show(); + return app.exec(); +} diff --git a/libkdepim/tests/testutf7encoder2.cpp b/libkdepim/tests/testutf7encoder2.cpp index 57c195662..6d67bae0a 100644 --- a/libkdepim/tests/testutf7encoder2.cpp +++ b/libkdepim/tests/testutf7encoder2.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include int main( int argc, char * argv[] ) { if ( argc == 1 ) { @@ -31,10 +31,10 @@ int main( int argc, char * argv[] ) { len = 1; cout << (enc->fromUnicode(TQString(buffer[i]),len)).data(); } - cout << endl; + std::cout << std::endl; #else int len = buffer.length(); - cout << (enc->fromUnicode(buffer,len)).data() << endl;; + std::cout << (enc->fromUnicode(buffer,len)).data() << std::endl;; #endif // CHAR_WISE delete enc; #endif // else USE_STREAM -- cgit v1.2.1