From 4f99f868f09bbffa2e15733b8b7c78eba07a199e Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 6 Dec 2020 21:23:48 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- kab/CMakeLists.txt | 2 +- kab/ChangeLog | 2 +- kab/Makefile.am | 6 +- kab/addressbook.cc | 2040 ----------------------------------------- kab/addressbook.cpp | 2040 +++++++++++++++++++++++++++++++++++++++++ kab/kabapi.cc | 220 ----- kab/kabapi.cpp | 220 +++++ kab/qconfigDB.cc | 2547 --------------------------------------------------- kab/qconfigDB.cpp | 2547 +++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 4812 insertions(+), 4812 deletions(-) delete mode 100644 kab/addressbook.cc create mode 100644 kab/addressbook.cpp delete mode 100644 kab/kabapi.cc create mode 100644 kab/kabapi.cpp delete mode 100644 kab/qconfigDB.cc create mode 100644 kab/qconfigDB.cpp (limited to 'kab') diff --git a/kab/CMakeLists.txt b/kab/CMakeLists.txt index 76c781467..a4e881466 100644 --- a/kab/CMakeLists.txt +++ b/kab/CMakeLists.txt @@ -27,7 +27,7 @@ link_directories( set( target kab ) set( ${target}_SRCS - kabapi.cc addressbook.cc qconfigDB.cc + kabapi.cpp addressbook.cpp qconfigDB.cpp ) tde_add_library( ${target} STATIC_PIC AUTOMOC diff --git a/kab/ChangeLog b/kab/ChangeLog index d3e36fcc1..51715a70d 100644 --- a/kab/ChangeLog +++ b/kab/ChangeLog @@ -11,7 +11,7 @@ Tue Dec 22 22:56:58 1998 Mirko Boehm * businesscard.h (class BusinessCard): Hopefully remove trigraph. - * datepickerdialog.cc (DateLabel): Removed default value + * datepickerdialog.cpp (DateLabel): Removed default value in the implementation. * keyvaluemap.h: Removed a default value for a function diff --git a/kab/Makefile.am b/kab/Makefile.am index 89e1aab8e..66018aed5 100644 --- a/kab/Makefile.am +++ b/kab/Makefile.am @@ -5,9 +5,9 @@ KABVERSION= 4.0.0 KABPATCH= 0 libkab_la_SOURCES = \ - kabapi.cc \ - addressbook.cc \ - qconfigDB.cc + kabapi.cpp \ + addressbook.cpp \ + qconfigDB.cpp libkab_la_LDFLAGS = $(KDE_MT_LDFLAGS) -no-undefined libkab_la_LIBADD = ../tdeui/libtdeui.la diff --git a/kab/addressbook.cc b/kab/addressbook.cc deleted file mode 100644 index 017621ac7..000000000 --- a/kab/addressbook.cc +++ /dev/null @@ -1,2040 +0,0 @@ -/* - This file implements the basic personal information management class - used in the TDE addressbook. - - the TDE addressbook - - $ Author: Mirko Boehm $ - $ Copyright: (C) 1996-2001, Mirko Boehm $ - $ Contact: mirko@kde.org - http://www.kde.org $ - $ License: GPL with the following explicit clarification: - This code may be linked against any version of the Qt toolkit - from Troll Tech, Norway. $ - - $Id$ -*/ - -#include "addressbook.h" -#include "qconfigDB.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -extern "C" { -#include -#include -#include -#include -} - -// ----- some defines: -#ifdef KAB_KDEBUG_AREA -#undef KAB_KDEBUG_AREA -#endif - -#define KAB_KDEBUG_AREA 800 - -#ifdef STD_USERFILENAME -#undef STD_USERFILENAME -#endif -#define STD_USERFILENAME "kab/addressbook.kab" - -#ifdef STD_CONFIGFILENAME -#undef STD_CONFIGFILENAME -#endif -#define STD_CONFIGFILENAME "kab/kab.config" - -#ifdef ENTRY_SECTION -#undef ENTRY_SECTION -#endif -#define ENTRY_SECTION "entries" - -// the name of the file-local configuration section -#ifdef LOCAL_CONFIG_SECTION -#undef LOCAL_CONFIG_SECTION -#endif -#define LOCAL_CONFIG_SECTION "config" - -// the name of the subsection for each entry -#ifdef ADDRESS_SUBSECTION -#undef ADDRESS_SUBSECTION -#endif -#define ADDRESS_SUBSECTION "addresses" - -#ifdef KAB_TEMPLATEFILE -#undef KAB_TEMPLATEFILE -#endif -#define KAB_TEMPLATEFILE "kab/template.kab" - -#ifdef KAB_CONFIGTEMPLATE -#undef KAB_CONFIGTEMPLATE -#endif -#define KAB_CONFIGTEMPLATE "kab/template.config" - -#ifdef KAB_CATEGORY_KEY -#undef KAB_CATEGORY_KEY -#endif -#define KAB_CATEGORY_KEY "categories" - -const char* AddressBook::Entry::Address::Fields[]= { - "headline", "position", - "org", "orgunit", "orgsubunit", - "deliverylabel", "address", "zip", "town", "country", "state" }; -const int AddressBook::Entry::Address::NoOfFields -=sizeof(AddressBook::Entry::Address::Fields) -/sizeof(AddressBook::Entry::Address::Fields[0]); - -const char* AddressBook::Entry::Fields[]= { - "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname", - "birthday", "comment", "talk", "emails", "keywords", "telephone", - "urls", "user1", "user2", "user3", "user4", "custom", "categories" }; -const int AddressBook::Entry::NoOfFields -=sizeof(AddressBook::Entry::Fields)/sizeof(AddressBook::Entry::Fields[0]); - -struct QStringLess - : public binary_function -{ - /** The function operator, inline. */ - bool operator()(const TQString& x, const TQString& y) const - { - return x < y; // make one Qt operator fit exactly - } -}; - -// ----- the derived map class: -class StringKabKeyMap : public map -{ /* Same as map, but a class for compilation reasons. This way we do not need - * to include the QStringLess class into the addressbook header file. */ -}; - -// ----- another derived map class: -class KeyNameMap : public map > -{ // same thing -}; - -KeyNameMap* AddressBook::Entry::fields; -KeyNameMap* AddressBook::Entry::Address::fields; - -bool -KabKey::operator == (const KabKey& key) const -{ - // ########################################################################### - return key.getKey()==getKey(); - // ########################################################################### -} - -void -KabKey::setKey(const TQCString& text) -{ - // ########################################################################### - key=text; - // ########################################################################### -} - -TQCString -KabKey::getKey() const -{ - // ########################################################################### - return key; - // ########################################################################### -} - - - -AddressBook::Entry::Address::Address() -{ -} - -bool AddressBook::Entry::Address::nameOfField(const char* key, TQString& value) -{ - KeyNameMap::iterator pos; - // ----- - if(fields==0) - { // this is executed exactly one time per application instance, - // as fields is static - int counter=0; - fields=new KeyNameMap; - TQ_CHECK_PTR(fields); - if(!fields->insert - (map >::value_type - (Fields[counter++], i18n("Headline"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Position"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Organization"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Department"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Sub-Department"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Delivery Label"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("street/postal","Address"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Zipcode"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("City"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Country"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("As in addresses", "State"))).second) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::Address::nameOfField (while " - << " creating field-name map): TYPO, correct this." - << endl; - } else { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::Address::nameOfField: " - << "inserted field names." << endl; - } -#if ! defined NDEBUG - TQString name; - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::Address::nameOfField:" << endl - << "Created key-fieldname-map. Defined fields are:" - << endl; - for(counter=0; counterfind(Fields[counter]); - if(pos==fields->end()) - { - kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl; - } else { - kdDebug(KAB_KDEBUG_AREA) - << " " << Fields[counter] << " (" - << (*pos).second.utf8() << ")" << endl; - } - } -#endif - } - // ----- now finally do the lookup: - pos=fields->find(key); - if(pos==fields->end()) - { - return false; - } else { - value=(*pos).second; - return true; - } -} - -bool AddressBook::Entry::nameOfField(const char* key, TQString& value) -{ - KeyNameMap::iterator pos; - // ----- - if(fields==0) - { // this is executed exactly one time per application instance, - // as fields is static - int counter=0; - fields=new KeyNameMap; - TQ_CHECK_PTR(fields); - if(!fields->insert - (map >::value_type - (Fields[counter++], i18n("person","Title"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Rank"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Formatted Name"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Name Prefix"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("First Name"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Middle Name"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Last Name"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Birthday"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Comment"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Talk Addresses"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Email Addresses"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Keywords"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Telephone Number"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("URLs"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("User Field 1"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("User Field 2"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("User Field 3"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("User Field 4"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Custom"))).second - || - !fields->insert - (map >::value_type - (Fields[counter++], i18n("Categories"))).second) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::Address::nameOfField (while " - << " creating field-name map): TYPO, correct this." << endl; - } else { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::Address::nameOfField: " - << "inserted field names." << endl; - } -#if ! defined NDEBUG - TQString name; - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::Entry::nameOfField:" << endl - << "Created key-fieldname-map. Defined fields are:" << endl; - for(counter=0; counterfind(Fields[counter]); - if(pos==fields->end()) - { - kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl; - } else { - kdDebug(KAB_KDEBUG_AREA) - << " " << Fields[counter] << " (" - << (*pos).second.utf8() << ")" << endl; - } - } -#endif - } - // ----- now finally do the lookup: - pos=fields->find(key); - if(pos==fields->end()) - { - return false; - } else { - value=(*pos).second; - return true; - } -} - -AddressBook::ErrorCode -AddressBook::Entry::getAddress(int index, Address& address) const -{ - // ########################################################################### - list
::const_iterator pos; - // ----- - if(index>=0 && (unsigned)indexquit(); // It is critical, but will possibly never happen. - } - connect(data, TQT_SIGNAL(fileChanged()), TQT_SLOT(dataFileChanged())); - connect(data, TQT_SIGNAL(changed(QConfigDB*)), - TQT_SLOT(reloaded(QConfigDB*))); - connect(config, TQT_SIGNAL(fileChanged()), TQT_SLOT(configFileChanged())); - // ----- set style: - - filename = locate( "data", STD_CONFIGFILENAME); - if (filename.isEmpty()) - { - filename = locateLocal( "data", STD_CONFIGFILENAME ); - // config does not exist yet - if(createConfigFile()!=NoError) - { - KMessageBox::sorry(this, - i18n("Your local kab configuration file " - "\"%1\" " - "could not be created. kab will probably not " - "work correctly without it.\n" - "Make sure you have not removed write permission " - "from your local TDE directory (usually ~/.trinity).").arg(filename)); - state=PermDenied; - } - } - loadConfigFile(); - // ----- now get some configuration settings: - if(config->get("config", keys)) - { - keys->get("CreateBackupOnStartup", createBackup); - } - // ----- check and possibly create user standard file: - filename = locate( "data", STD_USERFILENAME ); - - if(filename.isEmpty()) // if it does not exist - { - filename = locateLocal( "data", STD_USERFILENAME); - if(createNew(filename)!=NoError) // ...and we cannot create it - { - KMessageBox::sorry(this, - i18n("Your standard kab database file " - "\"%1\" " - "could not be created. kab will probably not " - "work correctly without it.\n" - "Make sure you have not removed write permission " - "from your local TDE directory (usually ~/.trinity).").arg(filename)); - state=PermDenied; - } else { - KMessageBox::information - (this, - i18n("kab has created your standard addressbook in\n\"%1\"") - .arg(filename)); - } - } - // ----- load the user standard file: - if(loadit) - { - if(load(filename)!=NoError) - { // ----- the standard file could not be loaded - state=PermDenied; - } else { - if(createBackup) - { - // ----- create the backup file: - TQString temp=data->fileName(); - if(data->setFileName(temp+".backup", false, false)) - { - if(!data->save()) - { - KMessageBox::information - (this, - i18n("Cannot create backup file (permission denied)."), - i18n("File Error")); - } - } else { - KMessageBox::error - (this, - i18n("Cannot open backup file for " - "writing (permission denied)."), - i18n("File Error")); - } - // ----- reset the filename: - if(!data->setFileName(temp, true, true)) - { - KMessageBox::error - (this, - i18n("Critical error:\n" - "Permissions changed in local directory!"), - i18n("File Error")); - closeFile(false); - state=PermDenied; - } else { - state=NoError; - } - } - } - } - // ----- - data->watch(true); - // ########################################################################### -} - -AddressBook::~AddressBook() -{ - // ########################################################################### - delete data; - delete config; - delete entries; - // ########################################################################### -} - -QConfigDB* AddressBook::getConfig() -{ - // ########################################################################### - return config; - // ########################################################################### -} - -AddressBook::ErrorCode AddressBook::getState() -{ - // ########################################################################### - return state; - // ########################################################################### -} - -AddressBook::ErrorCode AddressBook::load(const TQString& filename) -{ - // ----- Remark: Close the file if it could not be loaded! - // ########################################################################### - ErrorCode rc=NoError; - TQFileInfo newfile, oldfile; - // ----- - TQString fname = (filename.isEmpty()) ? data->fileName() : filename ; - if(fname.isEmpty()) // there was never a filename set: - { - state=NoFile; - return NoFile; - } - // ----- - newfile.setFile(fname); - oldfile.setFile(data->fileName()); - if(isSameFile(fname, data->fileName())) - { // ----- possibly deleted file: - if(data->load()) - { - emit(setStatus(i18n("File reloaded."))); - state=NoError; - } else { - switch - (KMessageBox::questionYesNo - (this, - i18n("The currently loaded file " - "\"%1\" " - "cannot be reloaded. kab may close or save it.\n" - "Save it if you accidentally deleted your data file.\n" - "Close it if you intended to do so.\n" - "Your file will be closed by default.") - .arg(oldfile.absFilePath()), - i18n("File Error"), - KStdGuiItem::close(), KStdGuiItem::save())) - { - case KMessageBox::No: // save - if(!data->save(i18n("(Safety copy on file error)").ascii(), true)) - { - KMessageBox::information(this, - i18n("Cannot save the file; will close it now."), - i18n("File Error")); - closeFile(false); - state=NoFile; - rc=PermDenied; - } else { - state=NoError; - rc=NoError; - } - break; // no error if we could save the file - default: // close - closeFile(false); - state=NoFile; - rc=NoSuchFile; - break; - } - } - } else { // ----- set new filename - if(data->setFileName(fname, true, true)) - { - if(data->load()) - { - emit(changed()); - emit(setStatus(i18n("File opened."))); - state=NoError; - } else { - KMessageBox::information(this, - i18n("Could not load the file."), - i18n("File Error")); - closeFile(false); - emit(setStatus(i18n("No such file."))); - rc=NoSuchFile; - } - } else { - if(KMessageBox::questionYesNo - (this, - i18n("The file \"%1\" cannot be found. " - "Create a new one?").arg(fname), - i18n("No Such File"), - i18n("Create"), KStdGuiItem::cancel())==KMessageBox::Yes) - { - if(createNew(fname)==NoError) - { - emit(setStatus(i18n("New file."))); - } else { // ----- do not close here, stick with the old file: - emit(setStatus(i18n("Canceled."))); - } - } - } - } - // ----- - if(rc==NoError) - { - data->watch(true); - updateMirrorMap(); - } - // ----- - return rc; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getListOfNames(TQStringList* strings, bool reverse, bool initials) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getListOfNames: called.\n"; - StringKabKeyMap::iterator pos; - TQString desc; - ErrorCode rc=NoError; - ErrorCode temp; - // ----- erase the list contents: - strings->clear(); - // ----- ...and fill it: - for(pos=entries->begin(); pos!=entries->end(); ++pos) - { - temp=literalName((*pos).second, desc, reverse, initials); - if(temp!=AddressBook::NoError) - { - desc=i18n("(Internal error in kab)"); - rc=InternError; - } - if(desc.isEmpty()) - { - desc=i18n("(empty entry)"); - } - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "AddressBook::getListOfNames: adding " << desc << endl; - strings->append(desc); - } - // ----- any problems? - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::getListOfNames: done, " - << strings->count() - << " entries.\n"; - return rc; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::literalName(const KabKey& key, TQString& text, bool rev, bool init) -{ - // ########################################################################### - Entry entry; - ErrorCode rc; - // ----- get the entry: - rc=getEntry(key, entry); - if(rc!=NoError) - { - return rc; - } - // ----- - return literalName(entry, text, rev, init); - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::literalName(const Entry& entry, TQString& text, bool rev, bool init) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: called.\n"; - TQString firstname, middlename, lastname, nameprefix; - // ----- is the formatted name set? - if(!entry.fn.isEmpty()) - { - text=entry.fn; - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "AddressBook::literalName: done (fn).\n"; - return NoError; - } - // ----- prepare the strings: - firstname=entry.firstname.simplifyWhiteSpace(); - middlename=entry.middlename.simplifyWhiteSpace(); - lastname=entry.lastname.simplifyWhiteSpace(); - nameprefix=entry.nameprefix.simplifyWhiteSpace(); - // ----- create the initials: - if(init) - { - if(!firstname.isEmpty()) firstname=firstname.mid(0, 1)+'.'; - if(!middlename.isEmpty()) middlename=middlename.mid(0, 1)+'.'; - // if(!lastname.isEmpty()) lastname=lastname.mid(0, 1)+'.'; - } - // ----- assemble the string: - text=""; - if(rev) - { // name, firstname - add. name - name prefix - if(!lastname.isEmpty()) - { - text=lastname; - } - if(!firstname.isEmpty() || !middlename.isEmpty() || !nameprefix.isEmpty()) - { - text+=','; - } - if(!firstname.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=firstname; - } - if(!middlename.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=middlename; - } - if(!nameprefix.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=nameprefix; - } - } else { - // firstname - add. name - name prefix - name - text=firstname; - if(!middlename.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=middlename; - } - if(!nameprefix.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=nameprefix; - } - if(!lastname.isEmpty()) - { - if(!text.isEmpty()) - { - text+=' '; - } - text+=lastname; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: done: " - << text << ".\n"; - return NoError; - // ########################################################################### -} - -unsigned int -AddressBook::noOfEntries() -{ - // ########################################################################### - return entries->size(); - // ########################################################################### -} - -void -AddressBook::dataFileChanged() -{ - // ########################################################################### - data->watch(false); // will be restarted after successful load - load(); - // ########################################################################### -} - -void -AddressBook::configFileChanged() -{ - bool GUARD; GUARD=true; - // ########################################################################### - if(!config->load()) - { - KMessageBox::error(this, - i18n("Cannot reload configuration file!"), - i18n("File Error")); - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::configFileChanged: " - "config file reloaded.\n"; - emit(setStatus(i18n("Configuration file reloaded."))); - } - // ########################################################################### -} - -void -AddressBook::reloaded(QConfigDB* db) -{ - bool GUARD; GUARD=false; - // ########################################################################### - if(db==data) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::reloaded: file has been " - "reloaded.\n"; - updateMirrorMap(); // WORK_TO_DO: what's up with the return value? - changed(); - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::save(const TQString& filename, bool force) -{ - // ########################################################################### - if(filename.isEmpty()) - { - if(data->save(0, force)) - { - emit(setStatus(i18n("File saved."))); - return NoError; - } else { - return PermDenied; - } - } else { - if(data->setFileName(filename, false, false)) - { - if(data->save(0, true)) - { - emit(newFile(filename)); - return NoError; - } else { - return PermDenied; - } - } else { - return PermDenied; - } - } - // ########################################################################### -} - -bool -AddressBook::isSameFile(const TQString& a, const TQString& b) -{ - // ########################################################################### - TQFileInfo filea(a), fileb(b); - // ----- - return filea.absFilePath()==fileb.absFilePath(); - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::closeFile(bool saveit) -{ - // ########################################################################### - if(saveit) - { - if(save()!=NoError) - { - emit(setStatus(i18n("Permission denied."))); - return PermDenied; - } - } - data->clear(); - // data->reset(); WORK_TO_DO: File name is not reset by now. - emit(setStatus(i18n("File closed."))); - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getEntry(const KabKey& key, Entry& entry) -{ - // ########################################################################### - Section *section; - // ----- - if(getEntry(key, section)==NoError) - { - return makeEntryFromSection(section, entry); - } else { - return NoSuchEntry; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getEntry(const KabKey& key, Section*& section) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getEntry: searching entry " - "with key " << key.getKey().data() << endl; - StringKabKeyMap::iterator pos; - // ----- - for(pos=entries->begin(); pos!=entries->end(); ++pos) - { - if((*pos).second==key) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "AddressBook::getEntry: key exists." << endl; - break; - } - } - if(pos==entries->end()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "AddressBook::getEntry: no such entry.\n"; - return NoSuchEntry; - } else { - if(data->get((TQCString)ENTRY_SECTION+'/'+key.getKey(), section)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "AddressBook::getEntry: done." << endl; - return NoError; - } else { - return InternError; - } - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getEntries(list& thelist) -{ - // ########################################################################### - StringKabKeyMap::iterator pos; - Entry entry; - ErrorCode rc; - // ----- - kdDebug(!thelist.empty(), KAB_KDEBUG_AREA) - << "AddressBook::getEntries: warning - non-empty value list!" << endl; - thelist.erase(thelist.begin(), thelist.end()); - for(pos=entries->begin(); pos!=entries->end(); ++pos) - { - rc=getEntry((*pos).second, entry); - if(rc==NoError) - { - thelist.push_back(entry); - } else { - return InternError; - } - } - // ----- - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getKey(int index, KabKey& key) -{ - // ########################################################################### - StringKabKeyMap::iterator pos; - // ----- - if((unsigned)indexsize()) - { - pos=entries->begin(); - advance(pos, index); - key=(*pos).second; - return NoError; - } else { - return NoSuchEntry; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::getIndex(const KabKey& key, int& index) -{ - bool GUARD; GUARD=true; - // ########################################################################### - StringKabKeyMap::iterator pos; - // ----- - index=0; - for(pos=entries->begin(); pos!=entries->end(); ++pos) - { - // kdDebug(KAB_KDEBUG_AREA) << (*pos).second.getKey().data() << " <--> " << - // key.getKey().data() << endl; - if((*pos).second==key) break; - ++index; - } - kdDebug(pos==entries->end(), KAB_KDEBUG_AREA) << - "AddressBook::getIndex: no such key." << endl; - if(pos==entries->end()) - { - return NoSuchEntry; - } else { - return NoError; - } - // ########################################################################### -} - -Section* -AddressBook::entrySection() -{ - // ########################################################################### - Section* section; - // ----- - if(!data->get(ENTRY_SECTION, section)) - { - return 0; - } else { - return section; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::add(const Entry& entry, KabKey& key, bool update) -{ - bool GUARD; GUARD=true; - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: called." << endl; - // ########################################################################### - Section* theEntries=entrySection(); - Section* newEntry; - KabKey nextKey; - ErrorCode locked; - ErrorCode rc; - // ----- - if(theEntries==0) - { - kdDebug(KAB_KDEBUG_AREA) << "AddressBook::add: no entries section." - << endl; - return NoFile; - } - newEntry=new Section; - if(newEntry==0) - { - KMessageBox::error(this, - i18n("Cannot initialize local variables."), - i18n("Out of Memory")); - kapp->quit(); // It is critical, but will possibly never happen. - return InternError; // shut the compiler up... - } - // ----- lock the file: - locked=lock(); - switch(locked) - { - case PermDenied: - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::add: permission denied." << endl; - return PermDenied; // cannot get r/w mode - case Locked: - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::add: db is already in r/w mode." << endl; - break; - case NoError: - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::add: got writing permissions." << endl; - break; - default: - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::add: unknown response, exiting." << endl; - return InternError; - } - // ----- - if(makeSectionFromEntry(entry, *newEntry)==NoError) - { - nextKey=nextAvailEntryKey(); - if(!theEntries->add(nextKey.getKey(), newEntry)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::add: Cannot insert section.\n"; - rc=InternError; - } else { - key=nextKey; - emit(changed()); - rc=NoError; - } - if(update) updateMirrorMap(); - } else { - rc=InternError; - } - if(locked!=Locked) - { // ----- unlock the file here: - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::add: dropped writing permissions." << endl; - locked=unlock(); - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: done." << endl; - if(locked!=NoError) - { - return locked; - } - if(rc!=NoError) - { - return rc; - } - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::change(const KabKey& key, const Entry& entry) -{ - // ########################################################################### - Section* theEntries=entrySection(); - Section* oldEntry; - ErrorCode locked; - ErrorCode rc; - // ----- - if(theEntries==0) - { - return NoFile; - } - // ----- lock the file: - locked=lock(); - if(locked==PermDenied) - { - return PermDenied; // cannot get r/w mode - } - // ----- - if(!theEntries->find(key.getKey(), oldEntry)) - { - rc=NoSuchEntry; - } else { - oldEntry->clear(); - rc=makeSectionFromEntry(entry, *oldEntry); - emit(changed()); - } - // ----- - if(locked!=PermDenied) - { // ----- unlock the file here: - locked=unlock(); - } - if(locked==NoError) - { - return rc; - } else { - return locked; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::remove(const KabKey& key) -{ - // ########################################################################### - Section *theEntries=entrySection(); - ErrorCode locked; - ErrorCode rc; - // ----- - if(theEntries==0) - { - return NoFile; - } - // ----- lock the file: - locked=lock(); - if(locked==PermDenied) - { - return PermDenied; // cannot get r/w mode - } - // ----- - if(theEntries->remove(key.getKey())) - { - rc=NoError; - emit(changed()); - } else { - rc=NoSuchEntry; - } - // ----- - if(locked!=PermDenied) - { // ----- unlock the file here: - locked=unlock(); - } - if(locked==NoError) - { - return rc; - } else { - return locked; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::lock() -{ - // ########################################################################### - if(!data->isRO()) return Locked; - if(data->setFileName(data->fileName(), false, false)) - { - return NoError; - } else { - KMessageBox::information(this, - i18n("The file you wanted to change could not be locked.\n" - "It is probably in use by another application or read-only."), - i18n("File Error")); - return PermDenied; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::unlock() -{ - // ########################################################################### - if(data->isRO()) return PermDenied; - if(data->setFileName(data->fileName(), true, true)) - { - return NoError; - } else { - return InternError; - } - // ########################################################################### -} - -KabKey -AddressBook::nextAvailEntryKey() -{ - // ########################################################################### - int max=0; - int temp; - Section::StringSectionMap::iterator pos; - Section *section=entrySection(); - KabKey key; - TQCString dummy; - bool good=true; - // ----- - if(section!=0) - { - for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos) - { - temp=0; - temp=(*pos).first.toInt(&good); - if(!good) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::nextAvailEntryKey: non-integer entry " - << endl; - } - if(temp>max) - { - max=temp; - } - } - } - // ----- - dummy.setNum(++max); - key.setKey(dummy); - // CHECK(key.getKey().toInt(&good)==max); - return key; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::updateMirrorMap() -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) - << "AddressBook::updateMirrorMap: updating mirror map.\n"; - TQString key; - Entry entry; - ErrorCode ec; - KabKey kk; - Section *section=entrySection(); - Section::StringSectionMap::iterator pos; - // ----- - entries->erase(entries->begin(), entries->end()); - if(section==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done, " - "no file loaded." << endl; - return NoError; - } - for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos) - { - if(makeEntryFromSection((*pos).second, entry)!=NoError) - { - // return InternError; // it is saver to continue without a key - } - key=""; - ec=literalName(entry, key, true, false); - if(key.isEmpty() || ec!=NoError) - { - key=i18n("(empty entry)"); - } - key+=(*pos).first; // append the section name to make the key unique - kk.setKey((*pos).first); - entries->insert(StringKabKeyMap::value_type(key, kk)); - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done." - << endl; - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::makeEntryFromSection(Section* section, Entry& entry) -{ - // ########################################################################### - Section *addresses; - Section *addressSection; - Section::StringSectionMap::iterator pos; - KeyValueMap *keys; - Entry temp; - Entry::Address address; - Entry::Address addressDummy; - int count; - // ----- create the aggregats: - const TQCString StringKeys[]= { - "title", - "rank", - "fn", - "nameprefix", - "firstname", - "middlename", - "lastname", - "comment", - "user1", - "user2", - "user3", - "user4" - }; - TQString* StringValues[]= { - &temp.title, - &temp.rank, - &temp.fn, - &temp.nameprefix, - &temp.firstname, - &temp.middlename, - &temp.lastname, - &temp.comment, - &temp.user1, - &temp.user2, - &temp.user3, - &temp.user4 - }; - const int StringKeySize=sizeof(StringKeys)/sizeof(StringKeys[0]); - const TQCString StringListKeys[]= { - "talk", - "emails", - "keywords", - "telephone", - "URLs", - "custom", - "categories" - }; - TQStringList* StringListValues[]= { - &temp.talk, - &temp.emails, - &temp.keywords, - &temp.telephone, - &temp.URLs, - &temp.custom, - &temp.categories - }; - const int StringListKeySize=sizeof(StringListKeys)/sizeof(StringListKeys[0]); - // ----- first parse "addresses" subsection: - if(!section->find(ADDRESS_SUBSECTION, addresses)) - { - return InternError; // no subsection called "addresses" - } - for(pos=addresses->sectionsBegin(); pos!=addresses->sectionsEnd(); ++pos) - { - if(!addresses->find((*pos).first, addressSection)) - { - return InternError; // no section we have an iterator for? - } - keys=addressSection->getKeys(); - address=addressDummy; // clean it up - if(makeAddressFromMap(keys, address)==AddressBook::NoError) - { - // ----- add the address to the list of addresses: - temp.addresses.push_back(address); - } else { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeEntryFromSection: cannot find all fields " - << "in an address subsection." << endl; - } - } - // ----- now parse all other fields directly: - keys=section->getKeys(); - for(count=0; countget(StringKeys[count], *StringValues[count])) - { - /* Spits out lots of warnings: - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeEntryFromSection: error: could not get " - << "value for key " << (const char*)StringKeys[count] - << "." << endl; - */ - } - } - for(count=0; countget(StringListKeys[count], *StringListValues[count])) - { - /* Spits out lots of warnings: - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeEntryFromSection: error: could not get " - << "value for key " << (const char*)StringListKeys[count] - << "." << endl; - */ - } - } - // ----- finally get the birthday: - keys->get("birthday", temp.birthday); // this may return false (no date) - // ----- - entry=temp; - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::makeAddressFromMap(KeyValueMap* keys, Entry::Address& address) -{ - // ########################################################################### - const TQCString Keys[]= { - "headline", - "position", - "org", - "orgunit", - "orgsubunit", - // "role", - "deliverylabel", - "address", - "zip", - "town", - "country", - "state" - }; - TQString* strings[]= { - &address.headline, - &address.position, - &address.org, - &address.orgUnit, - &address.orgSubUnit, - // &address.role, - &address.deliveryLabel, - &address.address, - &address.zip, - &address.town, - &address.country, - &address.state - }; - const int Size=sizeof(Keys)/sizeof(Keys[0]); - int count; - // ----- - for(count=0; countget(Keys[count], *strings[count]); - } - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::makeSectionFromEntry(const Entry& entry, Section& section) -{ - // ########################################################################### - list::const_iterator addPos; - Section *addresses=0; - Section *address=0; - TQCString key; // used for creating address subsection keys - int count=0; // counts the addresses - KeyValueMap *keys; - // ----- prepare the section object: - section.clear(); - // ----- first create "addresses" subsection: - if(!section.add(ADDRESS_SUBSECTION)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeSectionFromEntry: cannot create " << "subsection." - << " " << endl; - return InternError; - } - if(!section.find(ADDRESS_SUBSECTION, addresses)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeSectionFromEntry: cannot get new section." << endl; - return InternError; - } - // ----- now insert addresses: - for(addPos=entry.addresses.begin(); addPos!=entry.addresses.end(); ++addPos) - { - ++count; - key.setNum(count); - if(!addresses->add(key)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeSectionFromEntry: cannot create address " << endl; - return InternError; - } - if(!addresses->find(key, address)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeSectionFromEntry: cannot get new " << endl; - return InternError; - } - keys=address->getKeys(); - // ----- now insert keys into address: - if(!keys->insert("headline", (*addPos).headline) || - !keys->insert("position", (*addPos).position) || - !keys->insert("org", (*addPos).org) || - !keys->insert("orgunit", (*addPos).orgUnit) || - !keys->insert("orgsubunit", (*addPos).orgSubUnit) || - // !keys->insert("role", (*addPos).role) || - !keys->insert("deliverylabel", (*addPos).deliveryLabel) || - !keys->insert("address", (*addPos).address) || - !keys->insert("zip", (*addPos).zip) || - !keys->insert("town", (*addPos).town) || - !keys->insert("country", (*addPos).country) || - !keys->insert("state", (*addPos).state)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeSectionFromEntry: cannot completely " - << "insert this address." << endl; - return InternError; - } - } - // ----- now add the other fields: - keys=section.getKeys(); - if(!keys->insert("title", entry.title) || - !keys->insert("rank", entry.rank) || - !keys->insert("fn", entry.fn) || - !keys->insert("nameprefix", entry.nameprefix) || - !keys->insert("firstname", entry.firstname) || - !keys->insert("middlename", entry.middlename) || - !keys->insert("lastname", entry.lastname) || - !keys->insert("birthday", entry.birthday) || - !keys->insert("comment", entry.comment) || - !keys->insert("talk", entry.talk) || - !keys->insert("emails", entry.emails) || - !keys->insert("keywords", entry.keywords) || - !keys->insert("telephone", entry.telephone) || - !keys->insert("URLs", entry.URLs) || - !keys->insert("user1", entry.user1) || - !keys->insert("user2", entry.user2) || - !keys->insert("user3", entry.user3) || - !keys->insert("user4", entry.user4) || - !keys->insert("custom", entry.custom) || - !keys->insert("categories", entry.categories)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::makeEntryFromSection: cannot insert " - << "all fields of the entry." << endl; - return InternError; - } - // ----- - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::createNew(const TQString& filename) -{ - // ########################################################################### - const TQString KabTemplateFile=locate("data", "kab/template.kab"); - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::createNew: template file is \"" - << (const char*)KabTemplateFile.utf8() << "\"." << endl; - QConfigDB db; - // ----- - if(KabTemplateFile.isEmpty() - || !db.setFileName(KabTemplateFile, true, true)) - { - KMessageBox::error(this, - i18n("Cannot find kab's template file.\n" - "You cannot create new files."), - i18n("File Error")); - return InternError; - } - if(!db.load()) - { - KMessageBox::error(this, - i18n("Cannot read kab's template file.\n" - "You cannot create new files."), - i18n("Format Error")); - - return InternError; - } - if(!db.setFileName(filename, false, false)) - { - KMessageBox::error(this, - i18n("Cannot create the file\n\"") - +filename+"\"\n"+ - i18n("Could not create the new file."), - i18n("File Error")); - return PermDenied; - } - if(!db.save()) - { - KMessageBox::error(this, - i18n("Cannot save the file\n\"") - +filename+"\"\n"+ - i18n("Could not create the new file."), - i18n("File Error")); - return InternError; - } - // ----- - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::createConfigFile() -{ - // ########################################################################### - const TQString ConfigTemplateFile=locate("data", "kab/template.config"); - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::createConfigFile: config template file is \"" - << (const char*)ConfigTemplateFile.utf8() << "\"." << endl; - const TQString filename= locateLocal( "data", STD_CONFIGFILENAME); - QConfigDB db; - // ----- - if(ConfigTemplateFile.isEmpty() - || !db.setFileName(ConfigTemplateFile, true, true)) - { - KMessageBox::error(this, - i18n("Cannot find kab's configuration template file.\n" - "kab cannot be configured."), - i18n("File Error")); - - return InternError; - } - if(!db.load()) - { - KMessageBox::error(this, - i18n("Cannot read kab's configuration template file.\n" - "kab cannot be configured."), - i18n("File Error")); - return InternError; - } - if(!db.setFileName(filename, false, false)) - { - KMessageBox::error(this, - i18n("Cannot create the file\n\"") - +filename+"\"\n"+ - i18n("Could not create the new configuration file."), - i18n("File Error")); - return PermDenied; - } - if(!db.save()) - { - KMessageBox::error(this, - i18n("Cannot save the file\n\"") - +filename+"\"\n"+ - i18n("Could not create the new configuration file."), - i18n("File Error")); - return InternError; - } - // ----- - return NoError; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::loadConfigFile() -{ - // ########################################################################### - TQString file = locateLocal( "data", STD_CONFIGFILENAME); - if(config->setFileName(file, true, true)) - { - if(config->load()) - { - return NoError; - } else { - KMessageBox::information(this, - i18n("Cannot load kab's local configuration file.\n" - "There may be a formatting error.\n" - "kab cannot be configured."), - i18n("File Error")); - return InternError; - } - } else { - KMessageBox::information(this, - i18n("Cannot find kab's local configuration file.\n" - "kab cannot be configured."), - i18n("File Error")); - return NoSuchFile; - } - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::makeVCardFromEntry(const Entry&, const TQString&) -{ - // ########################################################################### - return NotImplemented; - // ########################################################################### -} - -AddressBook::ErrorCode -AddressBook::makeEntryFromVCard(const TQString&, Entry&) -{ - // ########################################################################### - return NotImplemented; - // ########################################################################### -} - -TQString -AddressBook::getStandardFileName() -{ - // ########################################################################### - return locateLocal( "data", STD_USERFILENAME); - // ########################################################################### -} - -TQString AddressBook::phoneType(AddressBook::Telephone phone) -{ - switch(phone) - { - case Fixed: return i18n("fixed"); break; - case Mobile: return i18n("mobile"); break; - case Fax: return i18n("fax"); break; - case Modem: return i18n("modem"); break; - default: return i18n("general"); - } -} - -void AddressBook::externalChange() -{ - updateMirrorMap(); -} - -Section* AddressBook::configurationSection() -{ - Section *section; - if(data!=0) - { - if(data->get(LOCAL_CONFIG_SECTION, section)) - { - return section; - } else { - return 0; - } - } else { - return 0; - } -} - -AddressBook::ErrorCode AddressBook::Entry::get(const char* fieldname, TQVariant& field) -{ - // "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname", - // "birthday", "comment", "talk", "emails", "keywords", "telephone", - // "urls", "user1", "user2", "user3", "user4", "custom" - int dummy=0; - // ----- - if(fieldname==Fields[dummy++]) - { // the title - field=title; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the rank - field=rank; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the formatted name - field=fn; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the nameprefix - field=nameprefix; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the firstname - field=firstname; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the middle name - field=middlename; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the last name - field=lastname; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the birthday - field=TQString(birthday.toString()); - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the comment - field=comment; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the talk addresses - field=talk; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the email addresses - field=emails; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the keywords - field=keywords; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the telephones - field=telephone; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the urls - field=URLs; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the user field 1 - field=user1; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the user field 2 - field=user2; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the user field 3 - field=user3; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the user field 4 - field=user4; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the custom fields (app specific) - field=custom; - return NoError; - } - // ----- we did not find that field: - return NoSuchField; -} - -AddressBook::ErrorCode AddressBook::Entry::Address::get(const char* fieldname, - TQVariant& field) -{ - // "headline", "position", - // "org", "orgunit", "orgsubunit", - // "deliverylabel", "address", "zip", "town", "country", "state" - int dummy=0; - // ----- - if(fieldname==Fields[dummy++]) - { // the headline - field=headline; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the position - field=position; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the organization - field=org; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the organizational unit - field=orgUnit; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the organizational subunit - field=orgSubUnit; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the delivery label - field=deliveryLabel; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the address - field=address; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the zip code - field=zip; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the town - field=town; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the country - field=country; - return NoError; - } - if(fieldname==Fields[dummy++]) - { // the state - field=state; - return NoError; - } - // ----- we did not find that field: - return NoSuchField; -} - -Section* AddressBook::categoriesSection() -{ - const TQString Predefines[]= { - i18n("Business"), - i18n("Private"), - i18n("Dates") }; - size_t Size=sizeof(Predefines)/sizeof(Predefines[0]); - Section* section; - Section* categories; - KeyValueMap *keys; - // ----- - if(data->get(KAB_CATEGORY_KEY, section)) - { - // it exists, go ahead - return section; - } else { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::categoriesSection: creating categories structure." << endl; - // it does not exist - create it - if(!data->createSection(KAB_CATEGORY_KEY)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::categoriesSection: error creating categories section." - << endl; - return 0; - } - data->get(KAB_CATEGORY_KEY, section); - // add the predefined categories: - categories=new Section; - keys=categories->getKeys(); - for(size_t count=0; countinsert(TQCString().setNum(count), values); - } - section->add(KAB_CATEGORY_KEY, categories); - keys=section->getKeys(); - keys->insert("NextAvailableCatKey", (long)Size); - } - save(); - if(data->get(KAB_CATEGORY_KEY, section)) - return section; - return 0; // might not happen -} - -AddressBook::ErrorCode AddressBook::categories(CategoriesMap& cat) -{ // WORK_TO_DO: use a permanent cached map and update on changed() - kdDebug(KAB_KDEBUG_AREA, !cat.isEmpty()) - << "AddressBook::categories: warning - categories map is supposed to be empty!" - << endl; - Section *section; - Section *categories; - KeyValueMap* keys; - int key; - bool rc; - TQStringList values; - StringStringMap::iterator pos; - // ----- query categories section: - section=categoriesSection(); - TQ_CHECK_PTR(section); - // ----- - if(!section->find(KAB_CATEGORY_KEY, categories)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::categories: error in database structure." - << endl; - return InternError; - } - // ----- everything is set up, create the categories map: - // use an iterator to walk over all elements of categories key-value-map: - keys=categories->getKeys(); - for(pos=keys->begin(); pos!=keys->end(); ++pos) - { - if(!keys->get((*pos).first, values)) - { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::categories: internal error querying categories." - << endl; - } else { - key=(*pos).first.toInt(&rc); - if(rc) - { - cat.insert(key, values[0]); - } else { - kdDebug(KAB_KDEBUG_AREA) - << "AddressBook::categories: error - non-integer category key - ignored." - << endl; - } - } - } - return NoError; -} - -#include "addressbook.moc" diff --git a/kab/addressbook.cpp b/kab/addressbook.cpp new file mode 100644 index 000000000..017621ac7 --- /dev/null +++ b/kab/addressbook.cpp @@ -0,0 +1,2040 @@ +/* + This file implements the basic personal information management class + used in the TDE addressbook. + + the TDE addressbook + + $ Author: Mirko Boehm $ + $ Copyright: (C) 1996-2001, Mirko Boehm $ + $ Contact: mirko@kde.org + http://www.kde.org $ + $ License: GPL with the following explicit clarification: + This code may be linked against any version of the Qt toolkit + from Troll Tech, Norway. $ + + $Id$ +*/ + +#include "addressbook.h" +#include "qconfigDB.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +#include +} + +// ----- some defines: +#ifdef KAB_KDEBUG_AREA +#undef KAB_KDEBUG_AREA +#endif + +#define KAB_KDEBUG_AREA 800 + +#ifdef STD_USERFILENAME +#undef STD_USERFILENAME +#endif +#define STD_USERFILENAME "kab/addressbook.kab" + +#ifdef STD_CONFIGFILENAME +#undef STD_CONFIGFILENAME +#endif +#define STD_CONFIGFILENAME "kab/kab.config" + +#ifdef ENTRY_SECTION +#undef ENTRY_SECTION +#endif +#define ENTRY_SECTION "entries" + +// the name of the file-local configuration section +#ifdef LOCAL_CONFIG_SECTION +#undef LOCAL_CONFIG_SECTION +#endif +#define LOCAL_CONFIG_SECTION "config" + +// the name of the subsection for each entry +#ifdef ADDRESS_SUBSECTION +#undef ADDRESS_SUBSECTION +#endif +#define ADDRESS_SUBSECTION "addresses" + +#ifdef KAB_TEMPLATEFILE +#undef KAB_TEMPLATEFILE +#endif +#define KAB_TEMPLATEFILE "kab/template.kab" + +#ifdef KAB_CONFIGTEMPLATE +#undef KAB_CONFIGTEMPLATE +#endif +#define KAB_CONFIGTEMPLATE "kab/template.config" + +#ifdef KAB_CATEGORY_KEY +#undef KAB_CATEGORY_KEY +#endif +#define KAB_CATEGORY_KEY "categories" + +const char* AddressBook::Entry::Address::Fields[]= { + "headline", "position", + "org", "orgunit", "orgsubunit", + "deliverylabel", "address", "zip", "town", "country", "state" }; +const int AddressBook::Entry::Address::NoOfFields +=sizeof(AddressBook::Entry::Address::Fields) +/sizeof(AddressBook::Entry::Address::Fields[0]); + +const char* AddressBook::Entry::Fields[]= { + "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname", + "birthday", "comment", "talk", "emails", "keywords", "telephone", + "urls", "user1", "user2", "user3", "user4", "custom", "categories" }; +const int AddressBook::Entry::NoOfFields +=sizeof(AddressBook::Entry::Fields)/sizeof(AddressBook::Entry::Fields[0]); + +struct QStringLess + : public binary_function +{ + /** The function operator, inline. */ + bool operator()(const TQString& x, const TQString& y) const + { + return x < y; // make one Qt operator fit exactly + } +}; + +// ----- the derived map class: +class StringKabKeyMap : public map +{ /* Same as map, but a class for compilation reasons. This way we do not need + * to include the QStringLess class into the addressbook header file. */ +}; + +// ----- another derived map class: +class KeyNameMap : public map > +{ // same thing +}; + +KeyNameMap* AddressBook::Entry::fields; +KeyNameMap* AddressBook::Entry::Address::fields; + +bool +KabKey::operator == (const KabKey& key) const +{ + // ########################################################################### + return key.getKey()==getKey(); + // ########################################################################### +} + +void +KabKey::setKey(const TQCString& text) +{ + // ########################################################################### + key=text; + // ########################################################################### +} + +TQCString +KabKey::getKey() const +{ + // ########################################################################### + return key; + // ########################################################################### +} + + + +AddressBook::Entry::Address::Address() +{ +} + +bool AddressBook::Entry::Address::nameOfField(const char* key, TQString& value) +{ + KeyNameMap::iterator pos; + // ----- + if(fields==0) + { // this is executed exactly one time per application instance, + // as fields is static + int counter=0; + fields=new KeyNameMap; + TQ_CHECK_PTR(fields); + if(!fields->insert + (map >::value_type + (Fields[counter++], i18n("Headline"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Position"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Organization"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Department"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Sub-Department"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Delivery Label"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("street/postal","Address"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Zipcode"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("City"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Country"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("As in addresses", "State"))).second) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::Address::nameOfField (while " + << " creating field-name map): TYPO, correct this." + << endl; + } else { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::Address::nameOfField: " + << "inserted field names." << endl; + } +#if ! defined NDEBUG + TQString name; + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::Address::nameOfField:" << endl + << "Created key-fieldname-map. Defined fields are:" + << endl; + for(counter=0; counterfind(Fields[counter]); + if(pos==fields->end()) + { + kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl; + } else { + kdDebug(KAB_KDEBUG_AREA) + << " " << Fields[counter] << " (" + << (*pos).second.utf8() << ")" << endl; + } + } +#endif + } + // ----- now finally do the lookup: + pos=fields->find(key); + if(pos==fields->end()) + { + return false; + } else { + value=(*pos).second; + return true; + } +} + +bool AddressBook::Entry::nameOfField(const char* key, TQString& value) +{ + KeyNameMap::iterator pos; + // ----- + if(fields==0) + { // this is executed exactly one time per application instance, + // as fields is static + int counter=0; + fields=new KeyNameMap; + TQ_CHECK_PTR(fields); + if(!fields->insert + (map >::value_type + (Fields[counter++], i18n("person","Title"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Rank"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Formatted Name"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Name Prefix"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("First Name"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Middle Name"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Last Name"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Birthday"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Comment"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Talk Addresses"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Email Addresses"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Keywords"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Telephone Number"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("URLs"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("User Field 1"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("User Field 2"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("User Field 3"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("User Field 4"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Custom"))).second + || + !fields->insert + (map >::value_type + (Fields[counter++], i18n("Categories"))).second) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::Address::nameOfField (while " + << " creating field-name map): TYPO, correct this." << endl; + } else { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::Address::nameOfField: " + << "inserted field names." << endl; + } +#if ! defined NDEBUG + TQString name; + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::Entry::nameOfField:" << endl + << "Created key-fieldname-map. Defined fields are:" << endl; + for(counter=0; counterfind(Fields[counter]); + if(pos==fields->end()) + { + kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl; + } else { + kdDebug(KAB_KDEBUG_AREA) + << " " << Fields[counter] << " (" + << (*pos).second.utf8() << ")" << endl; + } + } +#endif + } + // ----- now finally do the lookup: + pos=fields->find(key); + if(pos==fields->end()) + { + return false; + } else { + value=(*pos).second; + return true; + } +} + +AddressBook::ErrorCode +AddressBook::Entry::getAddress(int index, Address& address) const +{ + // ########################################################################### + list
::const_iterator pos; + // ----- + if(index>=0 && (unsigned)indexquit(); // It is critical, but will possibly never happen. + } + connect(data, TQT_SIGNAL(fileChanged()), TQT_SLOT(dataFileChanged())); + connect(data, TQT_SIGNAL(changed(QConfigDB*)), + TQT_SLOT(reloaded(QConfigDB*))); + connect(config, TQT_SIGNAL(fileChanged()), TQT_SLOT(configFileChanged())); + // ----- set style: + + filename = locate( "data", STD_CONFIGFILENAME); + if (filename.isEmpty()) + { + filename = locateLocal( "data", STD_CONFIGFILENAME ); + // config does not exist yet + if(createConfigFile()!=NoError) + { + KMessageBox::sorry(this, + i18n("Your local kab configuration file " + "\"%1\" " + "could not be created. kab will probably not " + "work correctly without it.\n" + "Make sure you have not removed write permission " + "from your local TDE directory (usually ~/.trinity).").arg(filename)); + state=PermDenied; + } + } + loadConfigFile(); + // ----- now get some configuration settings: + if(config->get("config", keys)) + { + keys->get("CreateBackupOnStartup", createBackup); + } + // ----- check and possibly create user standard file: + filename = locate( "data", STD_USERFILENAME ); + + if(filename.isEmpty()) // if it does not exist + { + filename = locateLocal( "data", STD_USERFILENAME); + if(createNew(filename)!=NoError) // ...and we cannot create it + { + KMessageBox::sorry(this, + i18n("Your standard kab database file " + "\"%1\" " + "could not be created. kab will probably not " + "work correctly without it.\n" + "Make sure you have not removed write permission " + "from your local TDE directory (usually ~/.trinity).").arg(filename)); + state=PermDenied; + } else { + KMessageBox::information + (this, + i18n("kab has created your standard addressbook in\n\"%1\"") + .arg(filename)); + } + } + // ----- load the user standard file: + if(loadit) + { + if(load(filename)!=NoError) + { // ----- the standard file could not be loaded + state=PermDenied; + } else { + if(createBackup) + { + // ----- create the backup file: + TQString temp=data->fileName(); + if(data->setFileName(temp+".backup", false, false)) + { + if(!data->save()) + { + KMessageBox::information + (this, + i18n("Cannot create backup file (permission denied)."), + i18n("File Error")); + } + } else { + KMessageBox::error + (this, + i18n("Cannot open backup file for " + "writing (permission denied)."), + i18n("File Error")); + } + // ----- reset the filename: + if(!data->setFileName(temp, true, true)) + { + KMessageBox::error + (this, + i18n("Critical error:\n" + "Permissions changed in local directory!"), + i18n("File Error")); + closeFile(false); + state=PermDenied; + } else { + state=NoError; + } + } + } + } + // ----- + data->watch(true); + // ########################################################################### +} + +AddressBook::~AddressBook() +{ + // ########################################################################### + delete data; + delete config; + delete entries; + // ########################################################################### +} + +QConfigDB* AddressBook::getConfig() +{ + // ########################################################################### + return config; + // ########################################################################### +} + +AddressBook::ErrorCode AddressBook::getState() +{ + // ########################################################################### + return state; + // ########################################################################### +} + +AddressBook::ErrorCode AddressBook::load(const TQString& filename) +{ + // ----- Remark: Close the file if it could not be loaded! + // ########################################################################### + ErrorCode rc=NoError; + TQFileInfo newfile, oldfile; + // ----- + TQString fname = (filename.isEmpty()) ? data->fileName() : filename ; + if(fname.isEmpty()) // there was never a filename set: + { + state=NoFile; + return NoFile; + } + // ----- + newfile.setFile(fname); + oldfile.setFile(data->fileName()); + if(isSameFile(fname, data->fileName())) + { // ----- possibly deleted file: + if(data->load()) + { + emit(setStatus(i18n("File reloaded."))); + state=NoError; + } else { + switch + (KMessageBox::questionYesNo + (this, + i18n("The currently loaded file " + "\"%1\" " + "cannot be reloaded. kab may close or save it.\n" + "Save it if you accidentally deleted your data file.\n" + "Close it if you intended to do so.\n" + "Your file will be closed by default.") + .arg(oldfile.absFilePath()), + i18n("File Error"), + KStdGuiItem::close(), KStdGuiItem::save())) + { + case KMessageBox::No: // save + if(!data->save(i18n("(Safety copy on file error)").ascii(), true)) + { + KMessageBox::information(this, + i18n("Cannot save the file; will close it now."), + i18n("File Error")); + closeFile(false); + state=NoFile; + rc=PermDenied; + } else { + state=NoError; + rc=NoError; + } + break; // no error if we could save the file + default: // close + closeFile(false); + state=NoFile; + rc=NoSuchFile; + break; + } + } + } else { // ----- set new filename + if(data->setFileName(fname, true, true)) + { + if(data->load()) + { + emit(changed()); + emit(setStatus(i18n("File opened."))); + state=NoError; + } else { + KMessageBox::information(this, + i18n("Could not load the file."), + i18n("File Error")); + closeFile(false); + emit(setStatus(i18n("No such file."))); + rc=NoSuchFile; + } + } else { + if(KMessageBox::questionYesNo + (this, + i18n("The file \"%1\" cannot be found. " + "Create a new one?").arg(fname), + i18n("No Such File"), + i18n("Create"), KStdGuiItem::cancel())==KMessageBox::Yes) + { + if(createNew(fname)==NoError) + { + emit(setStatus(i18n("New file."))); + } else { // ----- do not close here, stick with the old file: + emit(setStatus(i18n("Canceled."))); + } + } + } + } + // ----- + if(rc==NoError) + { + data->watch(true); + updateMirrorMap(); + } + // ----- + return rc; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getListOfNames(TQStringList* strings, bool reverse, bool initials) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getListOfNames: called.\n"; + StringKabKeyMap::iterator pos; + TQString desc; + ErrorCode rc=NoError; + ErrorCode temp; + // ----- erase the list contents: + strings->clear(); + // ----- ...and fill it: + for(pos=entries->begin(); pos!=entries->end(); ++pos) + { + temp=literalName((*pos).second, desc, reverse, initials); + if(temp!=AddressBook::NoError) + { + desc=i18n("(Internal error in kab)"); + rc=InternError; + } + if(desc.isEmpty()) + { + desc=i18n("(empty entry)"); + } + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "AddressBook::getListOfNames: adding " << desc << endl; + strings->append(desc); + } + // ----- any problems? + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::getListOfNames: done, " + << strings->count() + << " entries.\n"; + return rc; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::literalName(const KabKey& key, TQString& text, bool rev, bool init) +{ + // ########################################################################### + Entry entry; + ErrorCode rc; + // ----- get the entry: + rc=getEntry(key, entry); + if(rc!=NoError) + { + return rc; + } + // ----- + return literalName(entry, text, rev, init); + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::literalName(const Entry& entry, TQString& text, bool rev, bool init) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: called.\n"; + TQString firstname, middlename, lastname, nameprefix; + // ----- is the formatted name set? + if(!entry.fn.isEmpty()) + { + text=entry.fn; + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "AddressBook::literalName: done (fn).\n"; + return NoError; + } + // ----- prepare the strings: + firstname=entry.firstname.simplifyWhiteSpace(); + middlename=entry.middlename.simplifyWhiteSpace(); + lastname=entry.lastname.simplifyWhiteSpace(); + nameprefix=entry.nameprefix.simplifyWhiteSpace(); + // ----- create the initials: + if(init) + { + if(!firstname.isEmpty()) firstname=firstname.mid(0, 1)+'.'; + if(!middlename.isEmpty()) middlename=middlename.mid(0, 1)+'.'; + // if(!lastname.isEmpty()) lastname=lastname.mid(0, 1)+'.'; + } + // ----- assemble the string: + text=""; + if(rev) + { // name, firstname - add. name - name prefix + if(!lastname.isEmpty()) + { + text=lastname; + } + if(!firstname.isEmpty() || !middlename.isEmpty() || !nameprefix.isEmpty()) + { + text+=','; + } + if(!firstname.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=firstname; + } + if(!middlename.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=middlename; + } + if(!nameprefix.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=nameprefix; + } + } else { + // firstname - add. name - name prefix - name + text=firstname; + if(!middlename.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=middlename; + } + if(!nameprefix.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=nameprefix; + } + if(!lastname.isEmpty()) + { + if(!text.isEmpty()) + { + text+=' '; + } + text+=lastname; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: done: " + << text << ".\n"; + return NoError; + // ########################################################################### +} + +unsigned int +AddressBook::noOfEntries() +{ + // ########################################################################### + return entries->size(); + // ########################################################################### +} + +void +AddressBook::dataFileChanged() +{ + // ########################################################################### + data->watch(false); // will be restarted after successful load + load(); + // ########################################################################### +} + +void +AddressBook::configFileChanged() +{ + bool GUARD; GUARD=true; + // ########################################################################### + if(!config->load()) + { + KMessageBox::error(this, + i18n("Cannot reload configuration file!"), + i18n("File Error")); + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::configFileChanged: " + "config file reloaded.\n"; + emit(setStatus(i18n("Configuration file reloaded."))); + } + // ########################################################################### +} + +void +AddressBook::reloaded(QConfigDB* db) +{ + bool GUARD; GUARD=false; + // ########################################################################### + if(db==data) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::reloaded: file has been " + "reloaded.\n"; + updateMirrorMap(); // WORK_TO_DO: what's up with the return value? + changed(); + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::save(const TQString& filename, bool force) +{ + // ########################################################################### + if(filename.isEmpty()) + { + if(data->save(0, force)) + { + emit(setStatus(i18n("File saved."))); + return NoError; + } else { + return PermDenied; + } + } else { + if(data->setFileName(filename, false, false)) + { + if(data->save(0, true)) + { + emit(newFile(filename)); + return NoError; + } else { + return PermDenied; + } + } else { + return PermDenied; + } + } + // ########################################################################### +} + +bool +AddressBook::isSameFile(const TQString& a, const TQString& b) +{ + // ########################################################################### + TQFileInfo filea(a), fileb(b); + // ----- + return filea.absFilePath()==fileb.absFilePath(); + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::closeFile(bool saveit) +{ + // ########################################################################### + if(saveit) + { + if(save()!=NoError) + { + emit(setStatus(i18n("Permission denied."))); + return PermDenied; + } + } + data->clear(); + // data->reset(); WORK_TO_DO: File name is not reset by now. + emit(setStatus(i18n("File closed."))); + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getEntry(const KabKey& key, Entry& entry) +{ + // ########################################################################### + Section *section; + // ----- + if(getEntry(key, section)==NoError) + { + return makeEntryFromSection(section, entry); + } else { + return NoSuchEntry; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getEntry(const KabKey& key, Section*& section) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getEntry: searching entry " + "with key " << key.getKey().data() << endl; + StringKabKeyMap::iterator pos; + // ----- + for(pos=entries->begin(); pos!=entries->end(); ++pos) + { + if((*pos).second==key) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "AddressBook::getEntry: key exists." << endl; + break; + } + } + if(pos==entries->end()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "AddressBook::getEntry: no such entry.\n"; + return NoSuchEntry; + } else { + if(data->get((TQCString)ENTRY_SECTION+'/'+key.getKey(), section)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "AddressBook::getEntry: done." << endl; + return NoError; + } else { + return InternError; + } + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getEntries(list& thelist) +{ + // ########################################################################### + StringKabKeyMap::iterator pos; + Entry entry; + ErrorCode rc; + // ----- + kdDebug(!thelist.empty(), KAB_KDEBUG_AREA) + << "AddressBook::getEntries: warning - non-empty value list!" << endl; + thelist.erase(thelist.begin(), thelist.end()); + for(pos=entries->begin(); pos!=entries->end(); ++pos) + { + rc=getEntry((*pos).second, entry); + if(rc==NoError) + { + thelist.push_back(entry); + } else { + return InternError; + } + } + // ----- + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getKey(int index, KabKey& key) +{ + // ########################################################################### + StringKabKeyMap::iterator pos; + // ----- + if((unsigned)indexsize()) + { + pos=entries->begin(); + advance(pos, index); + key=(*pos).second; + return NoError; + } else { + return NoSuchEntry; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::getIndex(const KabKey& key, int& index) +{ + bool GUARD; GUARD=true; + // ########################################################################### + StringKabKeyMap::iterator pos; + // ----- + index=0; + for(pos=entries->begin(); pos!=entries->end(); ++pos) + { + // kdDebug(KAB_KDEBUG_AREA) << (*pos).second.getKey().data() << " <--> " << + // key.getKey().data() << endl; + if((*pos).second==key) break; + ++index; + } + kdDebug(pos==entries->end(), KAB_KDEBUG_AREA) << + "AddressBook::getIndex: no such key." << endl; + if(pos==entries->end()) + { + return NoSuchEntry; + } else { + return NoError; + } + // ########################################################################### +} + +Section* +AddressBook::entrySection() +{ + // ########################################################################### + Section* section; + // ----- + if(!data->get(ENTRY_SECTION, section)) + { + return 0; + } else { + return section; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::add(const Entry& entry, KabKey& key, bool update) +{ + bool GUARD; GUARD=true; + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: called." << endl; + // ########################################################################### + Section* theEntries=entrySection(); + Section* newEntry; + KabKey nextKey; + ErrorCode locked; + ErrorCode rc; + // ----- + if(theEntries==0) + { + kdDebug(KAB_KDEBUG_AREA) << "AddressBook::add: no entries section." + << endl; + return NoFile; + } + newEntry=new Section; + if(newEntry==0) + { + KMessageBox::error(this, + i18n("Cannot initialize local variables."), + i18n("Out of Memory")); + kapp->quit(); // It is critical, but will possibly never happen. + return InternError; // shut the compiler up... + } + // ----- lock the file: + locked=lock(); + switch(locked) + { + case PermDenied: + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::add: permission denied." << endl; + return PermDenied; // cannot get r/w mode + case Locked: + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::add: db is already in r/w mode." << endl; + break; + case NoError: + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::add: got writing permissions." << endl; + break; + default: + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::add: unknown response, exiting." << endl; + return InternError; + } + // ----- + if(makeSectionFromEntry(entry, *newEntry)==NoError) + { + nextKey=nextAvailEntryKey(); + if(!theEntries->add(nextKey.getKey(), newEntry)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::add: Cannot insert section.\n"; + rc=InternError; + } else { + key=nextKey; + emit(changed()); + rc=NoError; + } + if(update) updateMirrorMap(); + } else { + rc=InternError; + } + if(locked!=Locked) + { // ----- unlock the file here: + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::add: dropped writing permissions." << endl; + locked=unlock(); + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: done." << endl; + if(locked!=NoError) + { + return locked; + } + if(rc!=NoError) + { + return rc; + } + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::change(const KabKey& key, const Entry& entry) +{ + // ########################################################################### + Section* theEntries=entrySection(); + Section* oldEntry; + ErrorCode locked; + ErrorCode rc; + // ----- + if(theEntries==0) + { + return NoFile; + } + // ----- lock the file: + locked=lock(); + if(locked==PermDenied) + { + return PermDenied; // cannot get r/w mode + } + // ----- + if(!theEntries->find(key.getKey(), oldEntry)) + { + rc=NoSuchEntry; + } else { + oldEntry->clear(); + rc=makeSectionFromEntry(entry, *oldEntry); + emit(changed()); + } + // ----- + if(locked!=PermDenied) + { // ----- unlock the file here: + locked=unlock(); + } + if(locked==NoError) + { + return rc; + } else { + return locked; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::remove(const KabKey& key) +{ + // ########################################################################### + Section *theEntries=entrySection(); + ErrorCode locked; + ErrorCode rc; + // ----- + if(theEntries==0) + { + return NoFile; + } + // ----- lock the file: + locked=lock(); + if(locked==PermDenied) + { + return PermDenied; // cannot get r/w mode + } + // ----- + if(theEntries->remove(key.getKey())) + { + rc=NoError; + emit(changed()); + } else { + rc=NoSuchEntry; + } + // ----- + if(locked!=PermDenied) + { // ----- unlock the file here: + locked=unlock(); + } + if(locked==NoError) + { + return rc; + } else { + return locked; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::lock() +{ + // ########################################################################### + if(!data->isRO()) return Locked; + if(data->setFileName(data->fileName(), false, false)) + { + return NoError; + } else { + KMessageBox::information(this, + i18n("The file you wanted to change could not be locked.\n" + "It is probably in use by another application or read-only."), + i18n("File Error")); + return PermDenied; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::unlock() +{ + // ########################################################################### + if(data->isRO()) return PermDenied; + if(data->setFileName(data->fileName(), true, true)) + { + return NoError; + } else { + return InternError; + } + // ########################################################################### +} + +KabKey +AddressBook::nextAvailEntryKey() +{ + // ########################################################################### + int max=0; + int temp; + Section::StringSectionMap::iterator pos; + Section *section=entrySection(); + KabKey key; + TQCString dummy; + bool good=true; + // ----- + if(section!=0) + { + for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos) + { + temp=0; + temp=(*pos).first.toInt(&good); + if(!good) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::nextAvailEntryKey: non-integer entry " + << endl; + } + if(temp>max) + { + max=temp; + } + } + } + // ----- + dummy.setNum(++max); + key.setKey(dummy); + // CHECK(key.getKey().toInt(&good)==max); + return key; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::updateMirrorMap() +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) + << "AddressBook::updateMirrorMap: updating mirror map.\n"; + TQString key; + Entry entry; + ErrorCode ec; + KabKey kk; + Section *section=entrySection(); + Section::StringSectionMap::iterator pos; + // ----- + entries->erase(entries->begin(), entries->end()); + if(section==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done, " + "no file loaded." << endl; + return NoError; + } + for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos) + { + if(makeEntryFromSection((*pos).second, entry)!=NoError) + { + // return InternError; // it is saver to continue without a key + } + key=""; + ec=literalName(entry, key, true, false); + if(key.isEmpty() || ec!=NoError) + { + key=i18n("(empty entry)"); + } + key+=(*pos).first; // append the section name to make the key unique + kk.setKey((*pos).first); + entries->insert(StringKabKeyMap::value_type(key, kk)); + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done." + << endl; + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::makeEntryFromSection(Section* section, Entry& entry) +{ + // ########################################################################### + Section *addresses; + Section *addressSection; + Section::StringSectionMap::iterator pos; + KeyValueMap *keys; + Entry temp; + Entry::Address address; + Entry::Address addressDummy; + int count; + // ----- create the aggregats: + const TQCString StringKeys[]= { + "title", + "rank", + "fn", + "nameprefix", + "firstname", + "middlename", + "lastname", + "comment", + "user1", + "user2", + "user3", + "user4" + }; + TQString* StringValues[]= { + &temp.title, + &temp.rank, + &temp.fn, + &temp.nameprefix, + &temp.firstname, + &temp.middlename, + &temp.lastname, + &temp.comment, + &temp.user1, + &temp.user2, + &temp.user3, + &temp.user4 + }; + const int StringKeySize=sizeof(StringKeys)/sizeof(StringKeys[0]); + const TQCString StringListKeys[]= { + "talk", + "emails", + "keywords", + "telephone", + "URLs", + "custom", + "categories" + }; + TQStringList* StringListValues[]= { + &temp.talk, + &temp.emails, + &temp.keywords, + &temp.telephone, + &temp.URLs, + &temp.custom, + &temp.categories + }; + const int StringListKeySize=sizeof(StringListKeys)/sizeof(StringListKeys[0]); + // ----- first parse "addresses" subsection: + if(!section->find(ADDRESS_SUBSECTION, addresses)) + { + return InternError; // no subsection called "addresses" + } + for(pos=addresses->sectionsBegin(); pos!=addresses->sectionsEnd(); ++pos) + { + if(!addresses->find((*pos).first, addressSection)) + { + return InternError; // no section we have an iterator for? + } + keys=addressSection->getKeys(); + address=addressDummy; // clean it up + if(makeAddressFromMap(keys, address)==AddressBook::NoError) + { + // ----- add the address to the list of addresses: + temp.addresses.push_back(address); + } else { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeEntryFromSection: cannot find all fields " + << "in an address subsection." << endl; + } + } + // ----- now parse all other fields directly: + keys=section->getKeys(); + for(count=0; countget(StringKeys[count], *StringValues[count])) + { + /* Spits out lots of warnings: + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeEntryFromSection: error: could not get " + << "value for key " << (const char*)StringKeys[count] + << "." << endl; + */ + } + } + for(count=0; countget(StringListKeys[count], *StringListValues[count])) + { + /* Spits out lots of warnings: + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeEntryFromSection: error: could not get " + << "value for key " << (const char*)StringListKeys[count] + << "." << endl; + */ + } + } + // ----- finally get the birthday: + keys->get("birthday", temp.birthday); // this may return false (no date) + // ----- + entry=temp; + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::makeAddressFromMap(KeyValueMap* keys, Entry::Address& address) +{ + // ########################################################################### + const TQCString Keys[]= { + "headline", + "position", + "org", + "orgunit", + "orgsubunit", + // "role", + "deliverylabel", + "address", + "zip", + "town", + "country", + "state" + }; + TQString* strings[]= { + &address.headline, + &address.position, + &address.org, + &address.orgUnit, + &address.orgSubUnit, + // &address.role, + &address.deliveryLabel, + &address.address, + &address.zip, + &address.town, + &address.country, + &address.state + }; + const int Size=sizeof(Keys)/sizeof(Keys[0]); + int count; + // ----- + for(count=0; countget(Keys[count], *strings[count]); + } + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::makeSectionFromEntry(const Entry& entry, Section& section) +{ + // ########################################################################### + list::const_iterator addPos; + Section *addresses=0; + Section *address=0; + TQCString key; // used for creating address subsection keys + int count=0; // counts the addresses + KeyValueMap *keys; + // ----- prepare the section object: + section.clear(); + // ----- first create "addresses" subsection: + if(!section.add(ADDRESS_SUBSECTION)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeSectionFromEntry: cannot create " << "subsection." + << " " << endl; + return InternError; + } + if(!section.find(ADDRESS_SUBSECTION, addresses)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeSectionFromEntry: cannot get new section." << endl; + return InternError; + } + // ----- now insert addresses: + for(addPos=entry.addresses.begin(); addPos!=entry.addresses.end(); ++addPos) + { + ++count; + key.setNum(count); + if(!addresses->add(key)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeSectionFromEntry: cannot create address " << endl; + return InternError; + } + if(!addresses->find(key, address)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeSectionFromEntry: cannot get new " << endl; + return InternError; + } + keys=address->getKeys(); + // ----- now insert keys into address: + if(!keys->insert("headline", (*addPos).headline) || + !keys->insert("position", (*addPos).position) || + !keys->insert("org", (*addPos).org) || + !keys->insert("orgunit", (*addPos).orgUnit) || + !keys->insert("orgsubunit", (*addPos).orgSubUnit) || + // !keys->insert("role", (*addPos).role) || + !keys->insert("deliverylabel", (*addPos).deliveryLabel) || + !keys->insert("address", (*addPos).address) || + !keys->insert("zip", (*addPos).zip) || + !keys->insert("town", (*addPos).town) || + !keys->insert("country", (*addPos).country) || + !keys->insert("state", (*addPos).state)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeSectionFromEntry: cannot completely " + << "insert this address." << endl; + return InternError; + } + } + // ----- now add the other fields: + keys=section.getKeys(); + if(!keys->insert("title", entry.title) || + !keys->insert("rank", entry.rank) || + !keys->insert("fn", entry.fn) || + !keys->insert("nameprefix", entry.nameprefix) || + !keys->insert("firstname", entry.firstname) || + !keys->insert("middlename", entry.middlename) || + !keys->insert("lastname", entry.lastname) || + !keys->insert("birthday", entry.birthday) || + !keys->insert("comment", entry.comment) || + !keys->insert("talk", entry.talk) || + !keys->insert("emails", entry.emails) || + !keys->insert("keywords", entry.keywords) || + !keys->insert("telephone", entry.telephone) || + !keys->insert("URLs", entry.URLs) || + !keys->insert("user1", entry.user1) || + !keys->insert("user2", entry.user2) || + !keys->insert("user3", entry.user3) || + !keys->insert("user4", entry.user4) || + !keys->insert("custom", entry.custom) || + !keys->insert("categories", entry.categories)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::makeEntryFromSection: cannot insert " + << "all fields of the entry." << endl; + return InternError; + } + // ----- + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::createNew(const TQString& filename) +{ + // ########################################################################### + const TQString KabTemplateFile=locate("data", "kab/template.kab"); + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::createNew: template file is \"" + << (const char*)KabTemplateFile.utf8() << "\"." << endl; + QConfigDB db; + // ----- + if(KabTemplateFile.isEmpty() + || !db.setFileName(KabTemplateFile, true, true)) + { + KMessageBox::error(this, + i18n("Cannot find kab's template file.\n" + "You cannot create new files."), + i18n("File Error")); + return InternError; + } + if(!db.load()) + { + KMessageBox::error(this, + i18n("Cannot read kab's template file.\n" + "You cannot create new files."), + i18n("Format Error")); + + return InternError; + } + if(!db.setFileName(filename, false, false)) + { + KMessageBox::error(this, + i18n("Cannot create the file\n\"") + +filename+"\"\n"+ + i18n("Could not create the new file."), + i18n("File Error")); + return PermDenied; + } + if(!db.save()) + { + KMessageBox::error(this, + i18n("Cannot save the file\n\"") + +filename+"\"\n"+ + i18n("Could not create the new file."), + i18n("File Error")); + return InternError; + } + // ----- + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::createConfigFile() +{ + // ########################################################################### + const TQString ConfigTemplateFile=locate("data", "kab/template.config"); + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::createConfigFile: config template file is \"" + << (const char*)ConfigTemplateFile.utf8() << "\"." << endl; + const TQString filename= locateLocal( "data", STD_CONFIGFILENAME); + QConfigDB db; + // ----- + if(ConfigTemplateFile.isEmpty() + || !db.setFileName(ConfigTemplateFile, true, true)) + { + KMessageBox::error(this, + i18n("Cannot find kab's configuration template file.\n" + "kab cannot be configured."), + i18n("File Error")); + + return InternError; + } + if(!db.load()) + { + KMessageBox::error(this, + i18n("Cannot read kab's configuration template file.\n" + "kab cannot be configured."), + i18n("File Error")); + return InternError; + } + if(!db.setFileName(filename, false, false)) + { + KMessageBox::error(this, + i18n("Cannot create the file\n\"") + +filename+"\"\n"+ + i18n("Could not create the new configuration file."), + i18n("File Error")); + return PermDenied; + } + if(!db.save()) + { + KMessageBox::error(this, + i18n("Cannot save the file\n\"") + +filename+"\"\n"+ + i18n("Could not create the new configuration file."), + i18n("File Error")); + return InternError; + } + // ----- + return NoError; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::loadConfigFile() +{ + // ########################################################################### + TQString file = locateLocal( "data", STD_CONFIGFILENAME); + if(config->setFileName(file, true, true)) + { + if(config->load()) + { + return NoError; + } else { + KMessageBox::information(this, + i18n("Cannot load kab's local configuration file.\n" + "There may be a formatting error.\n" + "kab cannot be configured."), + i18n("File Error")); + return InternError; + } + } else { + KMessageBox::information(this, + i18n("Cannot find kab's local configuration file.\n" + "kab cannot be configured."), + i18n("File Error")); + return NoSuchFile; + } + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::makeVCardFromEntry(const Entry&, const TQString&) +{ + // ########################################################################### + return NotImplemented; + // ########################################################################### +} + +AddressBook::ErrorCode +AddressBook::makeEntryFromVCard(const TQString&, Entry&) +{ + // ########################################################################### + return NotImplemented; + // ########################################################################### +} + +TQString +AddressBook::getStandardFileName() +{ + // ########################################################################### + return locateLocal( "data", STD_USERFILENAME); + // ########################################################################### +} + +TQString AddressBook::phoneType(AddressBook::Telephone phone) +{ + switch(phone) + { + case Fixed: return i18n("fixed"); break; + case Mobile: return i18n("mobile"); break; + case Fax: return i18n("fax"); break; + case Modem: return i18n("modem"); break; + default: return i18n("general"); + } +} + +void AddressBook::externalChange() +{ + updateMirrorMap(); +} + +Section* AddressBook::configurationSection() +{ + Section *section; + if(data!=0) + { + if(data->get(LOCAL_CONFIG_SECTION, section)) + { + return section; + } else { + return 0; + } + } else { + return 0; + } +} + +AddressBook::ErrorCode AddressBook::Entry::get(const char* fieldname, TQVariant& field) +{ + // "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname", + // "birthday", "comment", "talk", "emails", "keywords", "telephone", + // "urls", "user1", "user2", "user3", "user4", "custom" + int dummy=0; + // ----- + if(fieldname==Fields[dummy++]) + { // the title + field=title; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the rank + field=rank; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the formatted name + field=fn; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the nameprefix + field=nameprefix; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the firstname + field=firstname; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the middle name + field=middlename; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the last name + field=lastname; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the birthday + field=TQString(birthday.toString()); + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the comment + field=comment; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the talk addresses + field=talk; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the email addresses + field=emails; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the keywords + field=keywords; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the telephones + field=telephone; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the urls + field=URLs; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the user field 1 + field=user1; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the user field 2 + field=user2; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the user field 3 + field=user3; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the user field 4 + field=user4; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the custom fields (app specific) + field=custom; + return NoError; + } + // ----- we did not find that field: + return NoSuchField; +} + +AddressBook::ErrorCode AddressBook::Entry::Address::get(const char* fieldname, + TQVariant& field) +{ + // "headline", "position", + // "org", "orgunit", "orgsubunit", + // "deliverylabel", "address", "zip", "town", "country", "state" + int dummy=0; + // ----- + if(fieldname==Fields[dummy++]) + { // the headline + field=headline; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the position + field=position; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the organization + field=org; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the organizational unit + field=orgUnit; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the organizational subunit + field=orgSubUnit; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the delivery label + field=deliveryLabel; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the address + field=address; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the zip code + field=zip; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the town + field=town; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the country + field=country; + return NoError; + } + if(fieldname==Fields[dummy++]) + { // the state + field=state; + return NoError; + } + // ----- we did not find that field: + return NoSuchField; +} + +Section* AddressBook::categoriesSection() +{ + const TQString Predefines[]= { + i18n("Business"), + i18n("Private"), + i18n("Dates") }; + size_t Size=sizeof(Predefines)/sizeof(Predefines[0]); + Section* section; + Section* categories; + KeyValueMap *keys; + // ----- + if(data->get(KAB_CATEGORY_KEY, section)) + { + // it exists, go ahead + return section; + } else { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::categoriesSection: creating categories structure." << endl; + // it does not exist - create it + if(!data->createSection(KAB_CATEGORY_KEY)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::categoriesSection: error creating categories section." + << endl; + return 0; + } + data->get(KAB_CATEGORY_KEY, section); + // add the predefined categories: + categories=new Section; + keys=categories->getKeys(); + for(size_t count=0; countinsert(TQCString().setNum(count), values); + } + section->add(KAB_CATEGORY_KEY, categories); + keys=section->getKeys(); + keys->insert("NextAvailableCatKey", (long)Size); + } + save(); + if(data->get(KAB_CATEGORY_KEY, section)) + return section; + return 0; // might not happen +} + +AddressBook::ErrorCode AddressBook::categories(CategoriesMap& cat) +{ // WORK_TO_DO: use a permanent cached map and update on changed() + kdDebug(KAB_KDEBUG_AREA, !cat.isEmpty()) + << "AddressBook::categories: warning - categories map is supposed to be empty!" + << endl; + Section *section; + Section *categories; + KeyValueMap* keys; + int key; + bool rc; + TQStringList values; + StringStringMap::iterator pos; + // ----- query categories section: + section=categoriesSection(); + TQ_CHECK_PTR(section); + // ----- + if(!section->find(KAB_CATEGORY_KEY, categories)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::categories: error in database structure." + << endl; + return InternError; + } + // ----- everything is set up, create the categories map: + // use an iterator to walk over all elements of categories key-value-map: + keys=categories->getKeys(); + for(pos=keys->begin(); pos!=keys->end(); ++pos) + { + if(!keys->get((*pos).first, values)) + { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::categories: internal error querying categories." + << endl; + } else { + key=(*pos).first.toInt(&rc); + if(rc) + { + cat.insert(key, values[0]); + } else { + kdDebug(KAB_KDEBUG_AREA) + << "AddressBook::categories: error - non-integer category key - ignored." + << endl; + } + } + } + return NoError; +} + +#include "addressbook.moc" diff --git a/kab/kabapi.cc b/kab/kabapi.cc deleted file mode 100644 index 62a50f162..000000000 --- a/kab/kabapi.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - This file implements the application programming interface - for using kab's addressbook files within other programs. - Parse it with kdoc to get the API documentation. - - the TDE addressbook - - $ Author: Mirko Boehm $ - $ Copyright: (C) 1996-2001, Mirko Boehm $ - $ Contact: mirko@kde.org - http://www.kde.org $ - $ License: GPL with the following explicit clarification: - This code may be linked against any version of the Qt toolkit - from Troll Tech, Norway. $ - - $Id$ -*/ - -#include "kabapi.h" -#include -#include -#include -#include - - -#include "kabapi.moc" - -#ifdef KAB_KDEBUG_AREA -#undef KAB_KDEBUG_AREA -#endif - -#define KAB_KDEBUG_AREA 800 - -using namespace std; - -KabAPI::KabAPI(TQWidget* parent, const char* name) - : KDialogBase(parent, name), - book(0), - listbox(new TDEListBox(this)), - selection(-1) -{ - TQ_CHECK_PTR(listbox); - setMainWidget(listbox); - showButtonApply(false); - enableButtonSeparator(true); - connect(listbox, TQT_SIGNAL(highlighted(int)), TQT_SLOT(entrySelected(int))); - connect(listbox, TQT_SIGNAL(doubleClicked ( TQListBoxItem * )),TQT_SLOT(slotDoubleClicked ( TQListBoxItem * ))); -} - - -void KabAPI::slotDoubleClicked ( TQListBoxItem * ) -{ - accept(); -} - -int KabAPI::exec() -{ - TQStringList names; - // ----- - if(book==0) - { - kdDebug(KAB_KDEBUG_AREA) - << "KabAPI::exec: you have to call init before using the API." - << endl; - return -1; - } else { - if(book->getListOfNames(&names, true, false)==AddressBook::NoError) - { - listbox->clear(); - listbox->insertStringList(names); - if(names.count()>0) - { - listbox->setCurrentItem(0); - } - listbox->setMinimumSize(listbox->sizeHint()); - adjustSize(); - resize(minimumSize()); - return KDialogBase::exec(); - } else { - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::exec: error creating interface." - << endl; - return -1; - } - } -} - -AddressBook::ErrorCode KabAPI::init() -{ - // ############################################################################ - book=new AddressBook(0, "KABAPI::book", true); //change parent from "this" to "0" //dsweet - if(book->getState()==AddressBook::NoError) - { - connect(book, TQT_SIGNAL(setStatus(const TQString&)), - TQT_SLOT(setStatusSlot(const TQString&))); - return AddressBook::NoError; - } else { - return AddressBook::InternError; - } - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::getEntry(AddressBook::Entry& entry, KabKey& key) -{ - // ############################################################################ - if(book->noOfEntries()==0) - { - return AddressBook::NoEntry; - } - if(selection>=0) - { - if(book->getKey(selection, key)==AddressBook::NoError) - { - if(book->getEntry(key, entry)==AddressBook::NoError) - { - return AddressBook::NoError; - } else { - return AddressBook::InternError; // this may not happen - } - } else { - return AddressBook::NoEntry; - } - } else { - return AddressBook::InternError; - } - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::add(const AddressBook::Entry& entry, KabKey& key, - bool update) -{ - // ############################################################################ - if(book->add(entry, key, update)!=AddressBook::NoError) - { - KMessageBox::sorry(this, i18n("Your new entry could not be added.")); - return AddressBook::InternError; - } else { - return AddressBook::NoError; - } - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::remove(const KabKey& key) -{ - TQ_CHECK_PTR(book); - // ############################################################################ - if(book->AddressBook::remove(key)==AddressBook::NoError) - { - return AddressBook::NoError; - } else { - return AddressBook::NoEntry; - } - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::getEntryByName(const TQString&, - list&, const int) -{ - // ############################################################################ - return AddressBook::NotImplemented; - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::getEntryByName(const AddressBook::Entry&, - list&, const int) -{ - // ############################################################################ - return AddressBook::NotImplemented; - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::getEntries(list& entries) -{ - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: called." << endl; - // ############################################################################ - if(book->noOfEntries()==0) - { // ----- database is valid, but empty: - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: no entries." << endl; - return AddressBook::NoEntry; - } - if(book->getEntries(entries)!=AddressBook::NoError) - { - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: intern error." << endl; - return AddressBook::InternError; - } else { - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: done." << endl; - return AddressBook::NoError; - } - // ############################################################################ -} - -AddressBook* KabAPI::addressbook() -{ - // ############################################################################ - return book; - // ############################################################################ -} - -AddressBook::ErrorCode KabAPI::save(bool force) -{ - // ############################################################################ - if(book->save("", force)!=AddressBook::NoError) - { - return AddressBook::PermDenied; - } else { - return AddressBook::NoError; - } - // ############################################################################ -} - -void KabAPI::entrySelected(int index) -{ - kdDebug(KAB_KDEBUG_AREA) << "KabAPI::entrySelected: entry " << index - <<" selected." << endl; - selection=index; -} - -void KabAPI::setStatusSlot(const TQString& text) -{ - emit(setStatus(text)); -} diff --git a/kab/kabapi.cpp b/kab/kabapi.cpp new file mode 100644 index 000000000..62a50f162 --- /dev/null +++ b/kab/kabapi.cpp @@ -0,0 +1,220 @@ +/* + This file implements the application programming interface + for using kab's addressbook files within other programs. + Parse it with kdoc to get the API documentation. + + the TDE addressbook + + $ Author: Mirko Boehm $ + $ Copyright: (C) 1996-2001, Mirko Boehm $ + $ Contact: mirko@kde.org + http://www.kde.org $ + $ License: GPL with the following explicit clarification: + This code may be linked against any version of the Qt toolkit + from Troll Tech, Norway. $ + + $Id$ +*/ + +#include "kabapi.h" +#include +#include +#include +#include + + +#include "kabapi.moc" + +#ifdef KAB_KDEBUG_AREA +#undef KAB_KDEBUG_AREA +#endif + +#define KAB_KDEBUG_AREA 800 + +using namespace std; + +KabAPI::KabAPI(TQWidget* parent, const char* name) + : KDialogBase(parent, name), + book(0), + listbox(new TDEListBox(this)), + selection(-1) +{ + TQ_CHECK_PTR(listbox); + setMainWidget(listbox); + showButtonApply(false); + enableButtonSeparator(true); + connect(listbox, TQT_SIGNAL(highlighted(int)), TQT_SLOT(entrySelected(int))); + connect(listbox, TQT_SIGNAL(doubleClicked ( TQListBoxItem * )),TQT_SLOT(slotDoubleClicked ( TQListBoxItem * ))); +} + + +void KabAPI::slotDoubleClicked ( TQListBoxItem * ) +{ + accept(); +} + +int KabAPI::exec() +{ + TQStringList names; + // ----- + if(book==0) + { + kdDebug(KAB_KDEBUG_AREA) + << "KabAPI::exec: you have to call init before using the API." + << endl; + return -1; + } else { + if(book->getListOfNames(&names, true, false)==AddressBook::NoError) + { + listbox->clear(); + listbox->insertStringList(names); + if(names.count()>0) + { + listbox->setCurrentItem(0); + } + listbox->setMinimumSize(listbox->sizeHint()); + adjustSize(); + resize(minimumSize()); + return KDialogBase::exec(); + } else { + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::exec: error creating interface." + << endl; + return -1; + } + } +} + +AddressBook::ErrorCode KabAPI::init() +{ + // ############################################################################ + book=new AddressBook(0, "KABAPI::book", true); //change parent from "this" to "0" //dsweet + if(book->getState()==AddressBook::NoError) + { + connect(book, TQT_SIGNAL(setStatus(const TQString&)), + TQT_SLOT(setStatusSlot(const TQString&))); + return AddressBook::NoError; + } else { + return AddressBook::InternError; + } + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::getEntry(AddressBook::Entry& entry, KabKey& key) +{ + // ############################################################################ + if(book->noOfEntries()==0) + { + return AddressBook::NoEntry; + } + if(selection>=0) + { + if(book->getKey(selection, key)==AddressBook::NoError) + { + if(book->getEntry(key, entry)==AddressBook::NoError) + { + return AddressBook::NoError; + } else { + return AddressBook::InternError; // this may not happen + } + } else { + return AddressBook::NoEntry; + } + } else { + return AddressBook::InternError; + } + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::add(const AddressBook::Entry& entry, KabKey& key, + bool update) +{ + // ############################################################################ + if(book->add(entry, key, update)!=AddressBook::NoError) + { + KMessageBox::sorry(this, i18n("Your new entry could not be added.")); + return AddressBook::InternError; + } else { + return AddressBook::NoError; + } + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::remove(const KabKey& key) +{ + TQ_CHECK_PTR(book); + // ############################################################################ + if(book->AddressBook::remove(key)==AddressBook::NoError) + { + return AddressBook::NoError; + } else { + return AddressBook::NoEntry; + } + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::getEntryByName(const TQString&, + list&, const int) +{ + // ############################################################################ + return AddressBook::NotImplemented; + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::getEntryByName(const AddressBook::Entry&, + list&, const int) +{ + // ############################################################################ + return AddressBook::NotImplemented; + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::getEntries(list& entries) +{ + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: called." << endl; + // ############################################################################ + if(book->noOfEntries()==0) + { // ----- database is valid, but empty: + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: no entries." << endl; + return AddressBook::NoEntry; + } + if(book->getEntries(entries)!=AddressBook::NoError) + { + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: intern error." << endl; + return AddressBook::InternError; + } else { + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::getEntries: done." << endl; + return AddressBook::NoError; + } + // ############################################################################ +} + +AddressBook* KabAPI::addressbook() +{ + // ############################################################################ + return book; + // ############################################################################ +} + +AddressBook::ErrorCode KabAPI::save(bool force) +{ + // ############################################################################ + if(book->save("", force)!=AddressBook::NoError) + { + return AddressBook::PermDenied; + } else { + return AddressBook::NoError; + } + // ############################################################################ +} + +void KabAPI::entrySelected(int index) +{ + kdDebug(KAB_KDEBUG_AREA) << "KabAPI::entrySelected: entry " << index + <<" selected." << endl; + selection=index; +} + +void KabAPI::setStatusSlot(const TQString& text) +{ + emit(setStatus(text)); +} diff --git a/kab/qconfigDB.cc b/kab/qconfigDB.cc deleted file mode 100644 index dc77a1e1b..000000000 --- a/kab/qconfigDB.cc +++ /dev/null @@ -1,2547 +0,0 @@ -/* the Configuration Database library, Version II - - the TDE addressbook - - $ Author: Mirko Boehm $ - $ Copyright: (C) 1996-2001, Mirko Boehm $ - $ Contact: mirko@kde.org - http://www.kde.org $ - $ License: GPL with the following explicit clarification: - This code may be linked against any version of the Qt toolkit - from Troll Tech, Norway. $ - - $Id$ -*/ - -#include "qconfigDB.h" -// #include "debug.h" - -extern "C" { -#include -#include -#include -#include -#include -} - -// #include -#include -#include -#include -#include -#include - -#include "qconfigDB.moc" -#include - -#ifdef KAB_KDEBUG_AREA -#undef KAB_KDEBUG_AREA -#endif - -#define KAB_KDEBUG_AREA 800 - -static bool isComment(TQCString line) -{ - // ############################################################################ - line=line.stripWhiteSpace(); - if(line.isEmpty()) - { - return false; // line is empty but not a comment - } else { - return(line[0]=='#'); - } - // ############################################################################ -} - -static void tokenize(list& res, const TQCString& text, char tr, bool strict=false) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: called." << endl; - int eins=0, zwei=0; - TQCString teil; - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partening -->%" << text.data() << "<--." << endl; - res.erase(res.begin(), res.end()); - // ----- - if(text.isEmpty()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "tokenize: text is an empty string, done." << endl; - return; - } - while(zwei!=-1) - { - teil=""; - zwei=text.find(tr, eins); - if(zwei!=-1) - { - teil=text.mid(eins, zwei-eins); - res.push_back(teil); - } else { // last element - if(!strict) // nur wenn dazwischen Zeichen sind - { - teil=text.mid(eins, text.length()-eins); - res.push_back(teil); - } - } - eins=zwei+1; - // if((unsigned)eins>=text.length()) break; - } - kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partened in " - << res.size() << " parts.\n"; - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: done." << endl; - // ############################################################################ -} - -// TQCString AuthorEmailAddress; // assign your email address to this string - -static TQCString ReadLineFromStream(TQTextStream& stream) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: reading line." << endl; - TQCString line; - // ----- - while(!stream.eof()) - { - line=stream.readLine().ascii(); - if(!line.isEmpty()) - { - if(isComment(line)) - { - line=""; - continue; - } - } - break; - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: line \"" << line.data() << "\" read.\n"; - return line; - // ############################################################################ -} - -// class implementations: - -list QConfigDB::LockFiles; // the lockfiles created by this session - -KeyValueMap::KeyValueMap() - : data(new StringStringMap) -{ - // ########################################################################### - // ########################################################################### -} - -KeyValueMap::KeyValueMap(const KeyValueMap& orig) - : data(new StringStringMap(*orig.data)) -{ - // ########################################################################### - // ########################################################################### -} - -KeyValueMap::~KeyValueMap() -{ - // ########################################################################### - delete data; - // ########################################################################### -} - -bool KeyValueMap::invariant() -{ - return true; -} - -StringStringMap::iterator KeyValueMap::begin() -{ - return data->begin(); -} - -StringStringMap::iterator KeyValueMap::end() -{ - return data->end(); -} - -unsigned int -KeyValueMap::size() const -{ - // ########################################################################### - return data->size(); - // ########################################################################### -} - -void -KeyValueMap::clear() -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::clear: erasing map contents ... " << endl; - // ----- - if(!data->empty()) // erase fails on empty containers! - { - data->erase(data->begin(), data->end()); - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "done." << endl; - // ########################################################################### -} - -bool -KeyValueMap::fill(const TQString& filename, bool force, bool relax) -{ - bool GUARD; GUARD=false; - // ########################################################################### - TQFile file(filename); - TQCString line; - // ----- - if(file.open(IO_ReadOnly)) - { - TQTextStream stream(&file); - // We read/write utf8 strings, so we don't want that TQTextStream uses local8bit - // Latin1 means : no conversion, when giving char*s to a TQTextStream. (DF) - stream.setEncoding(TQTextStream::Latin1); - // ----- - while(!stream.eof()) - { - line=stream.readLine().ascii(); - if(!line.isEmpty() /* && !stream.eof() */ && !isComment(line)) - { - if(!insertLine(line, force, relax, false)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::fill: could not insert line " - << line << ".\n"; // ignore this case further - } - } - } - file.close(); - // ----- - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::fill: cannot open file " << - filename << endl; - return false; - } - // ########################################################################### -} - -bool -KeyValueMap::save(const TQString& filename, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::save: saving data to -->" << - filename << "<--.\n"; - StringStringMap::iterator pos; - TQFile file(filename); - // ----- open file, regarding existence: - if(!force) - { - if(file.exists()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::save: file exists but may not." << endl; - return false; - } - } - if(file.open(IO_WriteOnly)) - { - TQTextStream stream(&file); - stream.setEncoding(TQTextStream::Latin1); // no conversion - stream << "# saved by KeyValueMap object ($Revision$)" << endl; - for(pos=data->begin(); pos!=data->end(); ++pos) - { // values do not get coded here - stream << (*pos).first << '=' << (*pos).second << endl; - } - file.close(); - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::save: could not open file -->%s<-- for saving." << - filename.utf8() << endl; - return false; - } - // ########################################################################### - return true; -} - -bool -KeyValueMap::save(TQTextStream& file, int count) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::save: saving data to given output stream." << endl; - StringStringMap::iterator pos; - bool ret=true; - char* prefix=new char[count+1]; - memset(prefix, ' ', count); - prefix[count]=0; - // ----- - for(pos=data->begin(); pos!=data->end(); ++pos) - { - file << prefix << (*pos).first << '=' << (*pos).second << endl; - } - delete [] prefix; - // ----- - return ret; - // ########################################################################### -} - - -bool -KeyValueMap::erase(const TQCString& key) -{ - // ########################################################################### - bool rc=(data->erase(key)>0); - return rc; - // ########################################################################### -} - - -bool -KeyValueMap::empty() -{ - // ########################################################################### - return data->empty(); - // ########################################################################### -} - -bool -KeyValueMap::parseComplexString -(const TQCString& orig, - int index, // first char to parse - TQCString& result, // string without leading and trailing ".." - int& noOfChars) // no of chars that represented the - const // complex string in the original -{ - bool GUARD; GUARD=false; - // ########################################################################### - int first; - TQCString temp(2*orig.length()); - TQCString mod; - int count=1; - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::parseComplexString: parsing the string -->" - << orig << "<--.\n"; - // ----- - if(orig.isEmpty()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::parseComplexString: string is empty.\n" - " " - "This is no valid complex string." << endl; - return false; - } - // ----- prepare the string: - temp=orig.mid(index, orig.length()-index); // remove everything before index - mod=temp.stripWhiteSpace(); // remove leading and trailing white spaces - // ----- test some conditions: - if(mod.length()<2) - { - kdDebug() << "KeyValueMap::parseComplexString: no pair of brackets " << endl; - return false; - } - if(mod[0]!='"') - { - kdDebug() << "KeyValueMap::parseComplexString: no opening bracket." << endl; - return false; - } - // ----- now parse it: - first=1; // first character after opening bracket - temp=""; - for(;;) - { - if(mod[first]=='\\') - { // handle special characters - ++first; - kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::parseComplexString: found " - "a special character \"%c\".", mod[first]) << endl; - if((unsigned)first==mod.length()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::parseComplexString: " - "string lacks the closing \".\n " - " This is no valid " - "complex string." << endl; - return false; - } - switch(mod[first]) - { - case 't': temp+='\t'; break; - case 'n': temp+='\n'; break; - case '"': temp+='"'; break; - case 'e': temp+="\\e"; break; - case '\\': temp+='\\'; break; - default: - // WORK_TO_DO: implement octal coding here! - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: " - "invalid control character.\n " - " This is no valid complex string." << endl; - return false; - } - count+=2; // this took 2 characters - ++first; - } else { // it is a character - ++count; - if(mod[first]=='"') // end of coded string? - { - break; - } - temp+=mod[first]; - ++first; - } - if((unsigned)first>=mod.length()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: " - "string lacks the closing \".\n " - " This is no valid complex string.\n"; - return false; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA).form( - "KeyValueMap::parseComplexString: finished parsing, no errors, " - "%i characters, %i in string.", count, temp.length()) << endl; - noOfChars=count; - result=temp; - // ########################################################################### - return true; -} - -TQCString -KeyValueMap::makeComplexString(const TQCString& orig) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::makeComplexString: coding the string\n -->" - << orig << - "<--\n into a complex string.\n"; - TQCString temp(2*orig.length()); - unsigned int count; - // ----- - temp+='"'; // opening bracket - for(count=0; count" - <find(key); - // ----- - if(pos==data->end()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "not in KeyValueMap." << endl; - return false; - } else { - value=(*pos).second; - kdDebug(GUARD, KAB_KDEBUG_AREA) << "in KeyValueMap, value is " - << value << endl; - return true; - } - // ########################################################################### -} - -bool -KeyValueMap::insertRaw(const TQCString& key, const TQCString& value, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::insertRaw: inserting uncoded value " - << value << - " for key " << key << endl; - int n=0; - // ----- - if(key.isEmpty()) // empty KEYS are errors: - { - kdDebug() << "KeyValueMap::insertRaw: tried to insert empty key." << endl; - return false; - } - if(force) // entry will be replaced - { - n=data->erase(key); - } - if(data->insert(StringStringMap::value_type(key, value)).second) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: success" - << (n==0 ? "" : " (forced)") << endl; - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: failed, " - "key already in KeyValueMap." << endl; - return false; - } - // ########################################################################### -} - - -// ----------------------------------------------------------------------------- -// HUGE SEPARATOR BETWEEN INTERNAL LOGIC AND EXTENDABLE PAIRS OF GET- AND INSERT -// -METHODS. -// EXTENDABLE MEANS: OTHER DATATYPES CAN BE ADDED HERE. -// ----------------------------------------------------------------------------- - -/* The following functions are the pairs of insert-get-methods for different - * data types. See keyvaluemap.h for the declarations. */ - -// ascii strings: - -bool -KeyValueMap::insert(const TQCString& key, const TQCString& value, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::insert: inserting value\n -->" - << value << - "<-- \"" - " for key\n -->" - << key << - "<--.\n"; - return insertRaw(key, makeComplexString(value), force); - // ########################################################################### -} - -/* Attention: - * This is another insert function that partens lines like "key=value"! - * It is used for reading files and command line parameters easily. - */ - -bool -KeyValueMap::insertLine(TQCString line, bool force, bool relax, bool encode) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::insertLine: inserting line -->"<& values, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: trying to " - "insert int list into map." << endl; - TQCString temp; - TQCString value; - list::const_iterator pos; - // ----- - for(pos=values.begin(); pos!=values.end(); ++pos) - { - temp.setNum(*pos); - value=value+temp+", "; - } - if(!value.isEmpty()) - { // remove last comma and space: - value.remove(value.length()-2, 2); - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: " - "constructed string value is " << value << endl; - return insert(key, value, force); - // ########################################################################### -} - -bool -KeyValueMap::get(const TQCString& key, list& values) const -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: trying to " - "decode int list for key " << key << endl; - kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: " - "attention - list should be empty but is not.\n"; - TQCString value; - list tokens; - list::iterator pos; - int temp; - bool ok; - // ----- - if(!get(key, value)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[int list]: no such key." << endl; - return false; - } - tokenize(tokens, value, ','); - if(tokens.empty()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[int list]: no tokens." << endl; - return false; - } - // ----- - for(pos=tokens.begin(); pos!=tokens.end(); ++pos) - { - temp=(*pos).toInt(&ok); - if(ok) - { - values.push_back(temp); - } else { - kdDebug() << "KeyValueMap::get[int list]: conversion error for " << *pos << endl; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]: done." << endl; - // ########################################################################### - return true; -} - -// (^^^ int lists) -// doubles: - -bool -KeyValueMap::insert(const TQCString& key, const double& value, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::insert[double]: trying to " - "insert value \"%f\" for key\n -->", value) << key << "<--.\n"; - TQCString temp; - // ----- - temp.setNum(value); - return insert(key, temp, force); - // ########################################################################### -} - -bool -KeyValueMap::get(const TQCString& key, double& value) const -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double]: trying to get " - "FLOAT value for key " << key << endl; - TQCString v; - bool ok; - double temp; - // ----- - if(!get(key, v)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int]: key " - <& values) const -{ - bool GUARD; GUARD=false; - kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: " - "attention!\n \"values\" list reference is not " - "empty!" << endl; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: trying to " - "decode string list for key " << key << endl; - TQCString raw, part, value; - int first=1, second=1, i; - // ----- get the string value as a whole: - if(!getRaw(key, raw)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list]: key " - << key << " not in KeyValueMap." << endl; - return false; - } - // ----- - for(;;) - { // ----- parten the string down into a list, find special characters: - second=first; - for(;;) - { - second=raw.find('\\', second); - // ----- this may never be the last and also not the second last - // character in a complex string: - if(second!=-1) - { // ----- check for string end: - // we use "\e" as token for the string-delimiter - if(raw[second+1]=='e' // the right character - && raw[second-1]!='\\') // not escaped - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get" - "[list]: found string end at pos " << - second << endl; - break; - } else { - ++second; - } - } else { - break; - } - } - if(second!=-1) - { - // ----- now second points to the end of the substring: - part="\""+raw.mid(first, second-first)+"\""; - // ----- insert decoded value into the list: - if(parseComplexString(part, 0, value, i)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get" - "[list]: found item " << value << endl; - values.push_back(value); - } else { - kdDebug() << "KeyValueMap::get[list]: parse error." << endl; - return false; - } - if((unsigned)second]: list end found." << endl; - break; - } - } else { // ----- finished: - break; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list]: done." << endl; - return true; - // ########################################################################### -} - -bool -KeyValueMap::insert(const TQCString& key, const list& values, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: " - "coding string list." << endl; - TQCString value="\""; - TQCString temp; - list::const_iterator pos; - // ----- create coded string list: - for(pos=values.begin(); - pos!=values.end(); - pos++) - { // create strings like "abc\efgh\eijk": - temp=makeComplexString(*pos); - temp.remove(0, 1); // remove the leading "\"" - temp.remove(temp.length()-1, 1); // the trailing "\"" - value+=temp; - value+="\\e"; - } - value+="\""; // finish the string - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: result " - "of coding is " << value << endl; - // ----- insert it without coding: - return insertRaw(key, value, force); - // ########################################################################### -} - -// (^^^ lists of strings) -// QStrList-s: - -bool -KeyValueMap::get(const TQCString& key, TQStrList& values) const -{ - bool GUARD; GUARD=false; - kdDebug(!values.isEmpty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: " - "attention!\n \"values\" list reference is not " - "empty!" << endl; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: trying to " - "decode string list for key " << key << endl; - TQCString raw, part, value; - int first=1, second=1, i; - // ----- get the string value as a whole: - if(!getRaw(key, raw)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: key " - << key <<" not in KeyValueMap." << endl; - return false; - } - // ----- - for(;;) - { // ----- parten the string down into a list, find special characters: - second=first; - for(;;) - { - second=raw.find('\\', second); - // ----- this may never be the last and also not the second last - // character in a complex string: - if(second!=-1) - { // ----- check for string end: - // we use "\e" as token for the string-delimiter - if(raw[second+1]=='e' // the right character - && raw[second-1]!='\\') // not escaped - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]:" - " found string end at pos %i." << second << endl; - break; - } else { - ++second; - } - } else { - break; - } - } - if(second!=-1) - { - // ----- now second points to the end of the substring: - part="\""+raw.mid(first, second-first)+"\""; - // ----- insert decoded value into the list: - if(parseComplexString(part, 0, value, i)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: " - "found item " << value << endl; - values.append(value); - } else { - kdDebug() << "KeyValueMap::get[QStrList]: parse error." << endl; - return false; - } - if((unsigned)second& values, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: trying " - "to insert double list into map." << endl; - TQCString buffer; - // TQCString value(30*values.size()); // not usable with Qt 2 - TQCString value; // WORK_TO_DO: how to reserve enough space to avoid growing? - list::const_iterator pos; - // ----- - for(pos=values.begin(); pos!=values.end(); ++pos) - { - buffer.setNum(*pos); - value=value+buffer+", "; - } - if(!value.isEmpty()) - { // remove last comma and space: - value.remove(value.length()-2, 2); - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: " - "constructed string value is " << value << endl; - return insert(key, value, force); - // ########################################################################### -} - -bool -KeyValueMap::get(const TQCString& key, list& values) const -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: trying to " - "decode double list for key " << key << endl; - kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: " - "attention - list should be empty but is not." << endl; - TQCString value; - list tokens; - list::iterator pos; - double temp; - bool ok; - // ----- - if(!get(key, value)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[double list]: no such key." << endl; - return false; - } - // ----- - tokenize(tokens, value, ','); - for(pos=tokens.begin(); pos!=tokens.end(); ++pos) - { - temp=(*pos).toDouble(&ok); - if(ok) - { - values.push_back(temp); - } else { - kdDebug() << "KeyValueMap::get[double list]: conversion error for " - << *pos << endl; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: done." << endl; - // ########################################################################### - return true; -} - -// (^^^ lists of doubles) -// QDates: - -bool -KeyValueMap::insert(const TQCString& key, const TQDate& value, bool force) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: trying to " - "insert TQDate into map." << endl; - list values; - // ----- - if(!value.isValid()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: invalid " - "date, inserting a null date." << endl; - for(int i=0; i<3; ++i) values.push_back(0); - } else { - values.push_back(value.year()); - values.push_back(value.month()); - values.push_back(value.day()); - } - // ----- - return insert(key, values, force); - // ########################################################################### -} - -bool -KeyValueMap::get(const TQCString& key, TQDate& date) const -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QDate]: trying to decode" - " TQDate for key " << key << endl; - list values; - long y, m, d; - TQDate temp; - // ----- - if(!get(key, values)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[QDate]: no such key." << endl; - return false; - } - if(values.size()!=3) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[QDate]: more or less than 3 values." << endl; - return false; - } - y=values.front(); values.pop_front(); - m=values.front(); values.pop_front(); - d=values.front(); - // ----- - if(y!=0 || m!=0 || d!=0) temp.setYMD(y, m, d); // avoid TQDate messages - if(!temp.isValid() && !temp.isNull()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[QDate]: no valid date." << endl; - return false; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "KeyValueMap::get[QDate]: done." << endl; - date=temp; - return true; - } - // ########################################################################### -} - -// (^^^ QDates) -// Section class: - -const int Section::indent_width=2; - -Section::Section() -{ - // ########################################################################### - // ########################################################################### -} - -Section::Section(const KeyValueMap& contents) -{ - // ########################################################################### - keys=contents; - // ########################################################################### -} - -bool -Section::add(const TQCString& name) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::add: adding section \"" - <save(stream, level+1)) - { - kdDebug() << "Section::save: error saving child section \"" << (*pos).first.data() << "\"." << endl; - return false; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::save: saved section \"" - << (*pos).first - << "\".\n"; - } - insertIndentSpace(stream, level); - stream << "[END " << (*pos).first << ']' << endl; - } - if(!keys.empty()) - { - insertIndentSpace(stream, level); - stream << "# key-value-pairs:" << endl; - if(!keys.save(stream, level*indent_width)) - { - kdDebug() << "Section::save: error saving key-value-pairs." << endl; - return false; - } - } - // ----- - return true; - // ########################################################################### -} - -bool -Section::readSection(TQTextStream& file, bool finish) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::readSection: reading section." << endl; - TQCString line; - TQCString name; - Section* temp; - // ----- - for(;;) - { - line=""; - line=ReadLineFromStream(file); - if(isEndOfSection(line)) - { // ----- eof does not matter: - return true; - } else { // ----- verify it: - if(file.eof()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "Section::readSection: EOF, line is \""<readSection(file)) - { - kdDebug() << "Section::readSection: unable to read " - "subsection \"" << name << "\".\n"; - return false; - } - } else { // ----- it has to be a key-value-pair: - if(!keys.insertLine(line, false, true, false)) - { - kdWarning() << "Attention: unable to parse key-value-pair " << endl - << "\t\"" << line << "\"," << endl - << "ignoring and continuing (maybe duplicate declaration of" - << " the key)." - << endl; - } - } - } - // ########################################################################### -} - -bool -Section::isBeginOfSection(TQCString line) -{ - bool GUARD; GUARD=false; - // ########################################################################### - line=line.simplifyWhiteSpace(); - if(line.isEmpty() || line.length()<2) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short " - "or empty line." << endl; - return false; - } - if(line[0]!='[' || line[line.length()-1]!=']') - { - return false; - } - // ----- - if(line.contains("END")) - { - return false; - } else { - return true; - } - // ########################################################################### -} - -bool -Section::isEndOfSection(TQCString line) -{ - bool GUARD; GUARD=false; - // ########################################################################### - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isEndOfSection: is " - << line <<" the end of" - " a section?" << endl; - int first=1, second; - TQCString temp; - // ----- - line=line.simplifyWhiteSpace(); - if(line.isEmpty() || line.length()<2) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short " - "or empty line." << endl; - return false; - } - if(line[0]!='[' || line[line.length()-1]!=']') - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "Section::isBeginOfSection: does not match." << endl; - return false; - } - // ----- find the word inside the brackets: - for(first=1; line[first]==' '; ++first); // find first non-whitespace character - for(second=first; line[second]!=' ' && line[second]!=']'; ++second); - temp=line.mid(first, second-first); - if(temp=="END") - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "Section::isBeginOfSection: yes, it is." << endl; - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "Section::isBeginOfSection: no, it is not." << endl; - return false; - } - // ########################################################################### -} - -TQCString -Section::nameOfSection(const TQCString& line) -{ - bool GUARD; GUARD=false; - // ########################################################################### - int first=1, second; - TQCString temp; - // ----- - temp=line.simplifyWhiteSpace(); - if(temp.isEmpty() || temp.length()<=2) - { // empty section names are not allowed - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "Section::isBeginOfSection: too short or empty line." << endl; - return ""; - } - if(temp[0]!='[' || temp[temp.length()-1]!=']') - { - return ""; - } - // ----- find the word inside the brackets: - for(first=1; temp[first]==' '; ++first); // find first non-whitespace character - for(second=first; temp[second]!=' ' && temp[second]!=']'; ++second); - temp=temp.mid(first, second-first); - if(temp=="END") - { - return ""; - } else { - return temp; - } - // ########################################################################### -} - -bool -Section::clear() -{ - // ########################################################################### - StringSectionMap::iterator pos; - // ----- - for(pos=sections.begin(); pos!=sections.end(); ++pos) - { - if(!(*pos).second->clear()) return false; - delete(*pos).second; - } - // sections.clear(); // seems to be not implemented - sections.erase(sections.begin(), sections.end()); - keys.clear(); - // ----- - return true; - // ########################################################################### -} - -bool -Section::empty() -{ - // ########################################################################### - return keys.empty() && sections.empty(); - // ########################################################################### -} - -Section::StringSectionMap::iterator -Section::sectionsBegin() -{ - // ########################################################################### - return sections.begin(); - // ########################################################################### -} - -Section::StringSectionMap::iterator -Section::sectionsEnd() -{ - // ########################################################################### - return sections.end(); - // ########################################################################### -} - -unsigned int -Section::noOfSections() -{ - // ########################################################################### - return sections.size(); - // ########################################################################### -} - -QConfigDB::QConfigDB(TQWidget* parent, const char* name) - : TQWidget(parent, name), - timer(0), - readonly(true), - locked(false), - mtime(new TQDateTime) -{ - // ########################################################################### - hide(); - // ########################################################################### -} - - -QConfigDB::~QConfigDB() -{ - // ############################################################################ - // disconnect(); - // ----- - if(timer!=0) - { - delete timer; timer=0; - } - if(!clear()) // this will emit changed() a last time - { - kdDebug() << "QConfigDB destructor: cannot remove me." << endl; - } - if(locked) - { - unlock(); - } - // ############################################################################ -} - -bool QConfigDB::invariant() -{ - return true; -} - -bool -QConfigDB::get(const list& key, KeyValueMap*& map) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: trying to get keys ... " << endl; - Section* section=⊤ - list::const_iterator pos; - // ----- - if(key.empty()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "ConfigDB::get: path is empty, returning toplevel section." << endl; - map=top.getKeys(); - return true; - } - for(pos=key.begin(); pos!=key.end(); ++pos) - { - if(!section->find(*pos, section)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "failed,\n at least the element \"" - << *pos << - "\" of " - "the key-list is not declared." << endl; - return false; - } - } - // ----- - map=section->getKeys(); - kdDebug(GUARD, KAB_KDEBUG_AREA) << "success." << endl; - return true; - // ############################################################################ -} - -KeyValueMap* -QConfigDB::get() -{ - // ############################################################################ - return top.getKeys(); - // ############################################################################ -} - -bool -QConfigDB::createSection(const list& key) -{ - // ############################################################################ - Section* section=⊤ - unsigned int index; - list::const_iterator pos; - Section* thenewone; - bool rc; - // ----- - pos=key.begin(); - for(index=0; indexfind(*pos, section)) - { // this section is not declared - Section* temp=new Section; // WORK_TO_DO: memory hole? - if(section->add(*pos, temp)) - { - section=temp; - } else { - delete temp; - return false; - } - } - ++pos; - } - // pos now points to the last element of key, - // section to the parent of the section that will be inserted - thenewone=new Section; - rc=section->add(*pos, thenewone); - return rc; // missing error report! WORK_TO_DO - // ############################################################################ -} - -bool -QConfigDB::clear() -{ - // ############################################################################ - bool rc=top.clear(); - emit(changed(this)); - return rc; - // ############################################################################ -} - -bool -QConfigDB::empty() -{ - // ############################################################################ - return top.empty(); - // ############################################################################ -} - -bool -QConfigDB::createSection(const TQCString& desc) -{ - // ############################################################################ - return createSection(stringToKeylist(desc)); - // ############################################################################ -} - -bool -QConfigDB::get(const TQCString& key, KeyValueMap*& map) -{ - // ############################################################################ - return get(stringToKeylist(key), map); - // ############################################################################ -} - -list -QConfigDB::stringToKeylist(const TQCString& desc) -{ - bool GUARD; GUARD=false; - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::stringToKeylist: parsing path " << desc << endl; - // ############################################################################ - list key; - int first=0, second; - TQCString temp; - // ----- - if(desc.isEmpty()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::stringToKeylist: path is empty." << endl; - return key; - } - for(;;) - { - second=desc.find('/', first); - if(second==-1) - { - if((unsigned)first& key, Section*& section) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: searching section ... " << endl; - Section* temp=⊤ - list::const_iterator pos; - // ----- - for(pos=key.begin(); pos!=key.end(); ++pos) - { - if(!temp->find(*pos, temp)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "failure, no such section."; - return false; - } - } - // ----- - section=temp; - kdDebug(GUARD, KAB_KDEBUG_AREA) << "success, section found." << endl; - return true; - // ############################################################################ -} - -bool -QConfigDB::isRO() -{ - // ############################################################################ - return readonly; - // ############################################################################ -} - -int -QConfigDB::IsLocked(const TQString& file) -{ - bool GUARD; GUARD=false; - // ############################################################################ - TQString lockfile=file+".lock"; - int pid=-1; - // ----- - if(access(TQFile::encodeName(lockfile), F_OK)==0) - { - TQFile f(lockfile); - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n" - << file << - "\nhas a lockfile.\n"; - if(f.open(IO_ReadOnly)) - { - TQTextStream stream(&f); - stream.setEncoding(TQTextStream::Latin1); // no conversion - // ----- - stream >> pid; - if(pid==-1) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file " - "does not contain the ID\n of the process that " - "created it." << endl; - return -1; - } - f.close(); - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::IsLocked: cannot open the lockfile." << endl; - return -1; - } - return pid; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n" - << file << "\nhas no lockfile.\n"; - return 0; - } - // ############################################################################ -} - -bool -QConfigDB::lock() -{ - bool GUARD; GUARD=false; - // ############################################################################ - if(locked) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock (current file): file " - "is already locked by this object." << endl; - return false; - } - if(lock(filename)) - { - locked=true; - return true; - } else { - return false; - } - // ############################################################################ -} - -bool -QConfigDB::lock(const TQString& file) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: locking the file " - << file << endl; - TQString lockfile=file+".lock"; - TQFile f(lockfile); - // ----- - if(access(TQFile::encodeName(lockfile), F_OK)==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: the file is locked by" - " another process." << endl; - return false; - } else { - if(f.open(IO_WriteOnly)) - { - TQTextStream stream(&f); - stream.setEncoding(TQTextStream::Latin1); // no conversion - // ----- - stream << getpid() << endl; - f.close(); - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: unable to create" - " lockfile." << endl; - return false; - } - } - // ----- - LockFiles.push_back(lockfile); - return true; - // ############################################################################ -} - -bool -QConfigDB::unlock() -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unlocking the file " - << filename << endl; - TQString lockfile=filename+".lock"; - list::iterator pos; - // ----- - if(!locked) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: this app did not " - "lock the file!" << endl; - return false; - } - if(access(TQFile::encodeName(lockfile), F_OK | W_OK)==0) - { - if(::remove(TQFile::encodeName(lockfile))==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::unlock: lockfile deleted." << endl; - for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos) - { - if((*pos)==lockfile) break; - } - if(pos!=LockFiles.end()) - { - LockFiles.erase(pos); --pos; - } else { - kdDebug() << "QConfigDB::unlock: file not mentioned in lockfile" << endl; - } - locked=false; - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unable to " - "delete lockfile.n" << endl; - return false; - } - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: the file is not" - " locked or permission has been denied." << endl; - return false; - } - // ############################################################################ -} - -void -QConfigDB::CleanLockFiles(int) -{ - bool GUARD; GUARD=false; - // ############################################################################ - list::iterator pos; - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA).form("QConfigDB::CleanLockFiles: removing %i " - "remaining lockfiles.", LockFiles.size()) << endl; - for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos) - { - if(::remove(TQFile::encodeName(*pos))==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - " " << *pos << " removed.\n"; - LockFiles.erase(pos); --pos; - } else { - kdDebug() << " could not remove " << *pos << endl; - } - } - // ----- - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CleanLockFiles: done." << endl; - // ############################################################################ -} - -void -QConfigDB::watch(bool state) -{ - // ############################################################################ - if(state) - { // start timer - if(timer==0) - { - timer=new TQTimer(this); - connect(timer, TQT_SIGNAL(timeout()), TQT_SLOT(checkFileChanged())); - } - timer->start(1000); - } else { // stop timer - if(timer!=0) - { - timer->stop(); - } - } - // ############################################################################ -} - -bool -QConfigDB::CheckLockFile(const TQString& file) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: called." << endl; - int pid; - // ----- - pid=IsLocked(file); - if(pid==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file is " - "not locked." << endl; - return false; - } - if(pid>0) - { - if(kill(pid, 0)!=0) - { // ----- no such process, we may remove the lockfile: - return false; - } - } - if(pid<0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file has " - "not been created by QConfigDB::lock." << endl; - } - // ----- check system time and creation time of lockfile: - // WORK_TO_DO: not implemented - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: done." << endl; - return true; - // ############################################################################ -} - -bool -QConfigDB::checkFileChanged() -{ - bool GUARD; GUARD=false; - // ############################################################################ - // kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: called." << endl; - if(filename.isEmpty()) - { // ----- false, as file does not exist and thus may be stored anyway - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: no filename." << endl; - return false; - } - TQFileInfo file(filename); - // ----- - if(file.exists()) - { - if(file.lastModified() > *mtime) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::checkFileChanged: file has been changed.n" << endl; - emit(fileChanged()); - return true; - } else { - return false; - } - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: could " - "not stat file, file does not exist." << endl; - if(!mtime->isValid()) - { // the file did never exist for us: - return false; // ... so it has not changed - } else { // it existed, and now it does no more - emit(fileChanged()); - return true; - } - } - // ############################################################################ -} - -bool -QConfigDB::storeFileAge() -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::storeFileAge: called." << endl; - TQFileInfo file(filename); - // ----- - if(file.exists()) - { - *mtime=file.lastModified(); - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::save: could not stat file." << endl; - *mtime=TQDateTime(); // a null date - return false; - } - // ############################################################################ -} - - -bool -QConfigDB::setFileName(const TQString& filename_, bool mustexist, bool readonly_) -{ - bool GUARD; GUARD=false; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: setting filename " - "to \"" - << filename_ <<"\"" << (readonly_ ? " (read only)" : "") << endl; - // ----- remove previous lock: - if(locked) - { - if(!unlock()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: cannot " - "release previous lock." << endl; - return false; - } - } - // ----- remove possible stale lockfile: - if(IsLocked(filename_)!=0 && !CheckLockFile(filename_)) - { // ----- it is stale: - if(::remove(TQFile::encodeName(filename_+".lock"))==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: removed stale lockfile." << endl; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: cannot remove stale lockfile." << endl; - return false; - } - } - // ----- - if(mustexist) - { - if(access(TQFile::encodeName(filename_), readonly_==true ? R_OK : W_OK | R_OK)==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: permission granted." << endl; - if(!readonly_) - { // we need r/w access: - if(lock(filename_)) - { - locked=true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " - "could not lock the file." << endl; - return false; - } - } - readonly=readonly_; - filename=filename_; - storeFileAge(); - return true; - } else { - kdDebug() << "QConfigDB::setFileName: permission denied, " << endl; - return false; - } - } else { - if(access(TQFile::encodeName(filename_), F_OK)==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: file exists." << endl; - if(access(TQFile::encodeName(filename_), W_OK | R_OK)==0) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: permission granted." << endl; - if(!readonly_) - { // we need r/w access: - if(lock(filename_)) - { - locked=true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " - "could not lock the file." << endl; - return false; - } - } - readonly=readonly_; - filename=filename_; - storeFileAge(); - return true; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " - "permission denied, filename not set." << endl; - return false; - } - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: permission granted, new file." << endl; - readonly=readonly_; - filename=filename_; - if(!readonly) - { - if(!lock()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::setFileName: could not lock the file." << endl; - return false; - } - } - storeFileAge(); - return true; - } - } - // ############################################################################ -} - -TQString -QConfigDB::fileName() -{ - // ############################################################################ - return filename; - // ############################################################################ -} - -bool -QConfigDB::save(const char* header, bool force) -{ - bool GUARD; GUARD=true; - // ############################################################################ - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: saving database -->" << filename << "<--.\n"; - bool wasRO=false; - bool rc; - // ----- - if(checkFileChanged()) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: file is newer, not saving." << endl; - return false; - } - if(force && isRO()) - { - if(setFileName(fileName(), true, false)) - { - wasRO=true; - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: switched to (forced) r/w mode." << endl; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: cannot switch to (forced) r/w mode." << endl; - return false; - } - } - // ----- now save it: - if(!isRO()) - { - TQFile file(filename); - if(file.open(IO_WriteOnly)) - { - TQTextStream stream(&file); - stream.setEncoding(TQTextStream::Latin1); // no conversion - // ----- - if(header!=0) - { - stream << "# " << header << endl; - } - stream << '#' << " [File created by QConfigDB object " - << version() << "]" << endl; - if(!top.save(stream)) // traverse tree - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: error saving subsections." << endl; - } - storeFileAge(); - file.close(); - rc=true; - } else { - kdDebug() << "QConfigDB::save: error opening file \"" - << filename << - "\" for writing.\n"; - rc=false; - } - } else { - rc=false; - } - // ----- reset r/o mode: - if(wasRO) // only true if we switched to forced r/w mode here - { - if(setFileName(fileName(), false, true)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: reset (forced) r/w mode." << endl; - } else { - kdDebug(GUARD, KAB_KDEBUG_AREA) << - "QConfigDB::save: cannot reset (forced) r/w mode." << endl; - rc=false; - } - } - // ----- - return rc; - // ############################################################################ -} - -bool -QConfigDB::load() -{ - bool GUARD; GUARD=false ; - // ############################################################################ - TQFile file(filename); - // ----- - if(file.open(IO_ReadOnly)) - { - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: file access OK." << endl; - TQTextStream stream(&file); - stream.setEncoding(TQTextStream::Latin1); // no conversion - // ----- - clear(); - bool rc=top.readSection(stream, false); - storeFileAge(); - file.close(); - emit(changed(this)); - kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: done." << endl; - return rc; - } else { - kdDebug() << "QConfigDB::load: error opening file \"" << filename << "\" for reading." << endl; - return false; - } - // ############################################################################ -} diff --git a/kab/qconfigDB.cpp b/kab/qconfigDB.cpp new file mode 100644 index 000000000..dc77a1e1b --- /dev/null +++ b/kab/qconfigDB.cpp @@ -0,0 +1,2547 @@ +/* the Configuration Database library, Version II + + the TDE addressbook + + $ Author: Mirko Boehm $ + $ Copyright: (C) 1996-2001, Mirko Boehm $ + $ Contact: mirko@kde.org + http://www.kde.org $ + $ License: GPL with the following explicit clarification: + This code may be linked against any version of the Qt toolkit + from Troll Tech, Norway. $ + + $Id$ +*/ + +#include "qconfigDB.h" +// #include "debug.h" + +extern "C" { +#include +#include +#include +#include +#include +} + +// #include +#include +#include +#include +#include +#include + +#include "qconfigDB.moc" +#include + +#ifdef KAB_KDEBUG_AREA +#undef KAB_KDEBUG_AREA +#endif + +#define KAB_KDEBUG_AREA 800 + +static bool isComment(TQCString line) +{ + // ############################################################################ + line=line.stripWhiteSpace(); + if(line.isEmpty()) + { + return false; // line is empty but not a comment + } else { + return(line[0]=='#'); + } + // ############################################################################ +} + +static void tokenize(list& res, const TQCString& text, char tr, bool strict=false) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: called." << endl; + int eins=0, zwei=0; + TQCString teil; + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partening -->%" << text.data() << "<--." << endl; + res.erase(res.begin(), res.end()); + // ----- + if(text.isEmpty()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "tokenize: text is an empty string, done." << endl; + return; + } + while(zwei!=-1) + { + teil=""; + zwei=text.find(tr, eins); + if(zwei!=-1) + { + teil=text.mid(eins, zwei-eins); + res.push_back(teil); + } else { // last element + if(!strict) // nur wenn dazwischen Zeichen sind + { + teil=text.mid(eins, text.length()-eins); + res.push_back(teil); + } + } + eins=zwei+1; + // if((unsigned)eins>=text.length()) break; + } + kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partened in " + << res.size() << " parts.\n"; + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: done." << endl; + // ############################################################################ +} + +// TQCString AuthorEmailAddress; // assign your email address to this string + +static TQCString ReadLineFromStream(TQTextStream& stream) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: reading line." << endl; + TQCString line; + // ----- + while(!stream.eof()) + { + line=stream.readLine().ascii(); + if(!line.isEmpty()) + { + if(isComment(line)) + { + line=""; + continue; + } + } + break; + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: line \"" << line.data() << "\" read.\n"; + return line; + // ############################################################################ +} + +// class implementations: + +list QConfigDB::LockFiles; // the lockfiles created by this session + +KeyValueMap::KeyValueMap() + : data(new StringStringMap) +{ + // ########################################################################### + // ########################################################################### +} + +KeyValueMap::KeyValueMap(const KeyValueMap& orig) + : data(new StringStringMap(*orig.data)) +{ + // ########################################################################### + // ########################################################################### +} + +KeyValueMap::~KeyValueMap() +{ + // ########################################################################### + delete data; + // ########################################################################### +} + +bool KeyValueMap::invariant() +{ + return true; +} + +StringStringMap::iterator KeyValueMap::begin() +{ + return data->begin(); +} + +StringStringMap::iterator KeyValueMap::end() +{ + return data->end(); +} + +unsigned int +KeyValueMap::size() const +{ + // ########################################################################### + return data->size(); + // ########################################################################### +} + +void +KeyValueMap::clear() +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::clear: erasing map contents ... " << endl; + // ----- + if(!data->empty()) // erase fails on empty containers! + { + data->erase(data->begin(), data->end()); + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "done." << endl; + // ########################################################################### +} + +bool +KeyValueMap::fill(const TQString& filename, bool force, bool relax) +{ + bool GUARD; GUARD=false; + // ########################################################################### + TQFile file(filename); + TQCString line; + // ----- + if(file.open(IO_ReadOnly)) + { + TQTextStream stream(&file); + // We read/write utf8 strings, so we don't want that TQTextStream uses local8bit + // Latin1 means : no conversion, when giving char*s to a TQTextStream. (DF) + stream.setEncoding(TQTextStream::Latin1); + // ----- + while(!stream.eof()) + { + line=stream.readLine().ascii(); + if(!line.isEmpty() /* && !stream.eof() */ && !isComment(line)) + { + if(!insertLine(line, force, relax, false)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::fill: could not insert line " + << line << ".\n"; // ignore this case further + } + } + } + file.close(); + // ----- + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::fill: cannot open file " << + filename << endl; + return false; + } + // ########################################################################### +} + +bool +KeyValueMap::save(const TQString& filename, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::save: saving data to -->" << + filename << "<--.\n"; + StringStringMap::iterator pos; + TQFile file(filename); + // ----- open file, regarding existence: + if(!force) + { + if(file.exists()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::save: file exists but may not." << endl; + return false; + } + } + if(file.open(IO_WriteOnly)) + { + TQTextStream stream(&file); + stream.setEncoding(TQTextStream::Latin1); // no conversion + stream << "# saved by KeyValueMap object ($Revision$)" << endl; + for(pos=data->begin(); pos!=data->end(); ++pos) + { // values do not get coded here + stream << (*pos).first << '=' << (*pos).second << endl; + } + file.close(); + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::save: could not open file -->%s<-- for saving." << + filename.utf8() << endl; + return false; + } + // ########################################################################### + return true; +} + +bool +KeyValueMap::save(TQTextStream& file, int count) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::save: saving data to given output stream." << endl; + StringStringMap::iterator pos; + bool ret=true; + char* prefix=new char[count+1]; + memset(prefix, ' ', count); + prefix[count]=0; + // ----- + for(pos=data->begin(); pos!=data->end(); ++pos) + { + file << prefix << (*pos).first << '=' << (*pos).second << endl; + } + delete [] prefix; + // ----- + return ret; + // ########################################################################### +} + + +bool +KeyValueMap::erase(const TQCString& key) +{ + // ########################################################################### + bool rc=(data->erase(key)>0); + return rc; + // ########################################################################### +} + + +bool +KeyValueMap::empty() +{ + // ########################################################################### + return data->empty(); + // ########################################################################### +} + +bool +KeyValueMap::parseComplexString +(const TQCString& orig, + int index, // first char to parse + TQCString& result, // string without leading and trailing ".." + int& noOfChars) // no of chars that represented the + const // complex string in the original +{ + bool GUARD; GUARD=false; + // ########################################################################### + int first; + TQCString temp(2*orig.length()); + TQCString mod; + int count=1; + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::parseComplexString: parsing the string -->" + << orig << "<--.\n"; + // ----- + if(orig.isEmpty()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::parseComplexString: string is empty.\n" + " " + "This is no valid complex string." << endl; + return false; + } + // ----- prepare the string: + temp=orig.mid(index, orig.length()-index); // remove everything before index + mod=temp.stripWhiteSpace(); // remove leading and trailing white spaces + // ----- test some conditions: + if(mod.length()<2) + { + kdDebug() << "KeyValueMap::parseComplexString: no pair of brackets " << endl; + return false; + } + if(mod[0]!='"') + { + kdDebug() << "KeyValueMap::parseComplexString: no opening bracket." << endl; + return false; + } + // ----- now parse it: + first=1; // first character after opening bracket + temp=""; + for(;;) + { + if(mod[first]=='\\') + { // handle special characters + ++first; + kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::parseComplexString: found " + "a special character \"%c\".", mod[first]) << endl; + if((unsigned)first==mod.length()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::parseComplexString: " + "string lacks the closing \".\n " + " This is no valid " + "complex string." << endl; + return false; + } + switch(mod[first]) + { + case 't': temp+='\t'; break; + case 'n': temp+='\n'; break; + case '"': temp+='"'; break; + case 'e': temp+="\\e"; break; + case '\\': temp+='\\'; break; + default: + // WORK_TO_DO: implement octal coding here! + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: " + "invalid control character.\n " + " This is no valid complex string." << endl; + return false; + } + count+=2; // this took 2 characters + ++first; + } else { // it is a character + ++count; + if(mod[first]=='"') // end of coded string? + { + break; + } + temp+=mod[first]; + ++first; + } + if((unsigned)first>=mod.length()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: " + "string lacks the closing \".\n " + " This is no valid complex string.\n"; + return false; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA).form( + "KeyValueMap::parseComplexString: finished parsing, no errors, " + "%i characters, %i in string.", count, temp.length()) << endl; + noOfChars=count; + result=temp; + // ########################################################################### + return true; +} + +TQCString +KeyValueMap::makeComplexString(const TQCString& orig) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::makeComplexString: coding the string\n -->" + << orig << + "<--\n into a complex string.\n"; + TQCString temp(2*orig.length()); + unsigned int count; + // ----- + temp+='"'; // opening bracket + for(count=0; count" + <find(key); + // ----- + if(pos==data->end()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "not in KeyValueMap." << endl; + return false; + } else { + value=(*pos).second; + kdDebug(GUARD, KAB_KDEBUG_AREA) << "in KeyValueMap, value is " + << value << endl; + return true; + } + // ########################################################################### +} + +bool +KeyValueMap::insertRaw(const TQCString& key, const TQCString& value, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::insertRaw: inserting uncoded value " + << value << + " for key " << key << endl; + int n=0; + // ----- + if(key.isEmpty()) // empty KEYS are errors: + { + kdDebug() << "KeyValueMap::insertRaw: tried to insert empty key." << endl; + return false; + } + if(force) // entry will be replaced + { + n=data->erase(key); + } + if(data->insert(StringStringMap::value_type(key, value)).second) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: success" + << (n==0 ? "" : " (forced)") << endl; + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: failed, " + "key already in KeyValueMap." << endl; + return false; + } + // ########################################################################### +} + + +// ----------------------------------------------------------------------------- +// HUGE SEPARATOR BETWEEN INTERNAL LOGIC AND EXTENDABLE PAIRS OF GET- AND INSERT +// -METHODS. +// EXTENDABLE MEANS: OTHER DATATYPES CAN BE ADDED HERE. +// ----------------------------------------------------------------------------- + +/* The following functions are the pairs of insert-get-methods for different + * data types. See keyvaluemap.h for the declarations. */ + +// ascii strings: + +bool +KeyValueMap::insert(const TQCString& key, const TQCString& value, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::insert: inserting value\n -->" + << value << + "<-- \"" + " for key\n -->" + << key << + "<--.\n"; + return insertRaw(key, makeComplexString(value), force); + // ########################################################################### +} + +/* Attention: + * This is another insert function that partens lines like "key=value"! + * It is used for reading files and command line parameters easily. + */ + +bool +KeyValueMap::insertLine(TQCString line, bool force, bool relax, bool encode) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::insertLine: inserting line -->"<& values, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: trying to " + "insert int list into map." << endl; + TQCString temp; + TQCString value; + list::const_iterator pos; + // ----- + for(pos=values.begin(); pos!=values.end(); ++pos) + { + temp.setNum(*pos); + value=value+temp+", "; + } + if(!value.isEmpty()) + { // remove last comma and space: + value.remove(value.length()-2, 2); + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: " + "constructed string value is " << value << endl; + return insert(key, value, force); + // ########################################################################### +} + +bool +KeyValueMap::get(const TQCString& key, list& values) const +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: trying to " + "decode int list for key " << key << endl; + kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: " + "attention - list should be empty but is not.\n"; + TQCString value; + list tokens; + list::iterator pos; + int temp; + bool ok; + // ----- + if(!get(key, value)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[int list]: no such key." << endl; + return false; + } + tokenize(tokens, value, ','); + if(tokens.empty()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[int list]: no tokens." << endl; + return false; + } + // ----- + for(pos=tokens.begin(); pos!=tokens.end(); ++pos) + { + temp=(*pos).toInt(&ok); + if(ok) + { + values.push_back(temp); + } else { + kdDebug() << "KeyValueMap::get[int list]: conversion error for " << *pos << endl; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]: done." << endl; + // ########################################################################### + return true; +} + +// (^^^ int lists) +// doubles: + +bool +KeyValueMap::insert(const TQCString& key, const double& value, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::insert[double]: trying to " + "insert value \"%f\" for key\n -->", value) << key << "<--.\n"; + TQCString temp; + // ----- + temp.setNum(value); + return insert(key, temp, force); + // ########################################################################### +} + +bool +KeyValueMap::get(const TQCString& key, double& value) const +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double]: trying to get " + "FLOAT value for key " << key << endl; + TQCString v; + bool ok; + double temp; + // ----- + if(!get(key, v)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int]: key " + <& values) const +{ + bool GUARD; GUARD=false; + kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: " + "attention!\n \"values\" list reference is not " + "empty!" << endl; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: trying to " + "decode string list for key " << key << endl; + TQCString raw, part, value; + int first=1, second=1, i; + // ----- get the string value as a whole: + if(!getRaw(key, raw)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list]: key " + << key << " not in KeyValueMap." << endl; + return false; + } + // ----- + for(;;) + { // ----- parten the string down into a list, find special characters: + second=first; + for(;;) + { + second=raw.find('\\', second); + // ----- this may never be the last and also not the second last + // character in a complex string: + if(second!=-1) + { // ----- check for string end: + // we use "\e" as token for the string-delimiter + if(raw[second+1]=='e' // the right character + && raw[second-1]!='\\') // not escaped + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get" + "[list]: found string end at pos " << + second << endl; + break; + } else { + ++second; + } + } else { + break; + } + } + if(second!=-1) + { + // ----- now second points to the end of the substring: + part="\""+raw.mid(first, second-first)+"\""; + // ----- insert decoded value into the list: + if(parseComplexString(part, 0, value, i)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get" + "[list]: found item " << value << endl; + values.push_back(value); + } else { + kdDebug() << "KeyValueMap::get[list]: parse error." << endl; + return false; + } + if((unsigned)second]: list end found." << endl; + break; + } + } else { // ----- finished: + break; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list]: done." << endl; + return true; + // ########################################################################### +} + +bool +KeyValueMap::insert(const TQCString& key, const list& values, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: " + "coding string list." << endl; + TQCString value="\""; + TQCString temp; + list::const_iterator pos; + // ----- create coded string list: + for(pos=values.begin(); + pos!=values.end(); + pos++) + { // create strings like "abc\efgh\eijk": + temp=makeComplexString(*pos); + temp.remove(0, 1); // remove the leading "\"" + temp.remove(temp.length()-1, 1); // the trailing "\"" + value+=temp; + value+="\\e"; + } + value+="\""; // finish the string + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: result " + "of coding is " << value << endl; + // ----- insert it without coding: + return insertRaw(key, value, force); + // ########################################################################### +} + +// (^^^ lists of strings) +// QStrList-s: + +bool +KeyValueMap::get(const TQCString& key, TQStrList& values) const +{ + bool GUARD; GUARD=false; + kdDebug(!values.isEmpty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: " + "attention!\n \"values\" list reference is not " + "empty!" << endl; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: trying to " + "decode string list for key " << key << endl; + TQCString raw, part, value; + int first=1, second=1, i; + // ----- get the string value as a whole: + if(!getRaw(key, raw)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: key " + << key <<" not in KeyValueMap." << endl; + return false; + } + // ----- + for(;;) + { // ----- parten the string down into a list, find special characters: + second=first; + for(;;) + { + second=raw.find('\\', second); + // ----- this may never be the last and also not the second last + // character in a complex string: + if(second!=-1) + { // ----- check for string end: + // we use "\e" as token for the string-delimiter + if(raw[second+1]=='e' // the right character + && raw[second-1]!='\\') // not escaped + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]:" + " found string end at pos %i." << second << endl; + break; + } else { + ++second; + } + } else { + break; + } + } + if(second!=-1) + { + // ----- now second points to the end of the substring: + part="\""+raw.mid(first, second-first)+"\""; + // ----- insert decoded value into the list: + if(parseComplexString(part, 0, value, i)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: " + "found item " << value << endl; + values.append(value); + } else { + kdDebug() << "KeyValueMap::get[QStrList]: parse error." << endl; + return false; + } + if((unsigned)second& values, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: trying " + "to insert double list into map." << endl; + TQCString buffer; + // TQCString value(30*values.size()); // not usable with Qt 2 + TQCString value; // WORK_TO_DO: how to reserve enough space to avoid growing? + list::const_iterator pos; + // ----- + for(pos=values.begin(); pos!=values.end(); ++pos) + { + buffer.setNum(*pos); + value=value+buffer+", "; + } + if(!value.isEmpty()) + { // remove last comma and space: + value.remove(value.length()-2, 2); + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: " + "constructed string value is " << value << endl; + return insert(key, value, force); + // ########################################################################### +} + +bool +KeyValueMap::get(const TQCString& key, list& values) const +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: trying to " + "decode double list for key " << key << endl; + kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: " + "attention - list should be empty but is not." << endl; + TQCString value; + list tokens; + list::iterator pos; + double temp; + bool ok; + // ----- + if(!get(key, value)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[double list]: no such key." << endl; + return false; + } + // ----- + tokenize(tokens, value, ','); + for(pos=tokens.begin(); pos!=tokens.end(); ++pos) + { + temp=(*pos).toDouble(&ok); + if(ok) + { + values.push_back(temp); + } else { + kdDebug() << "KeyValueMap::get[double list]: conversion error for " + << *pos << endl; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: done." << endl; + // ########################################################################### + return true; +} + +// (^^^ lists of doubles) +// QDates: + +bool +KeyValueMap::insert(const TQCString& key, const TQDate& value, bool force) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: trying to " + "insert TQDate into map." << endl; + list values; + // ----- + if(!value.isValid()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: invalid " + "date, inserting a null date." << endl; + for(int i=0; i<3; ++i) values.push_back(0); + } else { + values.push_back(value.year()); + values.push_back(value.month()); + values.push_back(value.day()); + } + // ----- + return insert(key, values, force); + // ########################################################################### +} + +bool +KeyValueMap::get(const TQCString& key, TQDate& date) const +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QDate]: trying to decode" + " TQDate for key " << key << endl; + list values; + long y, m, d; + TQDate temp; + // ----- + if(!get(key, values)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[QDate]: no such key." << endl; + return false; + } + if(values.size()!=3) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[QDate]: more or less than 3 values." << endl; + return false; + } + y=values.front(); values.pop_front(); + m=values.front(); values.pop_front(); + d=values.front(); + // ----- + if(y!=0 || m!=0 || d!=0) temp.setYMD(y, m, d); // avoid TQDate messages + if(!temp.isValid() && !temp.isNull()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[QDate]: no valid date." << endl; + return false; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "KeyValueMap::get[QDate]: done." << endl; + date=temp; + return true; + } + // ########################################################################### +} + +// (^^^ QDates) +// Section class: + +const int Section::indent_width=2; + +Section::Section() +{ + // ########################################################################### + // ########################################################################### +} + +Section::Section(const KeyValueMap& contents) +{ + // ########################################################################### + keys=contents; + // ########################################################################### +} + +bool +Section::add(const TQCString& name) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::add: adding section \"" + <save(stream, level+1)) + { + kdDebug() << "Section::save: error saving child section \"" << (*pos).first.data() << "\"." << endl; + return false; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::save: saved section \"" + << (*pos).first + << "\".\n"; + } + insertIndentSpace(stream, level); + stream << "[END " << (*pos).first << ']' << endl; + } + if(!keys.empty()) + { + insertIndentSpace(stream, level); + stream << "# key-value-pairs:" << endl; + if(!keys.save(stream, level*indent_width)) + { + kdDebug() << "Section::save: error saving key-value-pairs." << endl; + return false; + } + } + // ----- + return true; + // ########################################################################### +} + +bool +Section::readSection(TQTextStream& file, bool finish) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::readSection: reading section." << endl; + TQCString line; + TQCString name; + Section* temp; + // ----- + for(;;) + { + line=""; + line=ReadLineFromStream(file); + if(isEndOfSection(line)) + { // ----- eof does not matter: + return true; + } else { // ----- verify it: + if(file.eof()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "Section::readSection: EOF, line is \""<readSection(file)) + { + kdDebug() << "Section::readSection: unable to read " + "subsection \"" << name << "\".\n"; + return false; + } + } else { // ----- it has to be a key-value-pair: + if(!keys.insertLine(line, false, true, false)) + { + kdWarning() << "Attention: unable to parse key-value-pair " << endl + << "\t\"" << line << "\"," << endl + << "ignoring and continuing (maybe duplicate declaration of" + << " the key)." + << endl; + } + } + } + // ########################################################################### +} + +bool +Section::isBeginOfSection(TQCString line) +{ + bool GUARD; GUARD=false; + // ########################################################################### + line=line.simplifyWhiteSpace(); + if(line.isEmpty() || line.length()<2) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short " + "or empty line." << endl; + return false; + } + if(line[0]!='[' || line[line.length()-1]!=']') + { + return false; + } + // ----- + if(line.contains("END")) + { + return false; + } else { + return true; + } + // ########################################################################### +} + +bool +Section::isEndOfSection(TQCString line) +{ + bool GUARD; GUARD=false; + // ########################################################################### + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isEndOfSection: is " + << line <<" the end of" + " a section?" << endl; + int first=1, second; + TQCString temp; + // ----- + line=line.simplifyWhiteSpace(); + if(line.isEmpty() || line.length()<2) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short " + "or empty line." << endl; + return false; + } + if(line[0]!='[' || line[line.length()-1]!=']') + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "Section::isBeginOfSection: does not match." << endl; + return false; + } + // ----- find the word inside the brackets: + for(first=1; line[first]==' '; ++first); // find first non-whitespace character + for(second=first; line[second]!=' ' && line[second]!=']'; ++second); + temp=line.mid(first, second-first); + if(temp=="END") + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "Section::isBeginOfSection: yes, it is." << endl; + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "Section::isBeginOfSection: no, it is not." << endl; + return false; + } + // ########################################################################### +} + +TQCString +Section::nameOfSection(const TQCString& line) +{ + bool GUARD; GUARD=false; + // ########################################################################### + int first=1, second; + TQCString temp; + // ----- + temp=line.simplifyWhiteSpace(); + if(temp.isEmpty() || temp.length()<=2) + { // empty section names are not allowed + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "Section::isBeginOfSection: too short or empty line." << endl; + return ""; + } + if(temp[0]!='[' || temp[temp.length()-1]!=']') + { + return ""; + } + // ----- find the word inside the brackets: + for(first=1; temp[first]==' '; ++first); // find first non-whitespace character + for(second=first; temp[second]!=' ' && temp[second]!=']'; ++second); + temp=temp.mid(first, second-first); + if(temp=="END") + { + return ""; + } else { + return temp; + } + // ########################################################################### +} + +bool +Section::clear() +{ + // ########################################################################### + StringSectionMap::iterator pos; + // ----- + for(pos=sections.begin(); pos!=sections.end(); ++pos) + { + if(!(*pos).second->clear()) return false; + delete(*pos).second; + } + // sections.clear(); // seems to be not implemented + sections.erase(sections.begin(), sections.end()); + keys.clear(); + // ----- + return true; + // ########################################################################### +} + +bool +Section::empty() +{ + // ########################################################################### + return keys.empty() && sections.empty(); + // ########################################################################### +} + +Section::StringSectionMap::iterator +Section::sectionsBegin() +{ + // ########################################################################### + return sections.begin(); + // ########################################################################### +} + +Section::StringSectionMap::iterator +Section::sectionsEnd() +{ + // ########################################################################### + return sections.end(); + // ########################################################################### +} + +unsigned int +Section::noOfSections() +{ + // ########################################################################### + return sections.size(); + // ########################################################################### +} + +QConfigDB::QConfigDB(TQWidget* parent, const char* name) + : TQWidget(parent, name), + timer(0), + readonly(true), + locked(false), + mtime(new TQDateTime) +{ + // ########################################################################### + hide(); + // ########################################################################### +} + + +QConfigDB::~QConfigDB() +{ + // ############################################################################ + // disconnect(); + // ----- + if(timer!=0) + { + delete timer; timer=0; + } + if(!clear()) // this will emit changed() a last time + { + kdDebug() << "QConfigDB destructor: cannot remove me." << endl; + } + if(locked) + { + unlock(); + } + // ############################################################################ +} + +bool QConfigDB::invariant() +{ + return true; +} + +bool +QConfigDB::get(const list& key, KeyValueMap*& map) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: trying to get keys ... " << endl; + Section* section=⊤ + list::const_iterator pos; + // ----- + if(key.empty()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "ConfigDB::get: path is empty, returning toplevel section." << endl; + map=top.getKeys(); + return true; + } + for(pos=key.begin(); pos!=key.end(); ++pos) + { + if(!section->find(*pos, section)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "failed,\n at least the element \"" + << *pos << + "\" of " + "the key-list is not declared." << endl; + return false; + } + } + // ----- + map=section->getKeys(); + kdDebug(GUARD, KAB_KDEBUG_AREA) << "success." << endl; + return true; + // ############################################################################ +} + +KeyValueMap* +QConfigDB::get() +{ + // ############################################################################ + return top.getKeys(); + // ############################################################################ +} + +bool +QConfigDB::createSection(const list& key) +{ + // ############################################################################ + Section* section=⊤ + unsigned int index; + list::const_iterator pos; + Section* thenewone; + bool rc; + // ----- + pos=key.begin(); + for(index=0; indexfind(*pos, section)) + { // this section is not declared + Section* temp=new Section; // WORK_TO_DO: memory hole? + if(section->add(*pos, temp)) + { + section=temp; + } else { + delete temp; + return false; + } + } + ++pos; + } + // pos now points to the last element of key, + // section to the parent of the section that will be inserted + thenewone=new Section; + rc=section->add(*pos, thenewone); + return rc; // missing error report! WORK_TO_DO + // ############################################################################ +} + +bool +QConfigDB::clear() +{ + // ############################################################################ + bool rc=top.clear(); + emit(changed(this)); + return rc; + // ############################################################################ +} + +bool +QConfigDB::empty() +{ + // ############################################################################ + return top.empty(); + // ############################################################################ +} + +bool +QConfigDB::createSection(const TQCString& desc) +{ + // ############################################################################ + return createSection(stringToKeylist(desc)); + // ############################################################################ +} + +bool +QConfigDB::get(const TQCString& key, KeyValueMap*& map) +{ + // ############################################################################ + return get(stringToKeylist(key), map); + // ############################################################################ +} + +list +QConfigDB::stringToKeylist(const TQCString& desc) +{ + bool GUARD; GUARD=false; + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::stringToKeylist: parsing path " << desc << endl; + // ############################################################################ + list key; + int first=0, second; + TQCString temp; + // ----- + if(desc.isEmpty()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::stringToKeylist: path is empty." << endl; + return key; + } + for(;;) + { + second=desc.find('/', first); + if(second==-1) + { + if((unsigned)first& key, Section*& section) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: searching section ... " << endl; + Section* temp=⊤ + list::const_iterator pos; + // ----- + for(pos=key.begin(); pos!=key.end(); ++pos) + { + if(!temp->find(*pos, temp)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "failure, no such section."; + return false; + } + } + // ----- + section=temp; + kdDebug(GUARD, KAB_KDEBUG_AREA) << "success, section found." << endl; + return true; + // ############################################################################ +} + +bool +QConfigDB::isRO() +{ + // ############################################################################ + return readonly; + // ############################################################################ +} + +int +QConfigDB::IsLocked(const TQString& file) +{ + bool GUARD; GUARD=false; + // ############################################################################ + TQString lockfile=file+".lock"; + int pid=-1; + // ----- + if(access(TQFile::encodeName(lockfile), F_OK)==0) + { + TQFile f(lockfile); + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n" + << file << + "\nhas a lockfile.\n"; + if(f.open(IO_ReadOnly)) + { + TQTextStream stream(&f); + stream.setEncoding(TQTextStream::Latin1); // no conversion + // ----- + stream >> pid; + if(pid==-1) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file " + "does not contain the ID\n of the process that " + "created it." << endl; + return -1; + } + f.close(); + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::IsLocked: cannot open the lockfile." << endl; + return -1; + } + return pid; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n" + << file << "\nhas no lockfile.\n"; + return 0; + } + // ############################################################################ +} + +bool +QConfigDB::lock() +{ + bool GUARD; GUARD=false; + // ############################################################################ + if(locked) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock (current file): file " + "is already locked by this object." << endl; + return false; + } + if(lock(filename)) + { + locked=true; + return true; + } else { + return false; + } + // ############################################################################ +} + +bool +QConfigDB::lock(const TQString& file) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: locking the file " + << file << endl; + TQString lockfile=file+".lock"; + TQFile f(lockfile); + // ----- + if(access(TQFile::encodeName(lockfile), F_OK)==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: the file is locked by" + " another process." << endl; + return false; + } else { + if(f.open(IO_WriteOnly)) + { + TQTextStream stream(&f); + stream.setEncoding(TQTextStream::Latin1); // no conversion + // ----- + stream << getpid() << endl; + f.close(); + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: unable to create" + " lockfile." << endl; + return false; + } + } + // ----- + LockFiles.push_back(lockfile); + return true; + // ############################################################################ +} + +bool +QConfigDB::unlock() +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unlocking the file " + << filename << endl; + TQString lockfile=filename+".lock"; + list::iterator pos; + // ----- + if(!locked) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: this app did not " + "lock the file!" << endl; + return false; + } + if(access(TQFile::encodeName(lockfile), F_OK | W_OK)==0) + { + if(::remove(TQFile::encodeName(lockfile))==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::unlock: lockfile deleted." << endl; + for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos) + { + if((*pos)==lockfile) break; + } + if(pos!=LockFiles.end()) + { + LockFiles.erase(pos); --pos; + } else { + kdDebug() << "QConfigDB::unlock: file not mentioned in lockfile" << endl; + } + locked=false; + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unable to " + "delete lockfile.n" << endl; + return false; + } + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: the file is not" + " locked or permission has been denied." << endl; + return false; + } + // ############################################################################ +} + +void +QConfigDB::CleanLockFiles(int) +{ + bool GUARD; GUARD=false; + // ############################################################################ + list::iterator pos; + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA).form("QConfigDB::CleanLockFiles: removing %i " + "remaining lockfiles.", LockFiles.size()) << endl; + for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos) + { + if(::remove(TQFile::encodeName(*pos))==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + " " << *pos << " removed.\n"; + LockFiles.erase(pos); --pos; + } else { + kdDebug() << " could not remove " << *pos << endl; + } + } + // ----- + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CleanLockFiles: done." << endl; + // ############################################################################ +} + +void +QConfigDB::watch(bool state) +{ + // ############################################################################ + if(state) + { // start timer + if(timer==0) + { + timer=new TQTimer(this); + connect(timer, TQT_SIGNAL(timeout()), TQT_SLOT(checkFileChanged())); + } + timer->start(1000); + } else { // stop timer + if(timer!=0) + { + timer->stop(); + } + } + // ############################################################################ +} + +bool +QConfigDB::CheckLockFile(const TQString& file) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: called." << endl; + int pid; + // ----- + pid=IsLocked(file); + if(pid==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file is " + "not locked." << endl; + return false; + } + if(pid>0) + { + if(kill(pid, 0)!=0) + { // ----- no such process, we may remove the lockfile: + return false; + } + } + if(pid<0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file has " + "not been created by QConfigDB::lock." << endl; + } + // ----- check system time and creation time of lockfile: + // WORK_TO_DO: not implemented + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: done." << endl; + return true; + // ############################################################################ +} + +bool +QConfigDB::checkFileChanged() +{ + bool GUARD; GUARD=false; + // ############################################################################ + // kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: called." << endl; + if(filename.isEmpty()) + { // ----- false, as file does not exist and thus may be stored anyway + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: no filename." << endl; + return false; + } + TQFileInfo file(filename); + // ----- + if(file.exists()) + { + if(file.lastModified() > *mtime) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::checkFileChanged: file has been changed.n" << endl; + emit(fileChanged()); + return true; + } else { + return false; + } + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: could " + "not stat file, file does not exist." << endl; + if(!mtime->isValid()) + { // the file did never exist for us: + return false; // ... so it has not changed + } else { // it existed, and now it does no more + emit(fileChanged()); + return true; + } + } + // ############################################################################ +} + +bool +QConfigDB::storeFileAge() +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::storeFileAge: called." << endl; + TQFileInfo file(filename); + // ----- + if(file.exists()) + { + *mtime=file.lastModified(); + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::save: could not stat file." << endl; + *mtime=TQDateTime(); // a null date + return false; + } + // ############################################################################ +} + + +bool +QConfigDB::setFileName(const TQString& filename_, bool mustexist, bool readonly_) +{ + bool GUARD; GUARD=false; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: setting filename " + "to \"" + << filename_ <<"\"" << (readonly_ ? " (read only)" : "") << endl; + // ----- remove previous lock: + if(locked) + { + if(!unlock()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: cannot " + "release previous lock." << endl; + return false; + } + } + // ----- remove possible stale lockfile: + if(IsLocked(filename_)!=0 && !CheckLockFile(filename_)) + { // ----- it is stale: + if(::remove(TQFile::encodeName(filename_+".lock"))==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: removed stale lockfile." << endl; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: cannot remove stale lockfile." << endl; + return false; + } + } + // ----- + if(mustexist) + { + if(access(TQFile::encodeName(filename_), readonly_==true ? R_OK : W_OK | R_OK)==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: permission granted." << endl; + if(!readonly_) + { // we need r/w access: + if(lock(filename_)) + { + locked=true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " + "could not lock the file." << endl; + return false; + } + } + readonly=readonly_; + filename=filename_; + storeFileAge(); + return true; + } else { + kdDebug() << "QConfigDB::setFileName: permission denied, " << endl; + return false; + } + } else { + if(access(TQFile::encodeName(filename_), F_OK)==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: file exists." << endl; + if(access(TQFile::encodeName(filename_), W_OK | R_OK)==0) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: permission granted." << endl; + if(!readonly_) + { // we need r/w access: + if(lock(filename_)) + { + locked=true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " + "could not lock the file." << endl; + return false; + } + } + readonly=readonly_; + filename=filename_; + storeFileAge(); + return true; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: " + "permission denied, filename not set." << endl; + return false; + } + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: permission granted, new file." << endl; + readonly=readonly_; + filename=filename_; + if(!readonly) + { + if(!lock()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::setFileName: could not lock the file." << endl; + return false; + } + } + storeFileAge(); + return true; + } + } + // ############################################################################ +} + +TQString +QConfigDB::fileName() +{ + // ############################################################################ + return filename; + // ############################################################################ +} + +bool +QConfigDB::save(const char* header, bool force) +{ + bool GUARD; GUARD=true; + // ############################################################################ + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: saving database -->" << filename << "<--.\n"; + bool wasRO=false; + bool rc; + // ----- + if(checkFileChanged()) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: file is newer, not saving." << endl; + return false; + } + if(force && isRO()) + { + if(setFileName(fileName(), true, false)) + { + wasRO=true; + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: switched to (forced) r/w mode." << endl; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: cannot switch to (forced) r/w mode." << endl; + return false; + } + } + // ----- now save it: + if(!isRO()) + { + TQFile file(filename); + if(file.open(IO_WriteOnly)) + { + TQTextStream stream(&file); + stream.setEncoding(TQTextStream::Latin1); // no conversion + // ----- + if(header!=0) + { + stream << "# " << header << endl; + } + stream << '#' << " [File created by QConfigDB object " + << version() << "]" << endl; + if(!top.save(stream)) // traverse tree + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: error saving subsections." << endl; + } + storeFileAge(); + file.close(); + rc=true; + } else { + kdDebug() << "QConfigDB::save: error opening file \"" + << filename << + "\" for writing.\n"; + rc=false; + } + } else { + rc=false; + } + // ----- reset r/o mode: + if(wasRO) // only true if we switched to forced r/w mode here + { + if(setFileName(fileName(), false, true)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: reset (forced) r/w mode." << endl; + } else { + kdDebug(GUARD, KAB_KDEBUG_AREA) << + "QConfigDB::save: cannot reset (forced) r/w mode." << endl; + rc=false; + } + } + // ----- + return rc; + // ############################################################################ +} + +bool +QConfigDB::load() +{ + bool GUARD; GUARD=false ; + // ############################################################################ + TQFile file(filename); + // ----- + if(file.open(IO_ReadOnly)) + { + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: file access OK." << endl; + TQTextStream stream(&file); + stream.setEncoding(TQTextStream::Latin1); // no conversion + // ----- + clear(); + bool rc=top.readSection(stream, false); + storeFileAge(); + file.close(); + emit(changed(this)); + kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: done." << endl; + return rc; + } else { + kdDebug() << "QConfigDB::load: error opening file \"" << filename << "\" for reading." << endl; + return false; + } + // ############################################################################ +} -- cgit v1.2.1