|
|
|
/*
|
|
|
|
This file is part of KAddressBook.
|
|
|
|
Copyright (C) 2003 Helge Deller <deller@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
version 2 License as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* - ldifvcardthumbnail -
|
|
|
|
*
|
|
|
|
* kioslave which generates tumbnails for vCard and LDIF files.
|
|
|
|
* The thumbnails are used e.g. by Konqueror or in the file selection
|
|
|
|
* dialog.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqdatetime.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kabc/ldifconverter.h>
|
|
|
|
#include <kabc/vcardconverter.h>
|
|
|
|
#include <kpixmapsplitter.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kglobalsettings.h>
|
|
|
|
|
|
|
|
#include "ldifvcardcreator.h"
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
ThumbCreator *new_creator()
|
|
|
|
{
|
|
|
|
KGlobal::locale()->insertCatalogue( "kaddressbook" );
|
|
|
|
return new VCard_LDIFCreator;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VCard_LDIFCreator::VCard_LDIFCreator()
|
|
|
|
: mSplitter( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VCard_LDIFCreator::~VCard_LDIFCreator()
|
|
|
|
{
|
|
|
|
delete mSplitter;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool VCard_LDIFCreator::readContents( const TQString &path )
|
|
|
|
{
|
|
|
|
// read file contents
|
|
|
|
TQFile file( path );
|
|
|
|
if ( !file.open( IO_ReadOnly ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQString info;
|
|
|
|
text.truncate(0);
|
|
|
|
|
|
|
|
// read the file
|
|
|
|
#if defined(KABC_VCARD_ENCODING_FIX)
|
|
|
|
const TQByteArray data = file.readAll();
|
|
|
|
const TQString contents( data );
|
|
|
|
const TQCString contentsRaw( data.data(), data.size() );
|
|
|
|
#else
|
|
|
|
TQString contents = file.readAll();
|
|
|
|
#endif
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
// convert the file contents to a KABC::Addressee address
|
|
|
|
KABC::AddresseeList addrList;
|
|
|
|
KABC::Addressee addr;
|
|
|
|
KABC::VCardConverter converter;
|
|
|
|
|
|
|
|
#if defined(KABC_VCARD_ENCODING_FIX)
|
|
|
|
addrList = converter.parseVCardsRaw( contentsRaw );
|
|
|
|
#else
|
|
|
|
addrList = converter.parseVCards( contents );
|
|
|
|
#endif
|
|
|
|
if ( addrList.count() == 0 )
|
|
|
|
if ( !KABC::LDIFConverter::LDIFToAddressee( contents, addrList ) )
|
|
|
|
return false;
|
|
|
|
if ( addrList.count()>1 ) {
|
|
|
|
// create an overview (list of all names)
|
|
|
|
name = i18n("One contact found:", "%n contacts found:", addrList.count());
|
|
|
|
unsigned int no, linenr;
|
|
|
|
for (linenr=no=0; linenr<30 && no<addrList.count(); ++no) {
|
|
|
|
addr = addrList[no];
|
|
|
|
info = addr.formattedName().simplifyWhiteSpace();
|
|
|
|
if (info.isEmpty())
|
|
|
|
info = addr.givenName() + " " + addr.familyName();
|
|
|
|
info = info.simplifyWhiteSpace();
|
|
|
|
if (info.isEmpty())
|
|
|
|
continue;
|
|
|
|
text.append(info);
|
|
|
|
text.append("\n");
|
|
|
|
++linenr;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// create card for _one_ contact
|
|
|
|
addr = addrList[ 0 ];
|
|
|
|
|
|
|
|
// prepare the text
|
|
|
|
name = addr.formattedName().simplifyWhiteSpace();
|
|
|
|
if ( name.isEmpty() )
|
|
|
|
name = addr.givenName() + " " + addr.familyName();
|
|
|
|
name = name.simplifyWhiteSpace();
|
|
|
|
|
|
|
|
|
|
|
|
KABC::PhoneNumber::List pnList = addr.phoneNumbers();
|
|
|
|
TQStringList phoneNumbers;
|
|
|
|
for (unsigned int no=0; no<pnList.count(); ++no) {
|
|
|
|
TQString pn = pnList[no].number().simplifyWhiteSpace();
|
|
|
|
if (!pn.isEmpty() && !phoneNumbers.contains(pn))
|
|
|
|
phoneNumbers.append(pn);
|
|
|
|
}
|
|
|
|
if ( !phoneNumbers.isEmpty() )
|
|
|
|
text += phoneNumbers.join("\n") + "\n";
|
|
|
|
|
|
|
|
info = addr.organization().simplifyWhiteSpace();
|
|
|
|
if ( !info.isEmpty() )
|
|
|
|
text += info + "\n";
|
|
|
|
|
|
|
|
// get an address
|
|
|
|
KABC::Address address = addr.address(KABC::Address::Work);
|
|
|
|
if (address.isEmpty())
|
|
|
|
address = addr.address(KABC::Address::Home);
|
|
|
|
if (address.isEmpty())
|
|
|
|
address = addr.address(KABC::Address::Pref);
|
|
|
|
info = address.formattedAddress();
|
|
|
|
if ( !info.isEmpty() )
|
|
|
|
text += info + "\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool VCard_LDIFCreator::createImageSmall()
|
|
|
|
{
|
|
|
|
text = name + "\n" + text;
|
|
|
|
|
|
|
|
if ( !mSplitter ) {
|
|
|
|
mSplitter = new KPixmapSplitter;
|
|
|
|
TQString pixmap = locate( "data", "konqueror/pics/thumbnailfont_7x4.png" );
|
|
|
|
if ( pixmap.isEmpty() ) {
|
|
|
|
delete mSplitter;
|
|
|
|
mSplitter=0;
|
|
|
|
kdWarning() << "VCard_LDIFCreator: Font image \"thumbnailfont_7x4.png\" not found!\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mSplitter->setPixmap( TQPixmap( pixmap ) );
|
|
|
|
mSplitter->setItemSize( TQSize( 4, 7 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize chSize = mSplitter->itemSize(); // the size of one char
|
|
|
|
int xOffset = chSize.width();
|
|
|
|
int yOffset = chSize.height();
|
|
|
|
|
|
|
|
// calculate a better border so that the text is centered
|
|
|
|
int canvasWidth = pixmapSize.width() - 2 * xborder;
|
|
|
|
int canvasHeight = pixmapSize.height() - 2 * yborder;
|
|
|
|
int numCharsPerLine = (int) (canvasWidth / chSize.width());
|
|
|
|
int numLines = (int) (canvasHeight / chSize.height());
|
|
|
|
|
|
|
|
// render the information
|
|
|
|
TQRect rect;
|
|
|
|
int rest = mPixmap.width() - (numCharsPerLine * chSize.width());
|
|
|
|
xborder = TQMAX( xborder, rest / 2 ); // center horizontally
|
|
|
|
rest = mPixmap.height() - (numLines * chSize.height());
|
|
|
|
yborder = TQMAX( yborder, rest / 2 ); // center vertically
|
|
|
|
// end centering
|
|
|
|
|
|
|
|
int x = xborder, y = yborder; // where to paint the characters
|
|
|
|
int posNewLine = mPixmap.width() - (chSize.width() + xborder);
|
|
|
|
int posLastLine = mPixmap.height() - (chSize.height() + yborder);
|
|
|
|
bool newLine = false;
|
|
|
|
Q_ASSERT( posNewLine > 0 );
|
|
|
|
const TQPixmap *fontPixmap = &(mSplitter->pixmap());
|
|
|
|
|
|
|
|
for ( uint i = 0; i < text.length(); i++ ) {
|
|
|
|
if ( x > posNewLine || newLine ) { // start a new line?
|
|
|
|
x = xborder;
|
|
|
|
y += yOffset;
|
|
|
|
|
|
|
|
if ( y > posLastLine ) // more text than space
|
|
|
|
break;
|
|
|
|
|
|
|
|
// after starting a new line, we also jump to the next
|
|
|
|
// physical newline in the file if we don't come from one
|
|
|
|
if ( !newLine ) {
|
|
|
|
int pos = text.find( '\n', i );
|
|
|
|
if ( pos > (int) i )
|
|
|
|
i = pos +1;
|
|
|
|
}
|
|
|
|
|
|
|
|
newLine = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for newlines in the text (unix,dos)
|
|
|
|
TQChar ch = text.at( i );
|
|
|
|
if ( ch == '\n' ) {
|
|
|
|
newLine = true;
|
|
|
|
continue;
|
|
|
|
} else if ( ch == '\r' && text.at(i+1) == '\n' ) {
|
|
|
|
newLine = true;
|
|
|
|
i++; // skip the next character (\n) as well
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rect = mSplitter->coordinates( ch );
|
|
|
|
if ( !rect.isEmpty() )
|
|
|
|
bitBlt( &mPixmap, TQPoint(x,y), fontPixmap, rect, TQt::CopyROP );
|
|
|
|
|
|
|
|
x += xOffset; // next character
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VCard_LDIFCreator::createImageBig()
|
|
|
|
{
|
|
|
|
TQFont normalFont( KGlobalSettings::generalFont() );
|
|
|
|
TQFont titleFont( normalFont );
|
|
|
|
titleFont.setBold(true);
|
|
|
|
// titleFont.setUnderline(true);
|
|
|
|
titleFont.setItalic(true);
|
|
|
|
|
|
|
|
TQPainter painter(&mPixmap);
|
|
|
|
painter.setFont(titleFont);
|
|
|
|
TQFontMetrics fm(painter.fontMetrics());
|
|
|
|
|
|
|
|
// draw contact name
|
|
|
|
painter.setClipRect(2, 2, pixmapSize.width()-4, pixmapSize.height()-4);
|
|
|
|
TQPoint p(5, fm.height()+2);
|
|
|
|
painter.drawText(p, name);
|
|
|
|
p.setY( 3*p.y()/2 );
|
|
|
|
|
|
|
|
// draw contact information
|
|
|
|
painter.setFont(normalFont);
|
|
|
|
fm = painter.fontMetrics();
|
|
|
|
|
|
|
|
const TQStringList list( TQStringList::split('\n', text) );
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin();
|
|
|
|
p.y()<=pixmapSize.height() && it != list.end(); ++it ) {
|
|
|
|
p.setY( p.y() + fm.height() );
|
|
|
|
painter.drawText(p, *it);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VCard_LDIFCreator::create(const TQString &path, int width, int height, TQImage &img)
|
|
|
|
{
|
|
|
|
if ( !readContents(path) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// resize the image if necessary
|
|
|
|
pixmapSize = TQSize( width, height );
|
|
|
|
if (height * 3 > width * 4)
|
|
|
|
pixmapSize.setHeight( width * 4 / 3 );
|
|
|
|
else
|
|
|
|
pixmapSize.setWidth( height * 3 / 4 );
|
|
|
|
|
|
|
|
if ( pixmapSize != mPixmap.size() )
|
|
|
|
mPixmap.resize( pixmapSize );
|
|
|
|
|
|
|
|
mPixmap.fill( TQColor( 245, 245, 245 ) ); // light-grey background
|
|
|
|
|
|
|
|
// one pixel for the rectangle, the rest. whitespace
|
|
|
|
xborder = 1 + pixmapSize.width()/16; // minimum x-border
|
|
|
|
yborder = 1 + pixmapSize.height()/16; // minimum y-border
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
if ( width >= 150 /*pixel*/ )
|
|
|
|
ok = createImageBig();
|
|
|
|
else
|
|
|
|
ok = createImageSmall();
|
|
|
|
if (!ok)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
img = mPixmap.convertToImage();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbCreator::Flags VCard_LDIFCreator::flags() const
|
|
|
|
{
|
|
|
|
return (Flags)(DrawFrame | BlendIcon);
|
|
|
|
}
|