2 This file is part of KAddressBook.
3 Copyright (C) 2003 Helge Deller <deller@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 version 2 License as published by the Free Software Foundation.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 * - ldifvcardthumbnail -
23 * kioslave which generates tumbnails for vCard and LDIF files.
24 * The thumbnails are used e.g. by Konqueror or in the file selection
29 #include <QtCore/QFile>
30 #include <QtGui/QImage>
31 #include <QtGui/QPainter>
32 #include <QtGui/QPixmap>
36 #include <kglobalsettings.h>
38 #include <kabc/ldifconverter.h>
39 #include <kabc/vcardconverter.h>
40 #include <kstandarddirs.h>
42 #include "ldifvcardcreator.h"
46 ThumbCreator
*new_creator()
48 KGlobal::locale()->insertCatalog( "kaddressbook" );
49 return new VCard_LDIFCreator
;
53 VCard_LDIFCreator::VCard_LDIFCreator()
58 VCard_LDIFCreator::~VCard_LDIFCreator()
64 bool VCard_LDIFCreator::readContents( const QString
&path
)
68 if ( !file
.open( QIODevice::ReadOnly
) )
75 QByteArray contents
= file
.readAll();
78 // convert the file contents to a KABC::Addressee address
79 KABC::Addressee::List addrList
;
81 KABC::VCardConverter converter
;
83 addrList
= converter
.parseVCards( contents
);
84 if ( addrList
.count() == 0 ) {
85 KABC::AddresseeList l
; // FIXME porting
86 if ( !KABC::LDIFConverter::LDIFToAddressee( contents
, l
) )
89 KABC::AddresseeList::ConstIterator
it( l
.constBegin() );
90 for ( ; it
!= l
.constEnd(); ++ it
) {
91 addrList
.append( *it
);
94 if ( addrList
.count()>1 ) {
95 // create an overview (list of all names)
96 name
= i18np("One contact found:", "%1 contacts found:", addrList
.count());
98 for (linenr
=no
=0; linenr
<30 && no
<addrList
.count(); ++no
) {
100 info
= addr
.formattedName().simplified();
102 info
= addr
.givenName() + ' ' + addr
.familyName();
103 info
= info
.simplified();
113 // create card for _one_ contact
114 addr
= addrList
[ 0 ];
117 name
= addr
.formattedName().simplified();
118 if ( name
.isEmpty() )
119 name
= addr
.givenName() + ' ' + addr
.familyName();
120 name
= name
.simplified();
123 KABC::PhoneNumber::List pnList
= addr
.phoneNumbers();
124 QStringList phoneNumbers
;
125 for (int no
=0; no
<pnList
.count(); ++no
) {
126 QString pn
= pnList
[no
].number().simplified();
127 if (!pn
.isEmpty() && !phoneNumbers
.contains(pn
))
128 phoneNumbers
.append(pn
);
130 if ( !phoneNumbers
.isEmpty() )
131 text
+= phoneNumbers
.join("\n") + '\n';
133 info
= addr
.organization().simplified();
134 if ( !info
.isEmpty() )
138 KABC::Address address
= addr
.address(KABC::Address::Work
);
139 if (address
.isEmpty())
140 address
= addr
.address(KABC::Address::Home
);
141 if (address
.isEmpty())
142 address
= addr
.address(KABC::Address::Pref
);
143 info
= address
.formattedAddress();
144 if ( !info
.isEmpty() )
150 QRect
glyphCoords(int index
, int fontWidth
)
152 int itemsPerRow
= fontWidth
/ 4;
153 return QRect( (index
% itemsPerRow
) * 4, (index
/ itemsPerRow
) * 7, 4, 7 );
156 bool VCard_LDIFCreator::createImageSmall()
158 text
= name
+ '\n' + text
;
161 QString pixmap
= KStandardDirs::locate( "data", "kio_thumbnail/pics/thumbnailfont_7x4.png" );
162 if ( pixmap
.isEmpty() ) {
163 kWarning() <<"VCard_LDIFCreator: Font image \"thumbnailfont_7x4.png\" not found!";
166 mFont
= new QPixmap( pixmap
);
169 QSize
chSize(4, 7); // the size of one char
170 int xOffset
= chSize
.width();
171 int yOffset
= chSize
.height();
173 // calculate a better border so that the text is centered
174 int canvasWidth
= pixmapSize
.width() - 2 * xborder
;
175 int canvasHeight
= pixmapSize
.height() - 2 * yborder
;
176 int numCharsPerLine
= (int) (canvasWidth
/ chSize
.width());
177 int numLines
= (int) (canvasHeight
/ chSize
.height());
179 // render the information
181 int rest
= mPixmap
.width() - (numCharsPerLine
* chSize
.width());
182 xborder
= qMax( xborder
, rest
/ 2 ); // center horizontally
183 rest
= mPixmap
.height() - (numLines
* chSize
.height());
184 yborder
= qMax( yborder
, rest
/ 2 ); // center vertically
187 int x
= xborder
, y
= yborder
; // where to paint the characters
188 int posNewLine
= mPixmap
.width() - (chSize
.width() + xborder
);
189 int posLastLine
= mPixmap
.height() - (chSize
.height() + yborder
);
190 bool newLine
= false;
191 Q_ASSERT( posNewLine
> 0 );
192 //const QPixmap *fontPixmap = &(mSplitter->pixmap());
194 for ( int i
= 0; i
< text
.length(); i
++ ) {
195 if ( x
> posNewLine
|| newLine
) { // start a new line?
199 if ( y
> posLastLine
) // more text than space
202 // after starting a new line, we also jump to the next
203 // physical newline in the file if we don't come from one
205 int pos
= text
.indexOf( '\n', i
);
213 // check for newlines in the text (unix,dos)
214 QChar ch
= text
.at( i
);
218 } else if ( ch
== '\r' && text
.at(i
+1) == '\n' ) {
220 i
++; // skip the next character (\n) as well
224 rect
= glyphCoords( (unsigned char)ch
.toLatin1(), mFont
->width() );
226 if ( !rect.isEmpty() )
227 bitBlt( &mPixmap, QPoint(x,y), fontPixmap, rect, Qt::CopyROP );
230 x
+= xOffset
; // next character
236 bool VCard_LDIFCreator::createImageBig()
238 QFont
normalFont( KGlobalSettings::generalFont() );
239 QFont
titleFont( normalFont
);
240 titleFont
.setBold(true);
241 // titleFont.setUnderline(true);
242 titleFont
.setItalic(true);
244 QPainter
painter(&mPixmap
);
245 painter
.setFont(titleFont
);
246 QFontMetrics
fm(painter
.fontMetrics());
249 painter
.setClipRect(2, 2, pixmapSize
.width()-4, pixmapSize
.height()-4);
250 QPoint
p(5, fm
.height()+2);
251 painter
.drawText(p
, name
);
254 // draw contact information
255 painter
.setFont(normalFont
);
256 fm
= painter
.fontMetrics();
258 const QStringList
list( text
.split('\n', QString::SkipEmptyParts
) );
259 for ( QStringList::ConstIterator it
= list
.begin();
260 p
.y()<=pixmapSize
.height() && it
!= list
.end(); ++it
) {
261 p
.setY( p
.y() + fm
.height() );
262 painter
.drawText(p
, *it
);
268 bool VCard_LDIFCreator::create(const QString
&path
, int width
, int height
, QImage
&img
)
270 if ( !readContents(path
) )
273 // resize the image if necessary
274 pixmapSize
= QSize( width
, height
);
275 if (height
* 3 > width
* 4)
276 pixmapSize
.setHeight( width
* 4 / 3 );
278 pixmapSize
.setWidth( height
* 3 / 4 );
280 if ( pixmapSize
!= mPixmap
.size() )
281 mPixmap
= QPixmap( pixmapSize
);
283 mPixmap
.fill( QColor( 245, 245, 245 ) ); // light-grey background
285 // one pixel for the rectangle, the rest. whitespace
286 xborder
= 1 + pixmapSize
.width()/16; // minimum x-border
287 yborder
= 1 + pixmapSize
.height()/16; // minimum y-border
290 if ( width
>= 150 /*pixel*/ )
291 ok
= createImageBig();
293 ok
= createImageSmall();
297 img
= mPixmap
.toImage();
301 ThumbCreator::Flags
VCard_LDIFCreator::flags() const
303 return (Flags
)(DrawFrame
| BlendIcon
);