kpilot Library API Documentation

knotes-conduit.cc

00001 /* knotes-conduit.cc                    KPilot
00002 **
00003 ** Copyright (C) 2000-2001 by Adriaan de Groot
00004 **
00005 ** This file is part of the KNotes conduit, a conduit for KPilot that
00006 ** synchronises the Pilot's memo pad application with KNotes.
00007 */
00008 
00009 /*
00010 ** This program is free software; you can redistribute it and/or modify
00011 ** it under the terms of the GNU General Public License as published by
00012 ** the Free Software Foundation; either version 2 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 ** GNU General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU General Public License
00021 ** along with this program in a file called COPYING; if not, write to
00022 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
00023 ** MA 02111-1307, USA.
00024 */
00025 
00026 /*
00027 ** Bug reports and questions can be sent to kde-pim@kde.org
00028 */
00029 
00030 
00031 #include "options.h"
00032 
00033 // Only include what we really need:
00034 // First UNIX system stuff, then std C++, 
00035 // then Qt, then KDE, then local includes.
00036 //
00037 //
00038 #ifndef QDIR_H
00039 #include <qdir.h>
00040 #endif
00041 
00042 #ifndef QMAP_H
00043 #include <qmap.h>
00044 #endif
00045 
00046 #ifndef _KGLOBAL_H
00047 #include <kglobal.h>
00048 #endif
00049 
00050 #ifndef _KSTDDIRS_H
00051 #include <kstddirs.h>
00052 #endif
00053 
00054 #ifndef _KMESSAGEBOX_H
00055 #include <kmessagebox.h>
00056 #endif
00057 
00058 #ifndef _KSIMPLECONFIG_H
00059 #include <ksimpleconfig.h>
00060 #endif
00061 
00062 #ifndef _KCONFIG_H
00063 #include <kconfig.h>
00064 #endif
00065 
00066 #ifndef _DCOPCLIENT_H
00067 #include <dcopclient.h>
00068 #endif
00069 
00070 #ifndef _KDEBUG_H
00071 #include <kdebug.h>
00072 #endif
00073 
00074 
00075 #ifndef _KPILOT_CONDUITAPP_H
00076 #include "conduitApp.h"
00077 #endif
00078 
00079 #ifndef _KPILOT_KPILOTCONFIG_H
00080 #include "kpilotConfig.h"
00081 #endif
00082 
00083 #ifndef _KPILOT_KNOTES_CONDUIT_H
00084 #include "knotes-conduit.h"
00085 #endif
00086 
00087 #ifndef _KPILOT_SETUPDIALOG_H
00088 #include "setupDialog.h"
00089 #endif
00090 
00091 #ifndef _KPILOT_PILOTMEMO_H
00092 #include "pilotMemo.h"
00093 #endif
00094 
00095 
00096 
00097 #ifndef _KPILOT_MD5WRAP_H
00098 #include        "md5wrap.h"
00099 #endif
00100 
00101 
00102 // Something to allow us to check what revision
00103 // the modules are that make up a binary distribution.
00104 //
00105 //
00106 static const char *knotes_conduit_id=
00107         "$Id: knotes-conduit.cc,v 1.20.6.6 2003/03/12 23:31:11 adridg Exp $";
00108 
00109 
00110 // This is a generic main() function, all
00111 // conduits look basically the same,
00112 // except for the name of the conduit.
00113 //
00114 //
00115 int main(int argc, char* argv[])
00116 {
00117         ConduitApp a(argc,argv,"knotes",
00118                 I18N_NOOP("KNotes Conduit"),
00119                 KPILOT_VERSION);
00120 
00121         a.addAuthor("Adriaan de Groot",
00122                 "KNotes Conduit author",
00123                 "adridg@sci.kun.nl");
00124 
00125         KNotesConduit conduit(a.getMode());
00126         a.setConduit(&conduit);
00127         return a.exec(true /* with DCOP support */);
00128 }
00129 
00130 
00131 NotesSettings::NotesSettings(const QString &configPath,
00132         const QString &notesdir,
00133         KConfig& c) :
00134         cP(configPath)
00135 {
00136         FUNCTIONSETUP;
00137 
00138 #ifdef DEBUG
00139         DEBUGCONDUIT << fname
00140                 << ": Reading note from "
00141                 << configPath
00142                 << " in dir "
00143                 << notesdir
00144                 << endl;
00145 #endif
00146 
00147         c.setGroup("KPilot");
00148         id = c.readNumEntry("pilotID",0);
00149         checksum = c.readEntry("checksum",QString::null);
00150         csValid = !(checksum.isNull());
00151 
00152         c.setGroup("Data");
00153         nN = c.readEntry("name");
00154 
00155         QString notedata(notesdir);
00156         notedata.append("/.");
00157         notedata.append(nN);
00158         notedata.append("_data");
00159         if (QFile::exists(notedata))
00160         {
00161 #ifdef DEBUG
00162                 DEBUGCONDUIT << fname 
00163                         << ": Data for note in " 
00164                         << notedata 
00165                         << endl;
00166 #endif
00167                 dP = notedata;
00168         }
00169         else
00170         {
00171                 kdWarning() << __FUNCTION__
00172                         << ": No data file for note?"
00173                         << " (tried "
00174                         << notedata << ")"
00175                         << endl;
00176         }
00177 }
00178 
00179 QString NotesSettings::computeCheckSum() const
00180 {
00181         FUNCTIONSETUP;
00182 
00183         if (dP.isEmpty()) return 0;
00184 
00185         QFile f(dP);
00186         if (!f.open(IO_ReadOnly))
00187         {
00188                 kdWarning() << __FUNCTION__
00189                         << ": Couldn't open file."
00190                         << endl;
00191                 return QString::null;
00192         }
00193 
00194         unsigned char data[PilotMemo::MAX_MEMO_LEN];
00195         int r = f.readBlock((char *)data,(int) PilotMemo::MAX_MEMO_LEN);
00196         if (r<1)
00197         {
00198                 kdWarning() << __FUNCTION__
00199                         << ": Couldn't read notes file."
00200                         << endl;
00201                 return QString::null;
00202         }
00203 
00204         QString s;
00205         MD5Context md5context;
00206         md5context.update(data,r);
00207         s=md5context.finalize();
00208 
00209         return s;
00210 }
00211 
00212 int NotesSettings::readNotesData(char *text)
00213 {
00214         FUNCTIONSETUP;
00215 
00216         // Check that the data can actually fit into a memo.
00217         // If it does, read it all.
00218         //
00219         QFile f(dataPath());
00220         int filesize = f.size();
00221 
00222         if (filesize > PilotMemo::MAX_MEMO_LEN) 
00223         {
00224                 kdWarning() << __FUNCTION__
00225                         << ": Notes file is too large ("
00226                         << filesize
00227                         << " bytes) -- truncated to "
00228                         << (int) PilotMemo::MAX_MEMO_LEN
00229                         << endl;
00230                 filesize = PilotMemo::MAX_MEMO_LEN;
00231         }
00232                 
00233         if (!f.open(IO_ReadOnly)) 
00234         {
00235                 kdWarning() << __FUNCTION__
00236                         << ": Couldn't read notes file."
00237                         << endl;
00238                 return 0;
00239         }
00240 
00241         memset(text,0,PilotMemo::MAX_MEMO_LEN+1);
00242         int len = f.readBlock(text,filesize);
00243 
00244 #ifdef DEBUG
00245         DEBUGCONDUIT << fname
00246                 << ": Read "
00247                 << len
00248                 << " bytes from note "
00249                 << dataPath()
00250                 << endl;
00251 #endif
00252 
00253         return len;
00254 }
00255 
00256 static NotesMap
00257 collectNotes()
00258 {
00259         FUNCTIONSETUP;
00260         NotesMap m;
00261 
00262         // This is code taken directly from KNotes
00263         //
00264         //
00265         QString str_notedir = KGlobal::dirs()->
00266                 saveLocation( "appdata", "notes/" );
00267 
00268 #ifdef DEBUG
00269         {
00270                 DEBUGCONDUIT << fname << ": Notes dir = " << str_notedir << endl;
00271         }
00272 #endif
00273 
00274         QDir notedir( str_notedir );
00275         QStringList notes = notedir.entryList( QDir::Files, QDir::Name );
00276         QStringList::ConstIterator  i;
00277 
00278         for (i=notes.begin() ; i !=notes.end(); ++i)
00279         {
00280                 QString notename,notedata ;
00281                 KSimpleConfig *c = 0L;
00282                 int version ;
00283 
00284 #ifdef DEBUG
00285                 {
00286                         DEBUGCONDUIT << fname << ": Reading note " << *i << endl;
00287                 }
00288 #endif
00289                 c = new KSimpleConfig( notedir.absFilePath(*i));
00290                 
00291                 c->setGroup("General");
00292                 version = c->readNumEntry("version",1);
00293                 if (version<2)
00294                 {
00295                         kdWarning() << __FUNCTION__
00296                                 << ": Skipping old-style KNote"
00297                                 << *i
00298                                 << endl;
00299                         goto EndNote;
00300                 }
00301 
00302                 {
00303                 NotesSettings n(notedir.absFilePath(*i),
00304                         notedir.absPath(),
00305                         *c);
00306                 m.insert(*i,n);
00307                 }
00308 
00309 EndNote:
00310                 delete c;
00311         }
00312 
00313         return m;
00314 }
00315 
00316 
00317 static NotesMap::Iterator *
00318 findID(NotesMap& m,unsigned long id)
00319 {
00320         FUNCTIONSETUP;
00321 
00322         NotesMap::Iterator *i = new NotesMap::Iterator;
00323 
00324         for ((*i)=m.begin(); (*i)!=m.end(); ++(*i))
00325         {
00326                 const NotesSettings& r = (*(*i));
00327 
00328                 if (r.pilotID()==id)
00329                 {
00330 #ifdef DEBUG
00331                         {
00332                                 DEBUGCONDUIT << fname
00333                                         << ": Found ID "
00334                                         << id
00335                                         << " in note "
00336                                         << r.configPath()
00337                                         << endl;
00338                         }
00339 #endif
00340                         return i;
00341                 }
00342         }
00343 
00344         delete i;
00345 
00346 #ifdef DEBUG
00347         {
00348                 DEBUGCONDUIT << fname
00349                         << ": ID "
00350                         << id
00351                         << " not found."
00352                         << endl;
00353         }
00354 #endif
00355                 
00356         return 0L;
00357 }
00358 
00359 
00360 
00361 KNotesConduit::KNotesConduit(eConduitMode mode) : 
00362         BaseConduit(mode),
00363         fDeleteNoteForMemo(false)
00364 {
00365         FUNCTIONSETUP;
00366 #ifdef DEBUG
00367         DEBUGCONDUIT<<knotes_conduit_id<<endl;
00368 #endif
00369 
00370 }
00371 
00372 KNotesConduit::~KNotesConduit()
00373 {
00374         FUNCTIONSETUP;
00375 
00376 }
00377 
00378 void
00379 KNotesConduit::readConfig()
00380 {
00381         FUNCTIONSETUP;
00382 
00383         KConfig& c = KPilotConfig::getConfig(KNotesOptions::KNotesGroup);
00384         getDebugLevel(c);
00385         fDeleteNoteForMemo = c.readBoolEntry("DeleteNoteForMemo",false);
00386 #ifdef DEBUG
00387         {
00388                 DEBUGCONDUIT << fname
00389                         << ": Settings "
00390                         << "DeleteNoteForMemo="
00391                         << fDeleteNoteForMemo
00392                         << endl;
00393         }
00394 #endif
00395 }
00396 
00397 void
00398 KNotesConduit::doSync()
00399 {
00400         FUNCTIONSETUP;
00401 
00402         readConfig();
00403 
00404         NotesMap m = collectNotes();
00405 
00406         // First add all the new KNotes to the Pilot
00407         //
00408         //
00409         int newCount = notesToPilot(m);
00410         int oldCount = pilotToNotes(m);
00411 
00412         if (newCount || oldCount)
00413         {
00414                 QString msg = i18n("Changed %1/%2 Memos/Notes")
00415                         .arg(newCount)
00416                         .arg(oldCount);
00417                 addSyncLogMessage(msg);
00418 
00419 #ifdef DEBUG
00420                 DEBUGCONDUIT << fname
00421                         << ": "
00422                         << msg
00423                         << endl;
00424 #endif
00425         }
00426 
00427         DCOPClient *dcopptr = KApplication::kApplication()->dcopClient();
00428         if (!dcopptr)
00429         {
00430                 kdWarning() << __FUNCTION__
00431                         << ": Can't get DCOP client."
00432                         << endl;
00433                 return;
00434         }
00435 
00436         QByteArray data;
00437         if (dcopptr -> send("knotes",
00438                 "KNotesIface",
00439                 "rereadNotesDir()",
00440                 data))
00441         {
00442                 kdWarning() << __FUNCTION__
00443                         << ": Couldn't tell KNotes to re-read notes."
00444                         << endl;
00445         }
00446 }
00447 
00448 
00449 bool KNotesConduit::addNewNote(NotesSettings& s)
00450 {
00451         FUNCTIONSETUP;
00452 
00453         // We know that this is a new memo (no pilot id)
00454         char text[PilotMemo::MAX_MEMO_LEN+1];
00455         if (!s.readNotesData(text))
00456         {
00457                 return false;
00458         }
00459 
00460         PilotMemo *memo = new PilotMemo(text,0,0,0);
00461         PilotRecord *rec = memo->pack();
00462         unsigned long id = writeRecord(rec);
00463 
00464         KSimpleConfig *c = new KSimpleConfig(s.configPath());
00465         c->setGroup("KPilot");
00466         c->writeEntry("pilotID",id);
00467         c->writeEntry("checksum",s.computeCheckSum());
00468 
00469         s.setId(id);
00470 
00471         delete c;
00472         delete rec;
00473         delete memo;
00474 
00475         return true;
00476 }
00477 
00478 bool KNotesConduit::changeNote(NotesSettings& s)
00479 {
00480         FUNCTIONSETUP;
00481 
00482         char text[PilotMemo::MAX_MEMO_LEN+1];
00483         if (!s.readNotesData(text))
00484         {
00485                 return false;
00486         }
00487 
00488         return false;
00489 }
00490 
00491 
00492 int KNotesConduit::notesToPilot(NotesMap& m)
00493 {
00494         FUNCTIONSETUP;
00495         NotesMap::Iterator i;
00496         int count=0;
00497 
00498 #ifdef DEBUG
00499         DEBUGCONDUIT << fname
00500                 << ": Adding new memos to pilot"
00501                 << endl;
00502 #endif
00503 
00504 
00505         for (i=m.begin(); i!=m.end(); ++i)
00506         {
00507                 NotesSettings& s=(*i);
00508 
00509                 if (s.isNew()) 
00510                 {
00511                         addNewNote(s);
00512                         count++;
00513                 }
00514                 if (s.isChanged()) 
00515                 {
00516                         changeNote(s);
00517                         count++;
00518                 }
00519         }
00520 
00521         return count;
00522 }
00523 
00524 bool KNotesConduit::newMemo(NotesMap& m,unsigned long id,PilotMemo *memo)
00525 {
00526         FUNCTIONSETUP;
00527 
00528         QString noteName = memo->sensibleTitle();
00529 
00530         // This is code taken directly from KNotes
00531         //
00532         //
00533         QString str_notedir = KGlobal::dirs()->
00534                 saveLocation( "appdata", "notes/" );
00535 
00536 #ifdef DEBUG
00537         {
00538                 DEBUGCONDUIT << fname << ": Notes dir = " << str_notedir << endl;
00539         }
00540 #endif
00541 
00542         QDir notedir( str_notedir );
00543 
00544         if (notedir.exists(noteName))
00545         {
00546                 noteName += QString::number(id);
00547         }
00548 
00549         if (notedir.exists(noteName))
00550         {
00551 #ifdef DEBUG
00552                 DEBUGCONDUIT << fname
00553                         << ": Note " << noteName
00554                         << " already exists!"
00555                         << endl;
00556 #endif
00557                 return false;
00558         }
00559 
00560         QString dataName = "." + noteName + "_data" ;
00561         bool success = false;
00562 #ifdef DEBUG
00563         {
00564                 DEBUGCONDUIT << fname
00565                         << ": Creating note "
00566                         << noteName
00567                         << endl;
00568         }
00569 #endif
00570 
00571         {
00572         QFile file(notedir.absFilePath(dataName));
00573         file.open(IO_WriteOnly | IO_Truncate);
00574         if (file.isOpen())
00575         {
00576                 file.writeBlock(memo->text(),strlen(memo->text()));
00577                 success = true;
00578         }
00579         file.close();
00580         }
00581 
00582         // Write out the KNotes config file 
00583         if (success)
00584         {
00585         KConfig *c = new KSimpleConfig( notedir.absFilePath(noteName));
00586         
00587         c->setGroup("General");
00588         c->writeEntry("version",2);
00589         c->setGroup("KPilot");
00590         c->writeEntry("pilotID",id);
00591         c->setGroup("Data");
00592         c->writeEntry("name",noteName);
00593         c->sync();
00594 
00595         delete c;
00596         }
00597 
00598         if (success)
00599         {
00600                 NotesSettings n(noteName,
00601                         notedir.absFilePath(noteName),
00602                         notedir.absFilePath(dataName),
00603                         id);
00604                 m.insert(noteName,n);
00605         }
00606 
00607         return success;
00608 }
00609 
00610 bool KNotesConduit::changeMemo(NotesMap& m,NotesMap::Iterator i,PilotMemo *memo)
00611 {
00612         FUNCTIONSETUP;
00613 
00614 
00615 // handle deleted memos (deleted on the pilot) here.
00616 // since they're just copies of what's in knotes,
00617 // delete the files.
00618 
00619         (void) m;
00620         NotesSettings n = *i;
00621 #ifdef DEBUG
00622         {
00623                 DEBUGCONDUIT << fname
00624                         << ": Updating note "
00625                         << n.configPath()
00626                         << endl;
00627         }
00628 #endif
00629         QFile file(n.dataPath());
00630         file.open(IO_WriteOnly | IO_Truncate);
00631         if (file.isOpen())
00632         {
00633                 file.writeBlock(memo->text(),strlen(memo->text()));
00634 #ifdef DEBUG
00635                 {
00636                         DEBUGCONDUIT << fname
00637                                 << ": Succesfully updated memo "
00638                                 << n.configPath()
00639                                 << endl;
00640                 }
00641 #endif
00642 
00643                 return true;
00644         }
00645         else
00646         {
00647                 return false;
00648         }
00649 }
00650 
00651 bool KNotesConduit::deleteNote(NotesMap& m,NotesMap::Iterator *i,
00652         unsigned long id)
00653 {
00654         FUNCTIONSETUP;
00655 
00656         if (!i)
00657         {
00658 #ifdef DEBUG
00659                 {
00660                         DEBUGCONDUIT << fname
00661                                 << ": Unknown Pilot memo "
00662                                 << id
00663                                 << " has been deleted."
00664                                 << endl;
00665                 }
00666 #endif
00667                 return false;
00668         }
00669 
00670 #ifdef DEBUG
00671         {
00672                 if (fDeleteNoteForMemo)
00673                 {
00674                         DEBUGCONDUIT << fname
00675                                 << ": Deleting pilot memo "
00676                                 << id
00677                                 << endl;
00678                 }
00679                 else
00680                 {
00681                         DEBUGCONDUIT << fname
00682                                 << ": Pilot memo "
00683                                 << id
00684                                 << " has been deleted, note remains."
00685                                 << endl;
00686                         return false;
00687                 }
00688         }
00689 #endif
00690 
00691         NotesSettings n = *(*i);
00692 
00693 #ifdef DEBUG
00694         {
00695                 DEBUGCONDUIT << fname
00696                         << ": Deleting note "
00697                         << n.configPath()
00698                         << endl;
00699         }
00700 #endif
00701 
00702         QFile::remove(n.dataPath());
00703         QFile::remove(n.configPath());
00704 
00705         m.remove(*i);
00706 
00707         return true;
00708 }
00709 
00710 
00711 int KNotesConduit::pilotToNotes(NotesMap& m)
00712 {
00713         FUNCTIONSETUP;
00714 
00715         PilotRecord *rec;
00716         int count=0;
00717         NotesMap::Iterator *i;
00718 
00719         while ((rec=readNextModifiedRecord()))
00720         {
00721                 unsigned long id = rec->getID();
00722                 bool success;
00723 
00724                 success=false;
00725 
00726 #ifdef DEBUG
00727                 DEBUGCONDUIT << fname 
00728                         << ": Read Pilot record with ID "
00729                         << id
00730                         << endl;
00731 #endif
00732 
00733                 i = findID(m,id);
00734                 if (rec->getAttrib() & dlpRecAttrDeleted)
00735                 {
00736                         success=deleteNote(m,i,id);
00737                 }
00738                 else
00739                 {
00740                         PilotMemo *memo = new PilotMemo(rec);
00741                         if (i)
00742                         {
00743                                 success=changeMemo(m,*i,memo);
00744                         }
00745                         else
00746                         {
00747                                 success=newMemo(m,id,memo);
00748                         }
00749                         delete memo;
00750                 }
00751                 delete rec;
00752 
00753                 if (success) 
00754                 { 
00755                         count++;
00756                 }
00757         }
00758 
00759 // we also need to tell knotes that things have changed in the dirs it owns
00760         DCOPClient *dcopptr = KApplication::kApplication()->dcopClient();
00761         if (!dcopptr)
00762         {
00763                 kdWarning() << __FUNCTION__
00764                         << ": Can't get DCOP client."
00765                         << endl;
00766                 return count;
00767         }
00768 
00769         QByteArray data;
00770         if (dcopptr -> send("knotes",
00771                 "KNotesIface",
00772                 "rereadNotesDir()",
00773                 data))
00774         {
00775 #ifdef DEBUG
00776                 DEBUGCONDUIT << fname
00777                         << ": DCOP to KNotes successful."
00778                         << endl;
00779 #endif
00780         }
00781         else
00782         {
00783                 kdWarning() << __FUNCTION__
00784                         << ": Couldn't tell KNotes about new notes."
00785                         << endl;
00786         }
00787 
00788         return count;
00789 }
00790 
00791 // aboutAndSetup is pretty much the same
00792 // on all conduits as well.
00793 //
00794 //
00795 QWidget*
00796 KNotesConduit::aboutAndSetup()
00797 {
00798         FUNCTIONSETUP;
00799 
00800         return new KNotesOptions(0L);
00801 }
00802 
00803 const char *
00804 KNotesConduit::dbInfo()
00805 {
00806         return "MemoDB";
00807 }
00808 
00809 
00810 
00811 /* virtual */ void
00812 KNotesConduit::doTest()
00813 {
00814         FUNCTIONSETUP;
00815         DCOPClient *dcopptr = KApplication::kApplication()->dcopClient();
00816         if (!dcopptr)
00817         {
00818                 kdWarning() << __FUNCTION__
00819                         << ": Can't get DCOP client."
00820                         << endl;
00821                 return;
00822         }
00823 
00824         NotesMap m = collectNotes();
00825 
00826 
00827         NotesMap::Iterator i;
00828         for (i=m.begin(); i!=m.end(); ++i)
00829         {
00830                 if ((*i).pilotID())
00831                 {
00832 #ifdef DEBUG
00833                         DEBUGCONDUIT << fname
00834                                 << ": Showing note " 
00835                                 << (*i).name()
00836                                 << endl;
00837 #endif
00838 
00839                         QByteArray data;
00840                         QDataStream arg(data,IO_WriteOnly);
00841                         arg << (*i).name() ;
00842                         if (dcopptr -> send("knotes",
00843                                 "KNotesIface",
00844                                 "showNote(QString)",
00845                                 data))
00846                         {
00847 #ifdef DEBUG
00848                                 DEBUGCONDUIT << fname
00849                                         << ": DCOP send successful"
00850                                         << endl;
00851 #endif
00852                         }
00853                         else
00854                         {
00855                                 kdWarning() << __FUNCTION__
00856                                         << ": DCOP send failed."
00857                                         << endl;
00858                         }
00859                 }
00860                 else
00861                 {
00862 #ifdef DEBUG
00863                         DEBUGCONDUIT << fname
00864                                 << ": Note "
00865                                 << (*i).name()
00866                                 << " not in Pilot"
00867                                 << endl;
00868 #endif
00869                 }
00870 #ifdef DEBUG
00871                 DEBUGCONDUIT << fname
00872                         << ": Checksum = "
00873                         << (*i).computeCheckSum()
00874                         << endl;
00875 #endif
00876         }
00877 
00878         (void) knotes_conduit_id;
00879 }
00880 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sat Oct 18 02:47:14 2003 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001