[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdenetwork/kopete/kopete
From:       Roman Jarosz <kedgedev () gmail ! com>
Date:       2009-03-30 22:01:39
Message-ID: 1238450499.597341.8969.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 947102 by rjarosz:

Add optimal width to contact list layout manger and make the calculation of width \
more sophistic. Speed optimalizations.



 M  +2 -1      config/appearance/contactlistlayouteditwidget.cpp  
 M  +28 -3     config/appearance/contactlisttoken.cpp  
 M  +4 -0      config/appearance/contactlisttoken.h  
 M  +3 -3      contactlist/DefaultContactListLayouts.xml  
 M  +3 -37     contactlist/contactlistlayoutitemconfig.cpp  
 M  +23 -21    contactlist/contactlistlayoutitemconfig.h  
 M  +3 -1      contactlist/contactlistlayoutmanager.cpp  
 M  +135 -30   contactlist/kopeteitemdelegate.cpp  
 M  +11 -0     contactlist/kopeteitemdelegate.h  


--- trunk/KDE/kdenetwork/kopete/kopete/config/appearance/contactlistlayouteditwidget.cpp \
#947101:947102 @@ -76,6 +76,7 @@
 			ContactListToken *token =  new ContactListToken( clToken.mName, \
clToken.mIconName, element.value(), m_tokenDropTarget );  token->setBold( \
element.bold() );  token->setSmall( element.small() );
+			token->setOptimalSize( element.optimalSize() );
 			token->setItalic( element.italic() );
 			token->setAlignment( element.alignment() );
 			m_tokenDropTarget->insertToken( token, i, j );
@@ -108,7 +109,7 @@
 					width = twl->width();
 				}
 				currentRowConfig.addElement( LayoutItemConfigRowElement( twl->value(), width, \
                twl->bold(), twl->italic(), twl->small(),
-				                                                         twl->alignment(), \
twl->prefix(), twl->suffix() ) ); +				                                               \
twl->optimalSize(), twl->alignment(), twl->prefix(), twl->suffix() ) );  }
 		}
 
--- trunk/KDE/kdenetwork/kopete/kopete/config/appearance/contactlisttoken.cpp \
#947101:947102 @@ -26,6 +26,7 @@
 #include "kopeteitemdelegate.h"
 
 const QString ActionSmallName = QLatin1String( "ActionSmall" );
+const QString ActionOptimalSizeName = QLatin1String( "ActionOptimalSize" );
 
 Token * ContactListTokenFactory::createToken(const QString &text, const QString \
&iconName, int value, QWidget *parent)  {
@@ -33,18 +34,26 @@
 }
 
 ContactListToken::ContactListToken( const QString &text, const QString &iconName, \
                int value, QWidget *parent )
-: TokenWithLayout( text, iconName, value, parent ), m_small( false )
+: TokenWithLayout( text, iconName, value, parent ), m_small( false ), m_optimalSize( \
false )  {
 }
 
 void ContactListToken::fillMenu( QMenu * menu )
 {
-	KAction *smallAction = new KAction( KIcon( "format-text-bold"), i18n( "Small" ), \
menu ); +	KAction *optimalSizeAction = new KAction( i18n( "Optimal width" ), menu );
+	optimalSizeAction->setObjectName( ActionOptimalSizeName );
+	optimalSizeAction->setCheckable( true );
+	optimalSizeAction->setChecked( m_optimalSize );
+	menu->addAction( optimalSizeAction );
+
+	menu->addSeparator();
+
+	KAction *smallAction = new KAction( KIcon( "format-font-size-less"), i18n( "Small" \
), menu );  smallAction->setObjectName( ActionSmallName );
 	smallAction->setCheckable( true );
 	smallAction->setChecked( m_small );
+	menu->addAction( smallAction );
 
-	menu->addAction( smallAction );
 	TokenWithLayout::fillMenu( menu );
 }
 
@@ -53,6 +62,8 @@
 	TokenWithLayout::menuExecuted( action );
 	if( action->objectName() == ActionSmallName )
 		setSmall( action->isChecked() );
+	else if( action->objectName() == ActionOptimalSizeName )
+		setOptimalSize( action->isChecked() );
 }
 
 bool ContactListToken::small() const
@@ -73,4 +84,18 @@
     emit changed();
 }
 
+bool ContactListToken::optimalSize() const
+{
+	return m_optimalSize;
+}
+
+void ContactListToken::setOptimalSize( bool optimalSize )
+{
+	if ( m_optimalSize == optimalSize )
+		return;
+
+	m_optimalSize = optimalSize;
+	emit changed();
+}
+
 #include "contactlisttoken.moc"
--- trunk/KDE/kdenetwork/kopete/kopete/config/appearance/contactlisttoken.h \
#947101:947102 @@ -35,12 +35,16 @@
 	bool small() const;
 	void setSmall( bool small );
 
+	bool optimalSize() const;
+	void setOptimalSize( bool optimalSize );
+
 protected:
 	virtual void fillMenu( QMenu * menu );
 	virtual void menuExecuted( const QAction* action );
 
 private:
 	bool m_small;
+	bool m_optimalSize;
 };
 
 #endif
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/DefaultContactListLayouts.xml \
#947101:947102 @@ -2,11 +2,11 @@
 <contactlist_layouts>
 	<layout name="Default" show_metacontact_icon="true" >
 		<row>
-			<element small="false" size="0" bold="true" alignment="left" value="DisplayName" \
                italic="false" />
-			<element small="false" size="0.2" bold="false" alignment="right" \
value="ContactIcons" italic="false" /> +			<element small="false" size="0" \
bold="true" alignment="left" optimalSize="false" value="DisplayName" italic="false" \
/> +			<element small="false" size="0" bold="false" alignment="right" \
optimalSize="true" value="ContactIcons" italic="false" />  </row>
 		<row>
-			<element small="true" size="1" bold="false" alignment="left" \
value="StatusMessage" italic="false" /> +			<element small="true" size="0" \
bold="false" alignment="left" optimalSize="false" value="StatusMessage" \
italic="false" />  </row>
 	</layout>
 </contactlist_layouts>
\ No newline at end of file
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/contactlistlayoutitemconfig.cpp \
#947101:947102 @@ -22,54 +22,20 @@
 
 namespace ContactList {
 
-	LayoutItemConfigRowElement::LayoutItemConfigRowElement( int value, qreal size, bool \
                bold, bool italic, bool small,
-	                                                        Qt::Alignment alignment, \
const QString &prefix, const QString &suffix ) \
+LayoutItemConfigRowElement::LayoutItemConfigRowElement( int value, qreal size, bool \
bold, bool italic, bool small, bool optimalSize, +                                    \
Qt::Alignment alignment, const QString &prefix, const QString &suffix )  : m_value( \
value )  , m_size( size )
 	, m_bold( bold )
 	, m_italic( italic )
 	, m_small( small )
+	, m_optimalSize( optimalSize )
 	, m_alignment( alignment )
 	, m_prefix( prefix )
 	, m_suffix( suffix )
 {
 }
 
-int LayoutItemConfigRowElement::value() const
-{
-	return m_value;
-}
-
-qreal LayoutItemConfigRowElement::size() const
-{
-	return m_size;
-}
-
-bool LayoutItemConfigRowElement::bold() const
-{
-	return m_bold;
-}
-
-bool ContactList::LayoutItemConfigRowElement::italic() const
-{
-	return m_italic;
-}
-
-Qt::Alignment LayoutItemConfigRowElement::alignment() const
-{
-	return m_alignment;
-}
-
-QString LayoutItemConfigRowElement::prefix() const
-{
-	return m_prefix;
-}
-
-QString LayoutItemConfigRowElement::suffix() const
-{
-	return m_suffix;
-}
-
 //////////////////////////////////////////////
 
 void LayoutItemConfigRow::addElement( LayoutItemConfigRowElement element )
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/contactlistlayoutitemconfig.h \
#947101:947102 @@ -30,28 +30,30 @@
 
 class KOPETE_CONTACT_LIST_EXPORT LayoutItemConfigRowElement
 {
-	public:
-		LayoutItemConfigRowElement( int value, qreal size, bool bold, bool italic, bool \
                small,
-		                            Qt::Alignment alignment, const QString &prefix = \
                QString(),
-		                            const QString &suffix = QString() );
+public:
+	LayoutItemConfigRowElement( int value, qreal size, bool bold, bool italic, bool \
small, bool optimalSize, +	                            Qt::Alignment alignment, const \
QString &prefix = QString(), +	                            const QString &suffix = \
QString() );  
-		int value() const;
-		qreal size() const;
-		bool bold() const;
-		bool italic() const;
-		Qt::Alignment alignment() const;
-		QString prefix() const;
-		QString suffix() const;
-		bool small() const { return m_small; }
-	
-	private:
-		int m_value;
-		qreal m_size;
-		bool m_bold;
-		bool m_italic;
-		bool m_small;
-		Qt::Alignment m_alignment;
-		QString m_prefix, m_suffix;
+	inline int value() const { return m_value; }
+	inline qreal size() const { return m_size; }
+	inline bool bold() const { return m_bold; }
+	inline bool italic() const { return m_italic; }
+	inline Qt::Alignment alignment() const { return m_alignment; }
+	inline QString prefix() const { return m_prefix; }
+	inline QString suffix() const { return m_suffix; }
+	inline bool small() const { return m_small; }
+	inline bool optimalSize() const { return m_optimalSize; }
+
+private:
+	int m_value;
+	qreal m_size;
+	bool m_bold;
+	bool m_italic;
+	bool m_small;
+	bool m_optimalSize;
+	Qt::Alignment m_alignment;
+	QString m_prefix, m_suffix;
 };
 
 class KOPETE_CONTACT_LIST_EXPORT LayoutItemConfigRow
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/contactlistlayoutmanager.cpp \
#947101:947102 @@ -211,6 +211,7 @@
 			bool bold = ( elementNode.toElement().attribute( "bold", "false" ).compare( \
"true", Qt::CaseInsensitive ) == 0 );  bool italic = ( \
elementNode.toElement().attribute( "italic", "false" ).compare( "true", \
Qt::CaseInsensitive ) == 0 );  bool small = ( elementNode.toElement().attribute( \
"small", "false" ).compare( "true", Qt::CaseInsensitive ) == 0 ); +			bool \
optimalSize = ( elementNode.toElement().attribute( "optimalSize", "false" ).compare( \
"true", Qt::CaseInsensitive ) == 0 );  QString alignmentString = \
elementNode.toElement().attribute( "alignment", "left" );  Qt::Alignment alignment;
 			
@@ -222,7 +223,7 @@
 			else
 				alignment = Qt::AlignCenter| Qt::AlignVCenter;
 
-			row.addElement( LayoutItemConfigRowElement( value, size, bold, italic, small, \
alignment, prefix, sufix ) ); +			row.addElement( LayoutItemConfigRowElement( value, \
size, bold, italic, small, optimalSize, alignment, prefix, sufix ) );  }
 
 		config.addRow( row );
@@ -289,6 +290,7 @@
 			elementElement.setAttribute ( "bold", element.bold() ? "true" : "false" );
 			elementElement.setAttribute ( "italic", element.italic() ? "true" : "false" );
 			elementElement.setAttribute ( "small", element.small() ? "true" : "false" );
+			elementElement.setAttribute ( "optimalSize", element.optimalSize() ? "true" : \
"false" );  
 			QString alignmentString;
 			if ( element.alignment() & Qt::AlignLeft )
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/kopeteitemdelegate.cpp \
#947101:947102 @@ -24,6 +24,7 @@
 #include <QModelIndex>
 #include <QAbstractItemView>
 #include <QApplication>
+#include <QVector>
 
 #include <qimageblitz.h>
 
@@ -166,7 +167,7 @@
 		return;
 
 	const int hBorderMargin = MARGIN * 2;
-	const int hMargins = hBorderMargin + ( rowCount - 1 ) * PADDING;
+	//const int hMargins = hBorderMargin + ( rowCount - 1 ) * PADDING;
 
 	int rowOffsetX = MARGIN;
 	int rowOffsetY = MARGIN;
@@ -292,46 +293,152 @@
 		QRectF rowBox( itemOffsetX, rowOffsetY, rowWidth, rowHeight );
 		int currentItemX = itemOffsetX;
 
-		//we need to do a quick pass to figure out how much space is left for auto sizing \
                elements
-		qreal spareSpace = 1.0;
-		int autoSizeElemCount = 0;
-		for ( int k = 0; k < elementCount; ++k )
-		{
-			spareSpace -= row.element( k ).size();
-			if ( row.element( k ).size() < 0.001 )
-				autoSizeElemCount++;
-		}
+		const qreal IconMarginH = 2.0;
+		const qreal IconMarginV = 1.0;
+		const qreal IconSize = rowHeight - 2 * IconMarginV;
 
-		qreal spacePerAutoSizeElem = spareSpace / (qreal) autoSizeElemCount;
+		QVector<DynamicLayoutItem> dynamicLayoutData( elementCount );
+		bool hasFixedTypeItem = false;
+
+		// Figure out width of items
 		for ( int j = 0; j < elementCount; ++j )
 		{
 			ContactList::LayoutItemConfigRowElement element = row.element( j );
-
 			const int value = element.value();
-			const int role = ContactList::LayoutManager::instance()->token( value \
).mModelRole; +			DynamicLayoutItem& dlItem = dynamicLayoutData[j];
 
-			qreal itemWidth = 0.0;
+			dlItem.dirty = true;
+			if ( value != ContactList::LayoutManager::ContactIcons && value != \
ContactList::LayoutManager::PlaceHolder ) +			{
+				dlItem.font = QFont( ( element.small() ) ? small : normal );
+				dlItem.font.setBold( element.bold() );
+				dlItem.font.setItalic( element.italic() );
 
-			int alignment = element.alignment();
+				const int role = ContactList::LayoutManager::instance()->token( value \
).mModelRole; +				QString text = ( role > -1 ) ? index.data( role ).toString() : \
QString(); +				dlItem.text = element.prefix() + text + element.suffix();
+			}
 
-			QFont font( ( element.small() ) ? small : normal );
-			font.setBold( element.bold() );
-			font.setItalic( element.italic() );
-			if ( painter )
-				painter->setFont( font );
+			if ( element.optimalSize() )
+			{
+				qreal idealWidth = 0;
+				if ( value == ContactList::LayoutManager::ContactIcons )
+				{
+					QObject* metaContactObject = qVariantValue<QObject*>( index.data( \
Kopete::Items::ObjectRole ) ); +					Kopete::MetaContact* metaContact = \
qobject_cast<Kopete::MetaContact*>(metaContactObject); +					const int \
contactListSize = metaContact->contacts().size(); +					idealWidth = contactListSize \
* IconSize; +					if ( contactListSize > 1 )
+						idealWidth += (contactListSize - 1) * IconMarginH;
 
-			QRectF elementBox;
+					hasFixedTypeItem = true;
+					dlItem.type = LayoutFixed;
+				}
+				else if ( ContactList::LayoutManager::PlaceHolder )
+				{
+					dlItem.type = LayoutNormal;
+				}
+				else
+				{
+					QFontMetricsF fm( dlItem.font );
+					idealWidth = fm.width( dlItem.text );
+					dlItem.type = LayoutNormal;
+				}
 
-			qreal size;
-			if ( element.size() > 0.0001 )
-				size = element.size();
+				if ( element.size() >= 0.001 )
+				{
+					const qreal maxWidth = rowWidth * element.size();
+					if ( maxWidth < idealWidth)
+						idealWidth = maxWidth;
+				}
+				dlItem.width = idealWidth;
+			}
 			else
-				size = spacePerAutoSizeElem;
+			{
+				if ( element.size() >= 0.001 )
+				{
+					dlItem.type = LayoutNormal;
+					dlItem.width = rowWidth * element.size();
+				}
+				else
+				{
+					dlItem.type = LayoutAuto;
+					dlItem.width = 0;
+				}
+			}
+		}
 
-			if ( size > 0.0001 )
+		// Check width of fixed items
+		qreal availableWidth = rowWidth;
+		if ( hasFixedTypeItem )
+		{
+			for ( int j = 0; j < elementCount; ++j )
 			{
-				itemWidth = rowWidth * size;
+				DynamicLayoutItem& dlItem = dynamicLayoutData[j];
+				if ( dlItem.type == LayoutFixed )
+				{
+					availableWidth -= dlItem.width;
+					dlItem.dirty = false;
+					if ( availableWidth < 0 )
+					{
+						dlItem.width += availableWidth;
+						availableWidth = 0;
+						break;
+					}
+				}
+			}
+		}
 
+		// Check width of normal items and count auto items
+		int layoutAutoItemCount = 0;
+		if ( availableWidth > 0 )
+		{
+			for ( int j = 0; j < elementCount; ++j )
+			{
+				DynamicLayoutItem& dlItem = dynamicLayoutData[j];
+				if ( dlItem.type == LayoutAuto )
+				{
+					layoutAutoItemCount++;
+				}
+				else if ( dlItem.dirty )
+				{
+					dlItem.dirty = false;
+					availableWidth -= dlItem.width;
+					if ( availableWidth < 0 )
+					{
+						dlItem.width += availableWidth;
+						availableWidth = 0;
+						break;
+					}
+				}
+			}
+		}
+
+		const qreal layoutAutoItemWidth = ( layoutAutoItemCount > 0 ) ? (availableWidth / \
(qreal)layoutAutoItemCount) : 0; +		for ( int j = 0; j < elementCount; ++j )
+		{
+			// Set auto items width
+			DynamicLayoutItem& dlItem = dynamicLayoutData[j];
+			if ( dlItem.dirty )
+			{
+				if ( availableWidth > 0 )
+					dlItem.width = layoutAutoItemWidth;
+				else
+					dlItem.width = 0;
+			}
+
+			qreal itemWidth = dlItem.width;
+			if ( itemWidth > 0 )
+			{
+				ContactList::LayoutItemConfigRowElement element = row.element( j );
+
+				const int value = element.value();
+				//const int role = ContactList::LayoutManager::instance()->token( value \
).mModelRole; +				const int alignment = element.alignment();
+
+				if ( painter )
+					painter->setFont( dlItem.font );
+
 				//special case for painting the ContactIcons...
 				if ( value == ContactList::LayoutManager::ContactIcons )
 				{
@@ -389,9 +496,7 @@
 				{
 					if ( painter )
 					{
-						QString text = ( role > -1 ) ? index.data( role ).toString() : QString();
-						text = element.prefix() + text + element.suffix();
-						text = QFontMetricsF( font ).elidedText( text, Qt::ElideRight, itemWidth );
+						QString text = QFontMetricsF( dlItem.font ).elidedText( dlItem.text, \
Qt::ElideRight, itemWidth );  QRectF drawRect( currentItemX, rowOffsetY, itemWidth, \
rowHeight );  painter->setClipRect( drawRect );
 						painter->drawText( drawRect, alignment, text );
--- trunk/KDE/kdenetwork/kopete/kopete/contactlist/kopeteitemdelegate.h \
#947101:947102 @@ -55,6 +55,17 @@
 	QPointF centerImage( const QImage& image, const QRectF& rect ) const;
 	QPointF centerImage( const QPixmap& pixmap, const QRectF& rect ) const;
 	qreal calculateRowHeight( const ContactList::LayoutItemConfigRow &row, const QFont \
&normal, const QFont &small ) const; +
+	enum LayoutType { LayoutAuto = 0, LayoutNormal, LayoutFixed };
+	struct DynamicLayoutItem {
+		bool dirty;
+		LayoutType type;
+		qreal width;
+
+		// Caching
+		QString text;
+		QFont font;
+	};
 };
 
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic