@@ -32,6 +32,7 @@ QgsDetailedItemDelegate::QgsDetailedItemDelegate(QObject * parent) :
3232 mpCheckBox(new QCheckBox())
3333
3434{
35+ // mpWidget->setFixedHeight(80);
3536 mpCheckBox->resize (16 ,16 );
3637}
3738
@@ -86,21 +87,24 @@ void QgsDetailedItemDelegate::paint(QPainter * thepPainter,
8687 QString myDetailString = theIndex.model ()->data (theIndex, Qt::UserRole).toString ();
8788 bool myCheckState = theIndex.model ()->data (theIndex, Qt::CheckStateRole).toBool ();
8889 mpCheckBox->setChecked (myCheckState);
89- QPixmap myPixmap (mpCheckBox->size ());
90- mpCheckBox->render (&myPixmap); // we will draw this onto the widget further down
90+ QPixmap myCbxPixmap (mpCheckBox->size ());
91+ mpCheckBox->render (&myCbxPixmap); // we will draw this onto the widget further down
92+ QPixmap myDecoPixmap;
9193
9294 //
9395 // Calculate the widget height and other metrics
9496 //
9597 QFont myFont = theOption.font ;
96- QFont myBoldFont = myFont;
97- myBoldFont.setBold (true );
98- myBoldFont.setPointSize (myFont.pointSize () + 3 );
99- QFontMetrics myMetrics (myBoldFont);
98+ QFont myTitleFont = myFont;
99+ myTitleFont.setBold (true );
100+ myTitleFont.setPointSize (myFont.pointSize () + 3 );
101+ QFontMetrics myTitleMetrics (myTitleFont);
102+ QFontMetrics myDetailMetrics (myFont);
100103 int myVerticalSpacer = 3 ; // spacing between title and description
101104 int myHorizontalSpacer = 5 ; // spacing between checkbox / icon and description
102- int myTextStartX = theOption.rect .x () + myPixmap.width () + myHorizontalSpacer;
103- int myHeight = myMetrics.height () + myVerticalSpacer;
105+ int myTextStartX = theOption.rect .x () + myHorizontalSpacer;
106+ int myTextStartY= theOption.rect .y () + myVerticalSpacer;
107+ int myHeight = myTitleMetrics.height () + myVerticalSpacer;
104108
105109 //
106110 // Draw the item background with a gradient if its highlighted
@@ -110,7 +114,7 @@ void QgsDetailedItemDelegate::paint(QPainter * thepPainter,
110114 QColor myColor1 = theOption.palette .highlight ();
111115 QColor myColor2 = myColor1;
112116 myColor2 = myColor2.lighter (110 ); // 10% lighter
113- int myHeight = myMetrics .height () + myVerticalSpacer;
117+ int myHeight = myTitleMetrics .height () + myVerticalSpacer;
114118 QLinearGradient myGradient (QPointF (0 ,theOption.rect .y ()),
115119 QPointF (0 ,theOption.rect .y () + myHeight*2 ));
116120 myGradient.setColorAt (0 , myColor1);
@@ -124,19 +128,61 @@ void QgsDetailedItemDelegate::paint(QPainter * thepPainter,
124128 //
125129 // Draw the checkbox
126130 //
127- thepPainter->drawPixmap (theOption.rect .x (),
128- theOption.rect .y () + mpCheckBox->height (),
129- myPixmap);
130-
131+ bool myCheckableFlag = true ;
132+ if (theIndex.flags () == Qt::ItemIsUserCheckable)
133+ {
134+ myCheckableFlag = false ;
135+ }
136+ if (myCheckableFlag)
137+ {
138+ thepPainter->drawPixmap (theOption.rect .x (),
139+ theOption.rect .y () + mpCheckBox->height (),
140+ myCbxPixmap);
141+ myTextStartX = theOption.rect .x () + myCbxPixmap.width () + myHorizontalSpacer;
142+ }
143+ //
144+ // Draw the decoration (pixmap)
131145 //
132- // Draw the title and description
146+ bool myIconFlag = false ;
147+ if (!theIndex.model ()->data (theIndex, Qt::DecorationRole).isNull ())
148+ {
149+ myDecoPixmap = theIndex.model ()->data (theIndex, Qt::DecorationRole).value <QPixmap>();
150+ thepPainter->drawPixmap (myTextStartX,
151+ myTextStartY + (myDecoPixmap.height () / 2 ),
152+ myDecoPixmap);
153+ myTextStartX += myDecoPixmap.width () + myHorizontalSpacer;
154+ }
155+ //
156+ // Draw the title
157+ //
158+ myTextStartY += myHeight/2 ;
159+ thepPainter->setFont (myTitleFont);
160+ thepPainter->drawText ( myTextStartX ,
161+ myTextStartY ,
162+ myString);
163+ //
164+ // Draw the description with word wrapping if needed
133165 //
134- thepPainter->setFont (myBoldFont);
135- thepPainter->drawText ( myTextStartX ,theOption.rect .y () + myHeight, myString);
136166 thepPainter->setFont (myFont); // return to original font set by client
137- thepPainter->drawText ( myTextStartX,
138- theOption.rect .y () + (myHeight *2 ) - myVerticalSpacer,
139- myDetailString);
167+ if (myIconFlag)
168+ {
169+ myTextStartY += myVerticalSpacer;
170+ }
171+ else
172+ {
173+ myTextStartY += myDetailMetrics.height () + myVerticalSpacer;
174+ }
175+ QStringList myList =
176+ wordWrap ( myDetailString, myDetailMetrics, theOption.rect .width () - myTextStartX );
177+ QStringListIterator myLineWrapIterator (myList);
178+ while (myLineWrapIterator.hasNext ())
179+ {
180+ QString myLine = myLineWrapIterator.next ();
181+ thepPainter->drawText ( myTextStartX,
182+ myTextStartY,
183+ myLine);
184+ myTextStartY += myDetailMetrics.height () - myVerticalSpacer;
185+ }
140186 thepPainter->restore ();
141187 }
142188}
@@ -152,14 +198,70 @@ QSize QgsDetailedItemDelegate::sizeHint(
152198 else // fall back to hand calculated & hand drawn item
153199 {
154200 QFont myFont = theOption.font ;
155- QFont myBoldFont = myFont;
156- myBoldFont.setBold (true );
157- myBoldFont.setPointSize (myFont.pointSize () + 3 );
158- QFontMetrics myMetrics (myBoldFont);
201+ QFont myTitleFont = myFont;
202+ myTitleFont.setBold (true );
203+ myTitleFont.setPointSize (myFont.pointSize () + 3 );
204+ QFontMetrics myTitleMetrics (myTitleFont);
205+ QFontMetrics myDetailMetrics (myFont);
159206 int myVerticalSpacer = 3 ; // spacing between title and description
160207 int myHorizontalSpacer = 5 ; // spacing between checkbox / icon and description
161- int myHeight = myMetrics.height () + myVerticalSpacer;
162- return QSize (50 ,
163- myHeight *2 + myVerticalSpacer);
208+ int myHeight = myTitleMetrics.height () + myVerticalSpacer;
209+ QString myDetailString = theIndex.model ()->data (theIndex, Qt::UserRole).toString ();
210+ QStringList myList = wordWrap ( myDetailString,
211+ myDetailMetrics,
212+ theOption.rect .width () - (mpCheckBox->width () + myHorizontalSpacer));
213+ myHeight += (myList.count () + 1 ) * (myDetailMetrics.height () - myVerticalSpacer);
214+ #ifdef Q_OS_MACX
215+ // for some reason itmes are non selectable if using rect.width() on osx
216+ return QSize (50 , myHeight + myVerticalSpacer);
217+ #else
218+ return QSize (theOption.rect .width (), myHeight + myVerticalSpacer);
219+ #endif
220+ }
221+ }
222+
223+ QStringList QgsDetailedItemDelegate::wordWrap (QString theString,
224+ QFontMetrics theMetrics,
225+ int theWidth) const
226+ {
227+ if ( theString.isEmpty () ) return QStringList ();
228+ if ( 50 >= theWidth ) return QStringList () << theString;
229+ QString myDebug = QString (" Word wrapping: %1 into %2 pixels" ).arg (theString).arg (theWidth);
230+ qDebug (myDebug.toLocal8Bit ());
231+ // iterate the string
232+ QStringList myList;
233+ QString myCumulativeLine=" " ;
234+ QString myStringToPreviousSpace=" " ;
235+ int myPreviousSpacePos=0 ;
236+ for (int i=0 ; i < theString.count (); ++i)
237+ {
238+ QChar myChar = theString.at (i);
239+ if (myChar == QChar (' ' ))
240+ {
241+ myStringToPreviousSpace = myCumulativeLine;
242+ myPreviousSpacePos=i;
243+ }
244+ myCumulativeLine += myChar;
245+ if (theMetrics.width (myCumulativeLine) >= theWidth)
246+ {
247+ // time to wrap
248+ // @todo deal with long strings that have no spaces
249+ // forcing a break at current pos...
250+ myList << myStringToPreviousSpace.trimmed ();
251+ i = myPreviousSpacePos;
252+ myStringToPreviousSpace = " " ;
253+ myCumulativeLine = " " ;
254+ }
255+ }// end of i loop
256+ // add whatever is left in the string to the list
257+ if (!myCumulativeLine.trimmed ().isEmpty ())
258+ {
259+ myList << myCumulativeLine.trimmed ();
164260 }
261+
262+ // qDebug("Wrapped legend entry:");
263+ // qDebug(theString);
264+ // qDebug(myList.join("\n").toLocal8Bit());
265+ return myList;
266+
165267}
0 commit comments