You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kword/KWMailMergeDataBase.cpp

560 lines
17 KiB

/* This file is part of the KDE project
Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
Modified by Joseph wenninger, 2001
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 "KWDocument.h"
#include "KWMailMergeDataBase.h"
#include "KWMailMergeDataBase.moc"
#include <KoCustomVariablesDia.h>
#include "defs.h"
#include <tdelocale.h>
#include <kdebug.h>
#include <kstdaction.h>
#include <tdeaction.h>
#include <tdemessagebox.h>
#include <kseparator.h>
#include <kservice.h>
#include <tdemainwindow.h>
#include <tqfile.h>
#include <tqvbox.h>
#include <tqspinbox.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
/******************************************************************
*
* Class: KWMailMergeDataBase
*
******************************************************************/
KWMailMergeDataBase::KWMailMergeDataBase( KWDocument *doc_ )
: TQObject(doc_,doc_->dcopObject()->objId()+".MailMergeDataBase"),
KWordMailMergeDatabaseIface(TQCString(doc_->dcopObject()->objId()+".MailMergeDataBase")),
m_version(0),
doc( doc_ )
{
plugin=0; //loadPlugin("classic");
rejectdcopcall=false;
}
TQStringList KWMailMergeDataBase::availablePlugins()
{
TQStringList tmp;
TDETrader::OfferList pluginOffers=TDETrader::self()->query(TQString::fromLatin1("KWord/MailMergePlugin"),TQString());
for (TDETrader::OfferList::Iterator it=pluginOffers.begin();*it;++it)
{
tmp.append((*it)->property("X-TDE-InternalName").toString());
kdDebug()<<"Found mail merge plugin: "<< (*it)->name()<<endl;
}
return tmp;
}
bool KWMailMergeDataBase::isConfigDialogShown()
{
return rejectdcopcall;
}
bool KWMailMergeDataBase::loadPlugin(const TQString &name,const TQString &command)
{
if (rejectdcopcall)return false;
TQString constrain=TQString("[X-TDE-InternalName] =='"+name+"'");
kdDebug()<<constrain<<endl;
TDETrader::OfferList pluginOffers=TDETrader::self()->query(TQString::fromLatin1("KWord/MailMergePlugin"),constrain);
KService::Ptr it=pluginOffers.first();
TQVariant verProp=it->property("X-TDE-PluginVersion");
int version=verProp.toInt();
if (it)
{
KWMailMergeDataSource *tmp=loadPlugin(it->library());
if (!tmp)
{
kdDebug()<<"Couldn't load plugin"<<endl;
return false; //Plugin couldn't be loaded
}
//Plugin found and loaded
if (command=="silent") {
return askUserForConfirmationAndConfig(tmp,false,0,version);
}
else
{
if (command=="open") action=KWSLOpen;
else if (command=="create") action=KWSLCreate;
else action=KWSLUnspecified;
return askUserForConfirmationAndConfig(tmp,true,0,version);
}
}
else
{
kdDebug()<<"No plugin found"<<endl;
return false; //No plugin with specified name found
}
}
KWMailMergeDataSource *KWMailMergeDataBase::openPluginFor(int type,int &version)
{
version=0;
KWMailMergeDataSource *ret=0;
TQString constrain=TQString("'%1' in [X-TDE-Capabilities]").arg(((type==KWSLCreate)?KWSLCreate_text:KWSLOpen_text));
kdDebug()<<constrain<<endl;
TDETrader::OfferList pluginOffers=TDETrader::self()->query(TQString::fromLatin1("KWord/MailMergePlugin"),constrain);
//Only for debugging
for (TDETrader::OfferList::Iterator it=pluginOffers.begin();*it;++it)
{
kdDebug()<<"Found mail merge plugin: "<< (*it)->name()<<endl;
}
if (!pluginOffers.count())
{
//Sorry no suitable plugins found
kdDebug()<<"No plugins found"<<endl;
KMessageBox::sorry(0,i18n("No plugins supporting the requested action were found."));
}
else
{
KWMailMergeChoosePluginDialog *dia=new KWMailMergeChoosePluginDialog(pluginOffers);
if (dia->exec()==TQDialog::Accepted)
{
TQVariant verProp=(*(pluginOffers.at(dia->currentPlugin())))->property("X-TDE-PluginVersion");
version=verProp.toInt();
ret=loadPlugin((*(pluginOffers.at(dia->currentPlugin())))->library());
}
}
return ret;
}
KWMailMergeDataSource *KWMailMergeDataBase::loadPlugin(const TQString& name)
{
if (!name.isEmpty())
{
// get the library loader instance
KLibLoader *loader = KLibLoader::self();
// try to load the library
TQString libname=name;
// TQString libname("lib%1");
KLibrary *lib = loader->library(TQFile::encodeName(libname));
if (lib) {
// get the create_ function
TQString factory=TQString("create_%1").arg(name);
void *create = lib->symbol(TQFile::encodeName(factory));
if (create)
{
// create the module
KWMailMergeDataSource * (*func)(TDEInstance*,TQObject*);
func = (KWMailMergeDataSource* (*)(TDEInstance*,TQObject*)) create;
KWMailMergeDataSource *tmpsource =func(KWFactory::instance(),this);
if (tmpsource)
{
TQDataStream tmpstream(tmpsource->info,IO_WriteOnly);
tmpstream<<name;
}
return tmpsource;
}
}
kdWarning() << "Couldn't load plugin " << name << endl;
}
else
kdWarning()<< "No plugin name specified" <<endl;
return 0;
}
bool KWMailMergeDataBase::isSampleRecord() {
return (0>doc->mailMergeRecord());
}
TQString KWMailMergeDataBase::getValue( const TQString &name, int record ) const
{
if (plugin)
{
if (record==-1) record=doc->mailMergeRecord();
return plugin->getValue(name,record);
}
else
return TQString("");
}
void KWMailMergeDataBase::refresh(bool force)
{
if (plugin) plugin->refresh(force);
}
const TQMap< TQString, TQString > &KWMailMergeDataBase::getRecordEntries() const
{
if (plugin)
return plugin->getRecordEntries();
else
return emptyMap;
}
int KWMailMergeDataBase::getNumRecords() const
{
if (plugin)
return plugin->getNumRecords();
else
return 0;
}
void KWMailMergeDataBase::showConfigDialog(TQWidget *par)
{
rejectdcopcall=true;
KWMailMergeConfigDialog *dia=new KWMailMergeConfigDialog(par,this);
dia->exec();
delete dia;
rejectdcopcall=false;
}
bool KWMailMergeDataBase::askUserForConfirmationAndConfig(KWMailMergeDataSource *tmpPlugin,bool config,TQWidget *par,int version)
{
if (tmpPlugin)
{
bool replaceit=false;
if (!config) replaceit=true;
else
replaceit=tmpPlugin->showConfigDialog(par,action);
if (replaceit)
{
if (plugin)
{
if (KMessageBox::warningContinueCancel(par,
i18n("Do you really want to replace the current datasource?"),
TQString(),TQString(),TQString(),true)== KMessageBox::Cancel)
{
delete tmpPlugin;
tmpPlugin=0;
return false;
}
delete plugin;
}
m_version=version;
plugin=tmpPlugin;
}
else
{
delete tmpPlugin;
tmpPlugin=0;
return false;
}
}
tmpPlugin->setObjId(TQCString(objId()+".MailMergePlugin"));
return true;
}
TQDomElement KWMailMergeDataBase::save(TQDomDocument &doc) const
{
kdDebug()<<"KWMailMergeDataBase::save()"<<endl;
TQDomElement parentElem=doc.createElement("MAILMERGE");
if (plugin)
{
kdDebug()<<"KWMailMergeDataBase::save() There is really something to save"<<endl;
TQDomElement el=doc.createElement(TQString::fromLatin1("PLUGIN"));
TQDataStream ds(plugin->info,IO_ReadOnly);
TQString libname;
ds>>libname;
el.setAttribute("library",libname);
parentElem.appendChild(el);
kdDebug()<<"KWMailMergeDataBase::save() Calling datasource save()"<<endl;
TQDomElement el2=doc.createElement(TQString::fromLatin1("DATASOURCE"));
plugin->save(doc,el2);
parentElem.appendChild(el2);
}
kdDebug()<<"KWMailMergeDataBase::save() leaving now"<<endl;
return parentElem;
// if (plugin) plugin->save(parentElem); // Not completely sure, perhaps the database itself has to save something too (JoWenn)
}
void KWMailMergeDataBase::load( const TQDomElement& parentElem )
{
TQDomNode dn=parentElem.namedItem("PLUGIN");
if (dn.isNull()) return;
TQDomElement el=dn.toElement();
plugin=loadPlugin(el.attribute("library"));
dn=parentElem.namedItem("DATASOURCE");
if (dn.isNull()) return;
el=dn.toElement();
if (plugin) plugin->load(el);
}
int KWMailMergeDataBase::version() {
kdDebug()<<"KWMailMergeDataBase::version:"<<m_version<<endl;
return m_version;
}
/******************************************************************
*
* Class: KWMailMerge ChoosePluginDialog
*
******************************************************************/
KWMailMergeChoosePluginDialog::KWMailMergeChoosePluginDialog( TDETrader::OfferList offers )
: KDialogBase( Plain, i18n( "Mail Merge Setup" ), Ok | Cancel, Ok,
/*parent*/ 0, "", true ), pluginOffers( offers )
{
TQWidget *back = plainPage();
TQVBoxLayout *layout = new TQVBoxLayout( back, 0, spacingHint() );
TQLabel *label = new TQLabel( i18n( "&Available sources:" ), back );
chooser = new TQComboBox( false, back );
label->setBuddy( chooser );
descriptionLabel = new TQLabel( back );
descriptionLabel->hide();
descriptionLabel->setAlignment( WordBreak );
descriptionLabel->setFrameShape( TQFrame::Box );
descriptionLabel->setFrameShadow( TQFrame::Sunken );
TQSize old_sizeHint;
for ( TDETrader::OfferList::Iterator it = pluginOffers.begin(); *it; ++it )
{
chooser->insertItem( (*it)->name() );
old_sizeHint = descriptionLabel->sizeHint();
descriptionLabel->setText( (*it)->comment() );
if (descriptionLabel->sizeHint().width()*descriptionLabel->sizeHint().height() > old_sizeHint.width()*old_sizeHint.height())
descriptionLabel->setMinimumSize(descriptionLabel->sizeHint() );
}
descriptionLabel->show();
connect( chooser, TQT_SIGNAL( activated( int ) ),
this, TQT_SLOT( pluginChanged( int ) ) );
layout->addWidget( label );
layout->addWidget( chooser );
layout->addWidget( descriptionLabel );
layout->addStretch( 1 );
pluginChanged( 0 );
}
KWMailMergeChoosePluginDialog::~KWMailMergeChoosePluginDialog()
{
}
int KWMailMergeChoosePluginDialog::currentPlugin() const
{
return chooser->currentItem();
}
void KWMailMergeChoosePluginDialog::pluginChanged( int pos )
{
descriptionLabel->setText( (*pluginOffers.at( pos ))->comment() );
}
/******************************************************************
*
* Class: KWMailMergeConfigDialog
*
******************************************************************/
KWMailMergeConfigDialog::KWMailMergeConfigDialog(TQWidget *parent,KWMailMergeDataBase *db)
: KDialogBase(Plain, i18n( "Mail Merge Setup" ), Close, Close, parent, "", true )
{
db_=db;
TQWidget *back = plainPage();
TQVBoxLayout *layout=new TQVBoxLayout(back);
// TQVBox *back = new TQVBox( page );
layout->setSpacing( KDialog::spacingHint() );
// TQVBox *row1 = new TQVBox( back );
// row1->setSpacing( KDialog::spacingHint() );
TQLabel *l = new TQLabel( i18n( "Datasource:" ),back );
// l->setMaximumHeight( l->sizeHint().height() );
layout->addWidget(l);
TQHBox *row1=new TQHBox(back);
layout->addWidget(row1);
row1->setSpacing( KDialog::spacingHint() );
edit=new TQPushButton(i18n("Edit Current..."),row1);
create=new TQPushButton(i18n("Create New..."),row1);
open=new TQPushButton(i18n("Open Existing..."),row1);
KSeparator *separator1 = new KSeparator(back);
layout->addWidget(separator1);
l = new TQLabel( i18n( "Merging:" ),back );
layout->addWidget(l);
// l->setMaximumHeight( l->sizeHint().height() );
TQHBox *row2=new TQHBox(back);
layout->addWidget(row2);
row2->setSpacing( KDialog::spacingHint() );
preview=new TQPushButton(i18n("Print Preview..."),row2);
document=new TQPushButton(i18n("Create New Document"),row2);
document->hide();
(void) new TQWidget(row2);
layout->addStretch();
KSeparator *separator2 = new KSeparator(back);
layout->addWidget(separator2);
enableDisableEdit();
connect(edit,TQT_SIGNAL(clicked()), this, TQT_SLOT(slotEditClicked()));
connect(create,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotCreateClicked()));
connect(open,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotOpenClicked()));
connect(preview,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotPreviewClicked()));
connect(document,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotDocumentClicked()));
}
void KWMailMergeConfigDialog::enableDisableEdit()
{
if (!db_->plugin)
{
preview->setEnabled(false);
document->setEnabled(false);
edit->setEnabled(false);
}
else
{
preview->setEnabled(true);
document->setEnabled(true);
edit->setEnabled(true);
}
}
void KWMailMergeConfigDialog::slotEditClicked()
{db_->action=KWSLEdit;
if (db_->plugin) db_->plugin->showConfigDialog((TQWidget*)parent(),KWSLEdit);
}
void KWMailMergeConfigDialog::slotCreateClicked()
{
db_->action=KWSLCreate;
doNewActions();
//done(TQDialog::Accepted);
}
void KWMailMergeConfigDialog::doNewActions()
{
int tmpVersion;
KWMailMergeDataSource *tmpPlugin=db_->openPluginFor(db_->action,tmpVersion);
if (tmpPlugin)
{
if (db_->askUserForConfirmationAndConfig(tmpPlugin,true,this,tmpVersion))
enableDisableEdit();
}
}
void KWMailMergeConfigDialog::slotOpenClicked()
{
db_->action=KWSLOpen;
doNewActions();
}
void KWMailMergeConfigDialog::slotPreviewClicked()
{
db_->action=KWSLMergePreview;
TDEMainWindow *mw=dynamic_cast<TDEMainWindow*>(((TQWidget *)parent())->topLevelWidget());
if (mw)
{
TDEAction *ac=mw->actionCollection()->action(KStdAction::stdName(KStdAction::PrintPreview));
if (ac) ac->activate();
else kdWarning()<<"Toplevel doesn't provide a print preview action"<<endl;
}
else
kdWarning()<<"Toplevel is no TDEMainWindow->no preview"<<endl;
}
void KWMailMergeConfigDialog::slotDocumentClicked()
{
db_->action=KWSLMergeDocument;
done(TQDialog::Accepted);
}
KWMailMergeConfigDialog::~KWMailMergeConfigDialog()
{
}
/******************************************************************
*
* Class: KWMailMergeVariableInsertDia
*
******************************************************************/
KWMailMergeVariableInsertDia::KWMailMergeVariableInsertDia( TQWidget *parent, KWMailMergeDataBase *db )
: KDialogBase( Plain, i18n( "Mail Merge - Variable Name" ),
Ok | Cancel, Ok, parent, "", true )
{
m_db=db;
TQWidget *page = plainPage();
TQVBoxLayout *layout = new TQVBoxLayout( page, marginHint(), spacingHint() );
layout->setAutoAdd( true );
TQLabel *l = new TQLabel( i18n( "Name:" ), page );
l->setMaximumHeight( l->sizeHint().height() );
names = new TQListBox( page );
TQMap< TQString, TQString >::ConstIterator it = db->getRecordEntries().begin();
for ( ; it != db->getRecordEntries().end(); ++it )
names->insertItem( m_db->version() ?it.data():it.key(), -1 );
setInitialSize( TQSize( 350, 400 ) );
connect( names, TQT_SIGNAL( selectionChanged() ),
this, TQT_SLOT( slotSelectionChanged() ) );
connect( names, TQT_SIGNAL( doubleClicked( TQListBoxItem* ) ),
this, TQT_SLOT( slotOk() ) );
setFocus();
enableButtonOK( names->currentItem() != -1 );
}
void KWMailMergeVariableInsertDia::slotSelectionChanged()
{
enableButtonOK( names->currentItem() != -1 );
}
TQString KWMailMergeVariableInsertDia::getName() const
{
if (m_db->version()>=1) {
TQString description=names->text(names->currentItem());
TQMap< TQString, TQString >::ConstIterator it = m_db->getRecordEntries().begin();
for ( ; it != m_db->getRecordEntries().end(); ++it )
if (description==it.data()) {
return it.key();
}
Q_ASSERT(0);
return ""; // can't happen
}
else
return names->text( names->currentItem() );
}