TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

addressbook.cc 54KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040
  1. /* -*- C++ -*-
  2. This file implements the basic personal information management class
  3. used in the TDE addressbook.
  4. the TDE addressbook
  5. $ Author: Mirko Boehm $
  6. $ Copyright: (C) 1996-2001, Mirko Boehm $
  7. $ Contact: mirko@kde.org
  8. http://www.kde.org $
  9. $ License: GPL with the following explicit clarification:
  10. This code may be linked against any version of the Qt toolkit
  11. from Troll Tech, Norway. $
  12. $Id$
  13. */
  14. #include "addressbook.h"
  15. #include "qconfigDB.h"
  16. #include <tqfileinfo.h>
  17. #include <tqstringlist.h>
  18. #include <tdeapplication.h>
  19. #include <tdeglobal.h>
  20. #include <kstandarddirs.h>
  21. #include <tdelocale.h>
  22. #include <kdebug.h>
  23. #include <tdemessagebox.h>
  24. extern "C" {
  25. #include <sys/stat.h>
  26. #include <sys/types.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29. }
  30. // ----- some defines:
  31. #ifdef KAB_KDEBUG_AREA
  32. #undef KAB_KDEBUG_AREA
  33. #endif
  34. #define KAB_KDEBUG_AREA 800
  35. #ifdef STD_USERFILENAME
  36. #undef STD_USERFILENAME
  37. #endif
  38. #define STD_USERFILENAME "kab/addressbook.kab"
  39. #ifdef STD_CONFIGFILENAME
  40. #undef STD_CONFIGFILENAME
  41. #endif
  42. #define STD_CONFIGFILENAME "kab/kab.config"
  43. #ifdef ENTRY_SECTION
  44. #undef ENTRY_SECTION
  45. #endif
  46. #define ENTRY_SECTION "entries"
  47. // the name of the file-local configuration section
  48. #ifdef LOCAL_CONFIG_SECTION
  49. #undef LOCAL_CONFIG_SECTION
  50. #endif
  51. #define LOCAL_CONFIG_SECTION "config"
  52. // the name of the subsection for each entry
  53. #ifdef ADDRESS_SUBSECTION
  54. #undef ADDRESS_SUBSECTION
  55. #endif
  56. #define ADDRESS_SUBSECTION "addresses"
  57. #ifdef KAB_TEMPLATEFILE
  58. #undef KAB_TEMPLATEFILE
  59. #endif
  60. #define KAB_TEMPLATEFILE "kab/template.kab"
  61. #ifdef KAB_CONFIGTEMPLATE
  62. #undef KAB_CONFIGTEMPLATE
  63. #endif
  64. #define KAB_CONFIGTEMPLATE "kab/template.config"
  65. #ifdef KAB_CATEGORY_KEY
  66. #undef KAB_CATEGORY_KEY
  67. #endif
  68. #define KAB_CATEGORY_KEY "categories"
  69. const char* AddressBook::Entry::Address::Fields[]= {
  70. "headline", "position",
  71. "org", "orgunit", "orgsubunit",
  72. "deliverylabel", "address", "zip", "town", "country", "state" };
  73. const int AddressBook::Entry::Address::NoOfFields
  74. =sizeof(AddressBook::Entry::Address::Fields)
  75. /sizeof(AddressBook::Entry::Address::Fields[0]);
  76. const char* AddressBook::Entry::Fields[]= {
  77. "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname",
  78. "birthday", "comment", "talk", "emails", "keywords", "telephone",
  79. "urls", "user1", "user2", "user3", "user4", "custom", "categories" };
  80. const int AddressBook::Entry::NoOfFields
  81. =sizeof(AddressBook::Entry::Fields)/sizeof(AddressBook::Entry::Fields[0]);
  82. struct QStringLess
  83. : public binary_function<const TQString&, const TQString&, bool>
  84. {
  85. /** The function operator, inline. */
  86. bool operator()(const TQString& x, const TQString& y) const
  87. {
  88. return x < y; // make one Qt operator fit exactly
  89. }
  90. };
  91. // ----- the derived map class:
  92. class StringKabKeyMap : public map<TQString, KabKey, QStringLess>
  93. { /* Same as map, but a class for compilation reasons. This way we do not need
  94. * to include the QStringLess class into the addressbook header file. */
  95. };
  96. // ----- another derived map class:
  97. class KeyNameMap : public map<const char*, TQString, less<const char*> >
  98. { // same thing
  99. };
  100. KeyNameMap* AddressBook::Entry::fields;
  101. KeyNameMap* AddressBook::Entry::Address::fields;
  102. bool
  103. KabKey::operator == (const KabKey& key) const
  104. {
  105. // ###########################################################################
  106. return key.getKey()==getKey();
  107. // ###########################################################################
  108. }
  109. void
  110. KabKey::setKey(const TQCString& text)
  111. {
  112. // ###########################################################################
  113. key=text;
  114. // ###########################################################################
  115. }
  116. TQCString
  117. KabKey::getKey() const
  118. {
  119. // ###########################################################################
  120. return key;
  121. // ###########################################################################
  122. }
  123. AddressBook::Entry::Address::Address()
  124. {
  125. }
  126. bool AddressBook::Entry::Address::nameOfField(const char* key, TQString& value)
  127. {
  128. KeyNameMap::iterator pos;
  129. // -----
  130. if(fields==0)
  131. { // this is executed exactly one time per application instance,
  132. // as fields is static
  133. int counter=0;
  134. fields=new KeyNameMap;
  135. TQ_CHECK_PTR(fields);
  136. if(!fields->insert
  137. (map<const char*, TQString, less<const char*> >::value_type
  138. (Fields[counter++], i18n("Headline"))).second
  139. ||
  140. !fields->insert
  141. (map<const char*, TQString, less<const char*> >::value_type
  142. (Fields[counter++], i18n("Position"))).second
  143. ||
  144. !fields->insert
  145. (map<const char*, TQString, less<const char*> >::value_type
  146. (Fields[counter++], i18n("Organization"))).second
  147. ||
  148. !fields->insert
  149. (map<const char*, TQString, less<const char*> >::value_type
  150. (Fields[counter++], i18n("Department"))).second
  151. ||
  152. !fields->insert
  153. (map<const char*, TQString, less<const char*> >::value_type
  154. (Fields[counter++], i18n("Sub-Department"))).second
  155. ||
  156. !fields->insert
  157. (map<const char*, TQString, less<const char*> >::value_type
  158. (Fields[counter++], i18n("Delivery Label"))).second
  159. ||
  160. !fields->insert
  161. (map<const char*, TQString, less<const char*> >::value_type
  162. (Fields[counter++], i18n("street/postal","Address"))).second
  163. ||
  164. !fields->insert
  165. (map<const char*, TQString, less<const char*> >::value_type
  166. (Fields[counter++], i18n("Zipcode"))).second
  167. ||
  168. !fields->insert
  169. (map<const char*, TQString, less<const char*> >::value_type
  170. (Fields[counter++], i18n("City"))).second
  171. ||
  172. !fields->insert
  173. (map<const char*, TQString, less<const char*> >::value_type
  174. (Fields[counter++], i18n("Country"))).second
  175. ||
  176. !fields->insert
  177. (map<const char*, TQString, less<const char*> >::value_type
  178. (Fields[counter++], i18n("As in addresses", "State"))).second)
  179. {
  180. kdDebug(KAB_KDEBUG_AREA)
  181. << "AddressBook::Entry::Address::nameOfField (while "
  182. << " creating field-name map): TYPO, correct this."
  183. << endl;
  184. } else {
  185. kdDebug(KAB_KDEBUG_AREA)
  186. << "AddressBook::Entry::Address::nameOfField: "
  187. << "inserted field names." << endl;
  188. }
  189. #if ! defined NDEBUG
  190. TQString name;
  191. kdDebug(KAB_KDEBUG_AREA)
  192. << "AddressBook::Entry::Address::nameOfField:" << endl
  193. << "Created key-fieldname-map. Defined fields are:"
  194. << endl;
  195. for(counter=0; counter<AddressBook::Entry::Address::NoOfFields;
  196. ++counter)
  197. {
  198. pos=fields->find(Fields[counter]);
  199. if(pos==fields->end())
  200. {
  201. kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl;
  202. } else {
  203. kdDebug(KAB_KDEBUG_AREA)
  204. << " " << Fields[counter] << " ("
  205. << (*pos).second.utf8() << ")" << endl;
  206. }
  207. }
  208. #endif
  209. }
  210. // ----- now finally do the lookup:
  211. pos=fields->find(key);
  212. if(pos==fields->end())
  213. {
  214. return false;
  215. } else {
  216. value=(*pos).second;
  217. return true;
  218. }
  219. }
  220. bool AddressBook::Entry::nameOfField(const char* key, TQString& value)
  221. {
  222. KeyNameMap::iterator pos;
  223. // -----
  224. if(fields==0)
  225. { // this is executed exactly one time per application instance,
  226. // as fields is static
  227. int counter=0;
  228. fields=new KeyNameMap;
  229. TQ_CHECK_PTR(fields);
  230. if(!fields->insert
  231. (map<const char*, TQString, less<const char*> >::value_type
  232. (Fields[counter++], i18n("person","Title"))).second
  233. ||
  234. !fields->insert
  235. (map<const char*, TQString, less<const char*> >::value_type
  236. (Fields[counter++], i18n("Rank"))).second
  237. ||
  238. !fields->insert
  239. (map<const char*, TQString, less<const char*> >::value_type
  240. (Fields[counter++], i18n("Formatted Name"))).second
  241. ||
  242. !fields->insert
  243. (map<const char*, TQString, less<const char*> >::value_type
  244. (Fields[counter++], i18n("Name Prefix"))).second
  245. ||
  246. !fields->insert
  247. (map<const char*, TQString, less<const char*> >::value_type
  248. (Fields[counter++], i18n("First Name"))).second
  249. ||
  250. !fields->insert
  251. (map<const char*, TQString, less<const char*> >::value_type
  252. (Fields[counter++], i18n("Middle Name"))).second
  253. ||
  254. !fields->insert
  255. (map<const char*, TQString, less<const char*> >::value_type
  256. (Fields[counter++], i18n("Last Name"))).second
  257. ||
  258. !fields->insert
  259. (map<const char*, TQString, less<const char*> >::value_type
  260. (Fields[counter++], i18n("Birthday"))).second
  261. ||
  262. !fields->insert
  263. (map<const char*, TQString, less<const char*> >::value_type
  264. (Fields[counter++], i18n("Comment"))).second
  265. ||
  266. !fields->insert
  267. (map<const char*, TQString, less<const char*> >::value_type
  268. (Fields[counter++], i18n("Talk Addresses"))).second
  269. ||
  270. !fields->insert
  271. (map<const char*, TQString, less<const char*> >::value_type
  272. (Fields[counter++], i18n("Email Addresses"))).second
  273. ||
  274. !fields->insert
  275. (map<const char*, TQString, less<const char*> >::value_type
  276. (Fields[counter++], i18n("Keywords"))).second
  277. ||
  278. !fields->insert
  279. (map<const char*, TQString, less<const char*> >::value_type
  280. (Fields[counter++], i18n("Telephone Number"))).second
  281. ||
  282. !fields->insert
  283. (map<const char*, TQString, less<const char*> >::value_type
  284. (Fields[counter++], i18n("URLs"))).second
  285. ||
  286. !fields->insert
  287. (map<const char*, TQString, less<const char*> >::value_type
  288. (Fields[counter++], i18n("User Field 1"))).second
  289. ||
  290. !fields->insert
  291. (map<const char*, TQString, less<const char*> >::value_type
  292. (Fields[counter++], i18n("User Field 2"))).second
  293. ||
  294. !fields->insert
  295. (map<const char*, TQString, less<const char*> >::value_type
  296. (Fields[counter++], i18n("User Field 3"))).second
  297. ||
  298. !fields->insert
  299. (map<const char*, TQString, less<const char*> >::value_type
  300. (Fields[counter++], i18n("User Field 4"))).second
  301. ||
  302. !fields->insert
  303. (map<const char*, TQString, less<const char*> >::value_type
  304. (Fields[counter++], i18n("Custom"))).second
  305. ||
  306. !fields->insert
  307. (map<const char*, TQString, less<const char*> >::value_type
  308. (Fields[counter++], i18n("Categories"))).second)
  309. {
  310. kdDebug(KAB_KDEBUG_AREA)
  311. << "AddressBook::Entry::Address::nameOfField (while "
  312. << " creating field-name map): TYPO, correct this." << endl;
  313. } else {
  314. kdDebug(KAB_KDEBUG_AREA)
  315. << "AddressBook::Entry::Address::nameOfField: "
  316. << "inserted field names." << endl;
  317. }
  318. #if ! defined NDEBUG
  319. TQString name;
  320. kdDebug(KAB_KDEBUG_AREA)
  321. << "AddressBook::Entry::nameOfField:" << endl
  322. << "Created key-fieldname-map. Defined fields are:" << endl;
  323. for(counter=0; counter<AddressBook::Entry::Address::NoOfFields;
  324. ++counter)
  325. {
  326. pos=fields->find(Fields[counter]);
  327. if(pos==fields->end())
  328. {
  329. kdDebug(KAB_KDEBUG_AREA) << " UNDEFINED" << endl;
  330. } else {
  331. kdDebug(KAB_KDEBUG_AREA)
  332. << " " << Fields[counter] << " ("
  333. << (*pos).second.utf8() << ")" << endl;
  334. }
  335. }
  336. #endif
  337. }
  338. // ----- now finally do the lookup:
  339. pos=fields->find(key);
  340. if(pos==fields->end())
  341. {
  342. return false;
  343. } else {
  344. value=(*pos).second;
  345. return true;
  346. }
  347. }
  348. AddressBook::ErrorCode
  349. AddressBook::Entry::getAddress(int index, Address& address) const
  350. {
  351. // ###########################################################################
  352. list<Address>::const_iterator pos;
  353. // -----
  354. if(index>=0 && (unsigned)index<addresses.size())
  355. {
  356. pos=addresses.begin();
  357. advance(pos, index);
  358. address=*pos;
  359. return AddressBook::NoError;
  360. } else {
  361. return AddressBook::OutOfRange;
  362. }
  363. // ###########################################################################
  364. }
  365. int AddressBook::Entry::noOfAddresses() const
  366. {
  367. return addresses.size();
  368. }
  369. AddressBook::AddressBook(TQWidget* parent, const char* name, bool loadit)
  370. : TQFrame(parent, name),
  371. config(new QConfigDB(this)),
  372. data(new QConfigDB(this)),
  373. entries(new StringKabKeyMap),
  374. state(NoFile)
  375. {
  376. register bool GUARD; GUARD=true;
  377. // ###########################################################################
  378. TQString dir, filename;
  379. bool createBackup=true;
  380. KeyValueMap *keys;
  381. // ----- do memory checks (do not rely on exception handling):
  382. if(config==0 || data==0 || entries==0)
  383. {
  384. KMessageBox::error(this,
  385. i18n("Cannot initialize local variables."),
  386. i18n("Out of Memory"));
  387. kapp->quit(); // It is critical, but will possibly never happen.
  388. }
  389. connect(data, TQT_SIGNAL(fileChanged()), TQT_SLOT(dataFileChanged()));
  390. connect(data, TQT_SIGNAL(changed(QConfigDB*)),
  391. TQT_SLOT(reloaded(QConfigDB*)));
  392. connect(config, TQT_SIGNAL(fileChanged()), TQT_SLOT(configFileChanged()));
  393. // ----- set style:
  394. filename = locate( "data", STD_CONFIGFILENAME);
  395. if (filename.isEmpty())
  396. {
  397. filename = locateLocal( "data", STD_CONFIGFILENAME );
  398. // config does not exist yet
  399. if(createConfigFile()!=NoError)
  400. {
  401. KMessageBox::sorry(this,
  402. i18n("Your local kab configuration file "
  403. "\"%1\" "
  404. "could not be created. kab will probably not "
  405. "work correctly without it.\n"
  406. "Make sure you have not removed write permission "
  407. "from your local TDE directory (usually ~/.trinity).").arg(filename));
  408. state=PermDenied;
  409. }
  410. }
  411. loadConfigFile();
  412. // ----- now get some configuration settings:
  413. if(config->get("config", keys))
  414. {
  415. keys->get("CreateBackupOnStartup", createBackup);
  416. }
  417. // ----- check and possibly create user standard file:
  418. filename = locate( "data", STD_USERFILENAME );
  419. if(filename.isEmpty()) // if it does not exist
  420. {
  421. filename = locateLocal( "data", STD_USERFILENAME);
  422. if(createNew(filename)!=NoError) // ...and we cannot create it
  423. {
  424. KMessageBox::sorry(this,
  425. i18n("Your standard kab database file "
  426. "\"%1\" "
  427. "could not be created. kab will probably not "
  428. "work correctly without it.\n"
  429. "Make sure you have not removed write permission "
  430. "from your local TDE directory (usually ~/.trinity).").arg(filename));
  431. state=PermDenied;
  432. } else {
  433. KMessageBox::information
  434. (this,
  435. i18n("kab has created your standard addressbook in\n\"%1\"")
  436. .arg(filename));
  437. }
  438. }
  439. // ----- load the user standard file:
  440. if(loadit)
  441. {
  442. if(load(filename)!=NoError)
  443. { // ----- the standard file could not be loaded
  444. state=PermDenied;
  445. } else {
  446. if(createBackup)
  447. {
  448. // ----- create the backup file:
  449. TQString temp=data->fileName();
  450. if(data->setFileName(temp+".backup", false, false))
  451. {
  452. if(!data->save())
  453. {
  454. KMessageBox::information
  455. (this,
  456. i18n("Cannot create backup file (permission denied)."),
  457. i18n("File Error"));
  458. }
  459. } else {
  460. KMessageBox::error
  461. (this,
  462. i18n("Cannot open backup file for "
  463. "writing (permission denied)."),
  464. i18n("File Error"));
  465. }
  466. // ----- reset the filename:
  467. if(!data->setFileName(temp, true, true))
  468. {
  469. KMessageBox::error
  470. (this,
  471. i18n("Critical error:\n"
  472. "Permissions changed in local directory!"),
  473. i18n("File Error"));
  474. closeFile(false);
  475. state=PermDenied;
  476. } else {
  477. state=NoError;
  478. }
  479. }
  480. }
  481. }
  482. // -----
  483. data->watch(true);
  484. // ###########################################################################
  485. }
  486. AddressBook::~AddressBook()
  487. {
  488. // ###########################################################################
  489. delete data;
  490. delete config;
  491. delete entries;
  492. // ###########################################################################
  493. }
  494. QConfigDB* AddressBook::getConfig()
  495. {
  496. // ###########################################################################
  497. return config;
  498. // ###########################################################################
  499. }
  500. AddressBook::ErrorCode AddressBook::getState()
  501. {
  502. // ###########################################################################
  503. return state;
  504. // ###########################################################################
  505. }
  506. AddressBook::ErrorCode AddressBook::load(const TQString& filename)
  507. {
  508. // ----- Remark: Close the file if it could not be loaded!
  509. // ###########################################################################
  510. ErrorCode rc=NoError;
  511. TQFileInfo newfile, oldfile;
  512. // -----
  513. TQString fname = (filename.isEmpty()) ? data->fileName() : filename ;
  514. if(fname.isEmpty()) // there was never a filename set:
  515. {
  516. state=NoFile;
  517. return NoFile;
  518. }
  519. // -----
  520. newfile.setFile(fname);
  521. oldfile.setFile(data->fileName());
  522. if(isSameFile(fname, data->fileName()))
  523. { // ----- possibly deleted file:
  524. if(data->load())
  525. {
  526. emit(setStatus(i18n("File reloaded.")));
  527. state=NoError;
  528. } else {
  529. switch
  530. (KMessageBox::questionYesNo
  531. (this,
  532. i18n("The currently loaded file "
  533. "\"%1\" "
  534. "cannot be reloaded. kab may close or save it.\n"
  535. "Save it if you accidentally deleted your data file.\n"
  536. "Close it if you intended to do so.\n"
  537. "Your file will be closed by default.")
  538. .arg(oldfile.absFilePath()),
  539. i18n("File Error"),
  540. KStdGuiItem::close(), KStdGuiItem::save()))
  541. {
  542. case KMessageBox::No: // save
  543. if(!data->save(i18n("(Safety copy on file error)").ascii(), true))
  544. {
  545. KMessageBox::information(this,
  546. i18n("Cannot save the file; will close it now."),
  547. i18n("File Error"));
  548. closeFile(false);
  549. state=NoFile;
  550. rc=PermDenied;
  551. } else {
  552. state=NoError;
  553. rc=NoError;
  554. }
  555. break; // no error if we could save the file
  556. default: // close
  557. closeFile(false);
  558. state=NoFile;
  559. rc=NoSuchFile;
  560. break;
  561. }
  562. }
  563. } else { // ----- set new filename
  564. if(data->setFileName(fname, true, true))
  565. {
  566. if(data->load())
  567. {
  568. emit(changed());
  569. emit(setStatus(i18n("File opened.")));
  570. state=NoError;
  571. } else {
  572. KMessageBox::information(this,
  573. i18n("Could not load the file."),
  574. i18n("File Error"));
  575. closeFile(false);
  576. emit(setStatus(i18n("No such file.")));
  577. rc=NoSuchFile;
  578. }
  579. } else {
  580. if(KMessageBox::questionYesNo
  581. (this,
  582. i18n("The file \"%1\" cannot be found. "
  583. "Create a new one?").arg(fname),
  584. i18n("No Such File"),
  585. i18n("Create"), KStdGuiItem::cancel())==KMessageBox::Yes)
  586. {
  587. if(createNew(fname)==NoError)
  588. {
  589. emit(setStatus(i18n("New file.")));
  590. } else { // ----- do not close here, stick with the old file:
  591. emit(setStatus(i18n("Canceled.")));
  592. }
  593. }
  594. }
  595. }
  596. // -----
  597. if(rc==NoError)
  598. {
  599. data->watch(true);
  600. updateMirrorMap();
  601. }
  602. // -----
  603. return rc;
  604. // ###########################################################################
  605. }
  606. AddressBook::ErrorCode
  607. AddressBook::getListOfNames(TQStringList* strings, bool reverse, bool initials)
  608. {
  609. register bool GUARD; GUARD=false;
  610. // ###########################################################################
  611. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getListOfNames: called.\n";
  612. StringKabKeyMap::iterator pos;
  613. TQString desc;
  614. ErrorCode rc=NoError;
  615. ErrorCode temp;
  616. // ----- erase the list contents:
  617. strings->clear();
  618. // ----- ...and fill it:
  619. for(pos=entries->begin(); pos!=entries->end(); ++pos)
  620. {
  621. temp=literalName((*pos).second, desc, reverse, initials);
  622. if(temp!=AddressBook::NoError)
  623. {
  624. desc=i18n("(Internal error in kab)");
  625. rc=InternError;
  626. }
  627. if(desc.isEmpty())
  628. {
  629. desc=i18n("(empty entry)");
  630. }
  631. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  632. "AddressBook::getListOfNames: adding " << desc << endl;
  633. strings->append(desc);
  634. }
  635. // ----- any problems?
  636. kdDebug(GUARD, KAB_KDEBUG_AREA)
  637. << "AddressBook::getListOfNames: done, "
  638. << strings->count()
  639. << " entries.\n";
  640. return rc;
  641. // ###########################################################################
  642. }
  643. AddressBook::ErrorCode
  644. AddressBook::literalName(const KabKey& key, TQString& text, bool rev, bool init)
  645. {
  646. // ###########################################################################
  647. Entry entry;
  648. ErrorCode rc;
  649. // ----- get the entry:
  650. rc=getEntry(key, entry);
  651. if(rc!=NoError)
  652. {
  653. return rc;
  654. }
  655. // -----
  656. return literalName(entry, text, rev, init);
  657. // ###########################################################################
  658. }
  659. AddressBook::ErrorCode
  660. AddressBook::literalName(const Entry& entry, TQString& text, bool rev, bool init)
  661. {
  662. register bool GUARD; GUARD=false;
  663. // ###########################################################################
  664. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: called.\n";
  665. TQString firstname, middlename, lastname, nameprefix;
  666. // ----- is the formatted name set?
  667. if(!entry.fn.isEmpty())
  668. {
  669. text=entry.fn;
  670. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  671. "AddressBook::literalName: done (fn).\n";
  672. return NoError;
  673. }
  674. // ----- prepare the strings:
  675. firstname=entry.firstname.simplifyWhiteSpace();
  676. middlename=entry.middlename.simplifyWhiteSpace();
  677. lastname=entry.lastname.simplifyWhiteSpace();
  678. nameprefix=entry.nameprefix.simplifyWhiteSpace();
  679. // ----- create the initials:
  680. if(init)
  681. {
  682. if(!firstname.isEmpty()) firstname=firstname.mid(0, 1)+'.';
  683. if(!middlename.isEmpty()) middlename=middlename.mid(0, 1)+'.';
  684. // if(!lastname.isEmpty()) lastname=lastname.mid(0, 1)+'.';
  685. }
  686. // ----- assemble the string:
  687. text="";
  688. if(rev)
  689. { // name, firstname - add. name - name prefix
  690. if(!lastname.isEmpty())
  691. {
  692. text=lastname;
  693. }
  694. if(!firstname.isEmpty() || !middlename.isEmpty() || !nameprefix.isEmpty())
  695. {
  696. text+=',';
  697. }
  698. if(!firstname.isEmpty())
  699. {
  700. if(!text.isEmpty())
  701. {
  702. text+=' ';
  703. }
  704. text+=firstname;
  705. }
  706. if(!middlename.isEmpty())
  707. {
  708. if(!text.isEmpty())
  709. {
  710. text+=' ';
  711. }
  712. text+=middlename;
  713. }
  714. if(!nameprefix.isEmpty())
  715. {
  716. if(!text.isEmpty())
  717. {
  718. text+=' ';
  719. }
  720. text+=nameprefix;
  721. }
  722. } else {
  723. // firstname - add. name - name prefix - name
  724. text=firstname;
  725. if(!middlename.isEmpty())
  726. {
  727. if(!text.isEmpty())
  728. {
  729. text+=' ';
  730. }
  731. text+=middlename;
  732. }
  733. if(!nameprefix.isEmpty())
  734. {
  735. if(!text.isEmpty())
  736. {
  737. text+=' ';
  738. }
  739. text+=nameprefix;
  740. }
  741. if(!lastname.isEmpty())
  742. {
  743. if(!text.isEmpty())
  744. {
  745. text+=' ';
  746. }
  747. text+=lastname;
  748. }
  749. }
  750. // -----
  751. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::literalName: done: "
  752. << text << ".\n";
  753. return NoError;
  754. // ###########################################################################
  755. }
  756. unsigned int
  757. AddressBook::noOfEntries()
  758. {
  759. // ###########################################################################
  760. return entries->size();
  761. // ###########################################################################
  762. }
  763. void
  764. AddressBook::dataFileChanged()
  765. {
  766. // ###########################################################################
  767. data->watch(false); // will be restarted after successful load
  768. load();
  769. // ###########################################################################
  770. }
  771. void
  772. AddressBook::configFileChanged()
  773. {
  774. register bool GUARD; GUARD=true;
  775. // ###########################################################################
  776. if(!config->load())
  777. {
  778. KMessageBox::error(this,
  779. i18n("Cannot reload configuration file!"),
  780. i18n("File Error"));
  781. } else {
  782. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::configFileChanged: "
  783. "config file reloaded.\n";
  784. emit(setStatus(i18n("Configuration file reloaded.")));
  785. }
  786. // ###########################################################################
  787. }
  788. void
  789. AddressBook::reloaded(QConfigDB* db)
  790. {
  791. register bool GUARD; GUARD=false;
  792. // ###########################################################################
  793. if(db==data)
  794. {
  795. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::reloaded: file has been "
  796. "reloaded.\n";
  797. updateMirrorMap(); // WORK_TO_DO: what's up with the return value?
  798. changed();
  799. }
  800. // ###########################################################################
  801. }
  802. AddressBook::ErrorCode
  803. AddressBook::save(const TQString& filename, bool force)
  804. {
  805. // ###########################################################################
  806. if(filename.isEmpty())
  807. {
  808. if(data->save(0, force))
  809. {
  810. emit(setStatus(i18n("File saved.")));
  811. return NoError;
  812. } else {
  813. return PermDenied;
  814. }
  815. } else {
  816. if(data->setFileName(filename, false, false))
  817. {
  818. if(data->save(0, true))
  819. {
  820. emit(newFile(filename));
  821. return NoError;
  822. } else {
  823. return PermDenied;
  824. }
  825. } else {
  826. return PermDenied;
  827. }
  828. }
  829. // ###########################################################################
  830. }
  831. bool
  832. AddressBook::isSameFile(const TQString& a, const TQString& b)
  833. {
  834. // ###########################################################################
  835. TQFileInfo filea(a), fileb(b);
  836. // -----
  837. return filea.absFilePath()==fileb.absFilePath();
  838. // ###########################################################################
  839. }
  840. AddressBook::ErrorCode
  841. AddressBook::closeFile(bool saveit)
  842. {
  843. // ###########################################################################
  844. if(saveit)
  845. {
  846. if(save()!=NoError)
  847. {
  848. emit(setStatus(i18n("Permission denied.")));
  849. return PermDenied;
  850. }
  851. }
  852. data->clear();
  853. // data->reset(); WORK_TO_DO: File name is not reset by now.
  854. emit(setStatus(i18n("File closed.")));
  855. return NoError;
  856. // ###########################################################################
  857. }
  858. AddressBook::ErrorCode
  859. AddressBook::getEntry(const KabKey& key, Entry& entry)
  860. {
  861. // ###########################################################################
  862. Section *section;
  863. // -----
  864. if(getEntry(key, section)==NoError)
  865. {
  866. return makeEntryFromSection(section, entry);
  867. } else {
  868. return NoSuchEntry;
  869. }
  870. // ###########################################################################
  871. }
  872. AddressBook::ErrorCode
  873. AddressBook::getEntry(const KabKey& key, Section*& section)
  874. {
  875. register bool GUARD; GUARD=false;
  876. // ###########################################################################
  877. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::getEntry: searching entry "
  878. "with key " << key.getKey().data() << endl;
  879. StringKabKeyMap::iterator pos;
  880. // -----
  881. for(pos=entries->begin(); pos!=entries->end(); ++pos)
  882. {
  883. if((*pos).second==key)
  884. {
  885. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  886. "AddressBook::getEntry: key exists." << endl;
  887. break;
  888. }
  889. }
  890. if(pos==entries->end())
  891. {
  892. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  893. "AddressBook::getEntry: no such entry.\n";
  894. return NoSuchEntry;
  895. } else {
  896. if(data->get((TQCString)ENTRY_SECTION+'/'+key.getKey(), section))
  897. {
  898. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  899. "AddressBook::getEntry: done." << endl;
  900. return NoError;
  901. } else {
  902. return InternError;
  903. }
  904. }
  905. // ###########################################################################
  906. }
  907. AddressBook::ErrorCode
  908. AddressBook::getEntries(list<Entry>& thelist)
  909. {
  910. // ###########################################################################
  911. StringKabKeyMap::iterator pos;
  912. Entry entry;
  913. ErrorCode rc;
  914. // -----
  915. kdDebug(!thelist.empty(), KAB_KDEBUG_AREA)
  916. << "AddressBook::getEntries: warning - non-empty value list!" << endl;
  917. thelist.erase(thelist.begin(), thelist.end());
  918. for(pos=entries->begin(); pos!=entries->end(); ++pos)
  919. {
  920. rc=getEntry((*pos).second, entry);
  921. if(rc==NoError)
  922. {
  923. thelist.push_back(entry);
  924. } else {
  925. return InternError;
  926. }
  927. }
  928. // -----
  929. return NoError;
  930. // ###########################################################################
  931. }
  932. AddressBook::ErrorCode
  933. AddressBook::getKey(int index, KabKey& key)
  934. {
  935. // ###########################################################################
  936. StringKabKeyMap::iterator pos;
  937. // -----
  938. if((unsigned)index<entries->size())
  939. {
  940. pos=entries->begin();
  941. advance(pos, index);
  942. key=(*pos).second;
  943. return NoError;
  944. } else {
  945. return NoSuchEntry;
  946. }
  947. // ###########################################################################
  948. }
  949. AddressBook::ErrorCode
  950. AddressBook::getIndex(const KabKey& key, int& index)
  951. {
  952. register bool GUARD; GUARD=true;
  953. // ###########################################################################
  954. StringKabKeyMap::iterator pos;
  955. // -----
  956. index=0;
  957. for(pos=entries->begin(); pos!=entries->end(); ++pos)
  958. {
  959. // kdDebug(KAB_KDEBUG_AREA) << (*pos).second.getKey().data() << " <--> " <<
  960. // key.getKey().data() << endl;
  961. if((*pos).second==key) break;
  962. ++index;
  963. }
  964. kdDebug(pos==entries->end(), KAB_KDEBUG_AREA) <<
  965. "AddressBook::getIndex: no such key." << endl;
  966. if(pos==entries->end())
  967. {
  968. return NoSuchEntry;
  969. } else {
  970. return NoError;
  971. }
  972. // ###########################################################################
  973. }
  974. Section*
  975. AddressBook::entrySection()
  976. {
  977. // ###########################################################################
  978. Section* section;
  979. // -----
  980. if(!data->get(ENTRY_SECTION, section))
  981. {
  982. return 0;
  983. } else {
  984. return section;
  985. }
  986. // ###########################################################################
  987. }
  988. AddressBook::ErrorCode
  989. AddressBook::add(const Entry& entry, KabKey& key, bool update)
  990. {
  991. bool GUARD; GUARD=true;
  992. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: called." << endl;
  993. // ###########################################################################
  994. Section* theEntries=entrySection();
  995. Section* newEntry;
  996. KabKey nextKey;
  997. ErrorCode locked;
  998. ErrorCode rc;
  999. // -----
  1000. if(theEntries==0)
  1001. {
  1002. kdDebug(KAB_KDEBUG_AREA) << "AddressBook::add: no entries section."
  1003. << endl;
  1004. return NoFile;
  1005. }
  1006. newEntry=new Section;
  1007. if(newEntry==0)
  1008. {
  1009. KMessageBox::error(this,
  1010. i18n("Cannot initialize local variables."),
  1011. i18n("Out of Memory"));
  1012. kapp->quit(); // It is critical, but will possibly never happen.
  1013. return InternError; // shut the compiler up...
  1014. }
  1015. // ----- lock the file:
  1016. locked=lock();
  1017. switch(locked)
  1018. {
  1019. case PermDenied:
  1020. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1021. << "AddressBook::add: permission denied." << endl;
  1022. return PermDenied; // cannot get r/w mode
  1023. case Locked:
  1024. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1025. << "AddressBook::add: db is already in r/w mode." << endl;
  1026. break;
  1027. case NoError:
  1028. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1029. << "AddressBook::add: got writing permissions." << endl;
  1030. break;
  1031. default:
  1032. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1033. << "AddressBook::add: unknown response, exiting." << endl;
  1034. return InternError;
  1035. }
  1036. // -----
  1037. if(makeSectionFromEntry(entry, *newEntry)==NoError)
  1038. {
  1039. nextKey=nextAvailEntryKey();
  1040. if(!theEntries->add(nextKey.getKey(), newEntry))
  1041. {
  1042. kdDebug(KAB_KDEBUG_AREA)
  1043. << "AddressBook::add: Cannot insert section.\n";
  1044. rc=InternError;
  1045. } else {
  1046. key=nextKey;
  1047. emit(changed());
  1048. rc=NoError;
  1049. }
  1050. if(update) updateMirrorMap();
  1051. } else {
  1052. rc=InternError;
  1053. }
  1054. if(locked!=Locked)
  1055. { // ----- unlock the file here:
  1056. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1057. << "AddressBook::add: dropped writing permissions." << endl;
  1058. locked=unlock();
  1059. }
  1060. // -----
  1061. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::add: done." << endl;
  1062. if(locked!=NoError)
  1063. {
  1064. return locked;
  1065. }
  1066. if(rc!=NoError)
  1067. {
  1068. return rc;
  1069. }
  1070. return NoError;
  1071. // ###########################################################################
  1072. }
  1073. AddressBook::ErrorCode
  1074. AddressBook::change(const KabKey& key, const Entry& entry)
  1075. {
  1076. // ###########################################################################
  1077. Section* theEntries=entrySection();
  1078. Section* oldEntry;
  1079. ErrorCode locked;
  1080. ErrorCode rc;
  1081. // -----
  1082. if(theEntries==0)
  1083. {
  1084. return NoFile;
  1085. }
  1086. // ----- lock the file:
  1087. locked=lock();
  1088. if(locked==PermDenied)
  1089. {
  1090. return PermDenied; // cannot get r/w mode
  1091. }
  1092. // -----
  1093. if(!theEntries->find(key.getKey(), oldEntry))
  1094. {
  1095. rc=NoSuchEntry;
  1096. } else {
  1097. oldEntry->clear();
  1098. rc=makeSectionFromEntry(entry, *oldEntry);
  1099. emit(changed());
  1100. }
  1101. // -----
  1102. if(locked!=PermDenied)
  1103. { // ----- unlock the file here:
  1104. locked=unlock();
  1105. }
  1106. if(locked==NoError)
  1107. {
  1108. return rc;
  1109. } else {
  1110. return locked;
  1111. }
  1112. // ###########################################################################
  1113. }
  1114. AddressBook::ErrorCode
  1115. AddressBook::remove(const KabKey& key)
  1116. {
  1117. // ###########################################################################
  1118. Section *theEntries=entrySection();
  1119. ErrorCode locked;
  1120. ErrorCode rc;
  1121. // -----
  1122. if(theEntries==0)
  1123. {
  1124. return NoFile;
  1125. }
  1126. // ----- lock the file:
  1127. locked=lock();
  1128. if(locked==PermDenied)
  1129. {
  1130. return PermDenied; // cannot get r/w mode
  1131. }
  1132. // -----
  1133. if(theEntries->remove(key.getKey()))
  1134. {
  1135. rc=NoError;
  1136. emit(changed());
  1137. } else {
  1138. rc=NoSuchEntry;
  1139. }
  1140. // -----
  1141. if(locked!=PermDenied)
  1142. { // ----- unlock the file here:
  1143. locked=unlock();
  1144. }
  1145. if(locked==NoError)
  1146. {
  1147. return rc;
  1148. } else {
  1149. return locked;
  1150. }
  1151. // ###########################################################################
  1152. }
  1153. AddressBook::ErrorCode
  1154. AddressBook::lock()
  1155. {
  1156. // ###########################################################################
  1157. if(!data->isRO()) return Locked;
  1158. if(data->setFileName(data->fileName(), false, false))
  1159. {
  1160. return NoError;
  1161. } else {
  1162. KMessageBox::information(this,
  1163. i18n("The file you wanted to change could not be locked.\n"
  1164. "It is probably in use by another application or read-only."),
  1165. i18n("File Error"));
  1166. return PermDenied;
  1167. }
  1168. // ###########################################################################
  1169. }
  1170. AddressBook::ErrorCode
  1171. AddressBook::unlock()
  1172. {
  1173. // ###########################################################################
  1174. if(data->isRO()) return PermDenied;
  1175. if(data->setFileName(data->fileName(), true, true))
  1176. {
  1177. return NoError;
  1178. } else {
  1179. return InternError;
  1180. }
  1181. // ###########################################################################
  1182. }
  1183. KabKey
  1184. AddressBook::nextAvailEntryKey()
  1185. {
  1186. // ###########################################################################
  1187. int max=0;
  1188. int temp;
  1189. Section::StringSectionMap::iterator pos;
  1190. Section *section=entrySection();
  1191. KabKey key;
  1192. TQCString dummy;
  1193. bool good=true;
  1194. // -----
  1195. if(section!=0)
  1196. {
  1197. for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos)
  1198. {
  1199. temp=0;
  1200. temp=(*pos).first.toInt(&good);
  1201. if(!good)
  1202. {
  1203. kdDebug(KAB_KDEBUG_AREA)
  1204. << "AddressBook::nextAvailEntryKey: non-integer entry "
  1205. << endl;
  1206. }
  1207. if(temp>max)
  1208. {
  1209. max=temp;
  1210. }
  1211. }
  1212. }
  1213. // -----
  1214. dummy.setNum(++max);
  1215. key.setKey(dummy);
  1216. // CHECK(key.getKey().toInt(&good)==max);
  1217. return key;
  1218. // ###########################################################################
  1219. }
  1220. AddressBook::ErrorCode
  1221. AddressBook::updateMirrorMap()
  1222. {
  1223. register bool GUARD; GUARD=false;
  1224. // ###########################################################################
  1225. kdDebug(GUARD, KAB_KDEBUG_AREA)
  1226. << "AddressBook::updateMirrorMap: updating mirror map.\n";
  1227. TQString key;
  1228. Entry entry;
  1229. ErrorCode ec;
  1230. KabKey kk;
  1231. Section *section=entrySection();
  1232. Section::StringSectionMap::iterator pos;
  1233. // -----
  1234. entries->erase(entries->begin(), entries->end());
  1235. if(section==0)
  1236. {
  1237. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done, "
  1238. "no file loaded." << endl;
  1239. return NoError;
  1240. }
  1241. for(pos=section->sectionsBegin(); pos!=section->sectionsEnd(); ++pos)
  1242. {
  1243. if(makeEntryFromSection((*pos).second, entry)!=NoError)
  1244. {
  1245. // return InternError; // it is saver to continue without a key
  1246. }
  1247. key="";
  1248. ec=literalName(entry, key, true, false);
  1249. if(key.isEmpty() || ec!=NoError)
  1250. {
  1251. key=i18n("(empty entry)");
  1252. }
  1253. key+=(*pos).first; // append the section name to make the key unique
  1254. kk.setKey((*pos).first);
  1255. entries->insert(StringKabKeyMap::value_type(key, kk));
  1256. }
  1257. // -----
  1258. kdDebug(GUARD, KAB_KDEBUG_AREA) << "AddressBook::updateMirrorMap: done."
  1259. << endl;
  1260. return NoError;
  1261. // ###########################################################################
  1262. }
  1263. AddressBook::ErrorCode
  1264. AddressBook::makeEntryFromSection(Section* section, Entry& entry)
  1265. {
  1266. // ###########################################################################
  1267. Section *addresses;
  1268. Section *addressSection;
  1269. Section::StringSectionMap::iterator pos;
  1270. KeyValueMap *keys;
  1271. Entry temp;
  1272. Entry::Address address;
  1273. Entry::Address addressDummy;
  1274. int count;
  1275. // ----- create the aggregats:
  1276. const TQCString StringKeys[]= {
  1277. "title",
  1278. "rank",
  1279. "fn",
  1280. "nameprefix",
  1281. "firstname",
  1282. "middlename",
  1283. "lastname",
  1284. "comment",
  1285. "user1",
  1286. "user2",
  1287. "user3",
  1288. "user4"
  1289. };
  1290. TQString* StringValues[]= {
  1291. &temp.title,
  1292. &temp.rank,
  1293. &temp.fn,
  1294. &temp.nameprefix,
  1295. &temp.firstname,
  1296. &temp.middlename,
  1297. &temp.lastname,
  1298. &temp.comment,
  1299. &temp.user1,
  1300. &temp.user2,
  1301. &temp.user3,
  1302. &temp.user4
  1303. };
  1304. const int StringKeySize=sizeof(StringKeys)/sizeof(StringKeys[0]);
  1305. const TQCString StringListKeys[]= {
  1306. "talk",
  1307. "emails",
  1308. "keywords",
  1309. "telephone",
  1310. "URLs",
  1311. "custom",
  1312. "categories"
  1313. };
  1314. TQStringList* StringListValues[]= {
  1315. &temp.talk,
  1316. &temp.emails,
  1317. &temp.keywords,
  1318. &temp.telephone,
  1319. &temp.URLs,
  1320. &temp.custom,
  1321. &temp.categories
  1322. };
  1323. const int StringListKeySize=sizeof(StringListKeys)/sizeof(StringListKeys[0]);
  1324. // ----- first parse "addresses" subsection:
  1325. if(!section->find(ADDRESS_SUBSECTION, addresses))
  1326. {
  1327. return InternError; // no subsection called "addresses"
  1328. }
  1329. for(pos=addresses->sectionsBegin(); pos!=addresses->sectionsEnd(); ++pos)
  1330. {
  1331. if(!addresses->find((*pos).first, addressSection))
  1332. {
  1333. return InternError; // no section we have an iterator for?
  1334. }
  1335. keys=addressSection->getKeys();
  1336. address=addressDummy; // clean it up
  1337. if(makeAddressFromMap(keys, address)==AddressBook::NoError)
  1338. {
  1339. // ----- add the address to the list of addresses:
  1340. temp.addresses.push_back(address);
  1341. } else {
  1342. kdDebug(KAB_KDEBUG_AREA)
  1343. << "AddressBook::makeEntryFromSection: cannot find all fields "
  1344. << "in an address subsection." << endl;
  1345. }
  1346. }
  1347. // ----- now parse all other fields directly:
  1348. keys=section->getKeys();
  1349. for(count=0; count<StringKeySize; ++count)
  1350. {
  1351. if(!keys->get(StringKeys[count], *StringValues[count]))
  1352. {
  1353. /* Spits out lots of warnings:
  1354. kdDebug(KAB_KDEBUG_AREA)
  1355. << "AddressBook::makeEntryFromSection: error: could not get "
  1356. << "value for key " << (const char*)StringKeys[count]
  1357. << "." << endl;
  1358. */
  1359. }
  1360. }
  1361. for(count=0; count<StringListKeySize; ++count)
  1362. {
  1363. if(!keys->get(StringListKeys[count], *StringListValues[count]))
  1364. {
  1365. /* Spits out lots of warnings:
  1366. kdDebug(KAB_KDEBUG_AREA)
  1367. << "AddressBook::makeEntryFromSection: error: could not get "
  1368. << "value for key " << (const char*)StringListKeys[count]
  1369. << "." << endl;
  1370. */
  1371. }
  1372. }
  1373. // ----- finally get the birthday:
  1374. keys->get("birthday", temp.birthday); // this may return false (no date)
  1375. // -----
  1376. entry=temp;
  1377. return NoError;
  1378. // ###########################################################################
  1379. }
  1380. AddressBook::ErrorCode
  1381. AddressBook::makeAddressFromMap(KeyValueMap* keys, Entry::Address& address)
  1382. {
  1383. // ###########################################################################
  1384. const TQCString Keys[]= {
  1385. "headline",
  1386. "position",
  1387. "org",
  1388. "orgunit",
  1389. "orgsubunit",
  1390. // "role",
  1391. "deliverylabel",
  1392. "address",
  1393. "zip",
  1394. "town",
  1395. "country",
  1396. "state"
  1397. };
  1398. TQString* strings[]= {
  1399. &address.headline,
  1400. &address.position,
  1401. &address.org,
  1402. &address.orgUnit,
  1403. &address.orgSubUnit,
  1404. // &address.role,
  1405. &address.deliveryLabel,
  1406. &address.address,
  1407. &address.zip,
  1408. &address.town,
  1409. &address.country,
  1410. &address.state
  1411. };
  1412. const int Size=sizeof(Keys)/sizeof(Keys[0]);
  1413. int count;
  1414. // -----
  1415. for(count=0; count<Size; ++count)
  1416. {
  1417. keys->get(Keys[count], *strings[count]);
  1418. }
  1419. return NoError;
  1420. // ###########################################################################
  1421. }
  1422. AddressBook::ErrorCode
  1423. AddressBook::makeSectionFromEntry(const Entry& entry, Section& section)
  1424. {
  1425. // ###########################################################################
  1426. list<Entry::Address>::const_iterator addPos;
  1427. Section *addresses=0;
  1428. Section *address=0;
  1429. TQCString key; // used for creating address subsection keys
  1430. int count=0; // counts the addresses
  1431. KeyValueMap *keys;
  1432. // ----- prepare the section object:
  1433. section.clear();
  1434. // ----- first create "addresses" subsection:
  1435. if(!section.add(ADDRESS_SUBSECTION))
  1436. {
  1437. kdDebug(KAB_KDEBUG_AREA)
  1438. << "AddressBook::makeSectionFromEntry: cannot create " << "subsection."
  1439. << " " << endl;
  1440. return InternError;
  1441. }
  1442. if(!section.find(ADDRESS_SUBSECTION, addresses))
  1443. {
  1444. kdDebug(KAB_KDEBUG_AREA)
  1445. << "AddressBook::makeSectionFromEntry: cannot get new section." << endl;
  1446. return InternError;
  1447. }
  1448. // ----- now insert addresses:
  1449. for(addPos=entry.addresses.begin(); addPos!=entry.addresses.end(); ++addPos)
  1450. {
  1451. ++count;
  1452. key.setNum(count);
  1453. if(!addresses->add(key))
  1454. {
  1455. kdDebug(KAB_KDEBUG_AREA)
  1456. << "AddressBook::makeSectionFromEntry: cannot create address " << endl;
  1457. return InternError;
  1458. }
  1459. if(!addresses->find(key, address))
  1460. {
  1461. kdDebug(KAB_KDEBUG_AREA)
  1462. << "AddressBook::makeSectionFromEntry: cannot get new " << endl;
  1463. return InternError;
  1464. }
  1465. keys=address->getKeys();
  1466. // ----- now insert keys into address:
  1467. if(!keys->insert("headline", (*addPos).headline) ||
  1468. !keys->insert("position", (*addPos).position) ||
  1469. !keys->insert("org", (*addPos).org) ||
  1470. !keys->insert("orgunit", (*addPos).orgUnit) ||
  1471. !keys->insert("orgsubunit", (*addPos).orgSubUnit) ||
  1472. // !keys->insert("role", (*addPos).role) ||
  1473. !keys->insert("deliverylabel", (*addPos).deliveryLabel) ||
  1474. !keys->insert("address", (*addPos).address) ||
  1475. !keys->insert("zip", (*addPos).zip) ||
  1476. !keys->insert("town", (*addPos).town) ||
  1477. !keys->insert("country", (*addPos).country) ||
  1478. !keys->insert("state", (*addPos).state))
  1479. {
  1480. kdDebug(KAB_KDEBUG_AREA)
  1481. << "AddressBook::makeSectionFromEntry: cannot completely "
  1482. << "insert this address." << endl;
  1483. return InternError;
  1484. }
  1485. }
  1486. // ----- now add the other fields:
  1487. keys=section.getKeys();
  1488. if(!keys->insert("title", entry.title) ||
  1489. !keys->insert("rank", entry.rank) ||
  1490. !keys->insert("fn", entry.fn) ||
  1491. !keys->insert("nameprefix", entry.nameprefix) ||
  1492. !keys->insert("firstname", entry.firstname) ||
  1493. !keys->insert("middlename", entry.middlename) ||
  1494. !keys->insert("lastname", entry.lastname) ||
  1495. !keys->insert("birthday", entry.birthday) ||
  1496. !keys->insert("comment", entry.comment) ||
  1497. !keys->insert("talk", entry.talk) ||
  1498. !keys->insert("emails", entry.emails) ||
  1499. !keys->insert("keywords", entry.keywords) ||
  1500. !keys->insert("telephone", entry.telephone) ||
  1501. !keys->insert("URLs", entry.URLs) ||
  1502. !keys->insert("user1", entry.user1) ||
  1503. !keys->insert("user2", entry.user2) ||
  1504. !keys->insert("user3", entry.user3) ||
  1505. !keys->insert("user4", entry.user4) ||
  1506. !keys->insert("custom", entry.custom) ||
  1507. !keys->insert("categories", entry.categories))
  1508. {
  1509. kdDebug(KAB_KDEBUG_AREA)
  1510. << "AddressBook::makeEntryFromSection: cannot insert "
  1511. << "all fields of the entry." << endl;
  1512. return InternError;
  1513. }
  1514. // -----
  1515. return NoError;
  1516. // ###########################################################################
  1517. }
  1518. AddressBook::ErrorCode
  1519. AddressBook::createNew(const TQString& filename)
  1520. {
  1521. // ###########################################################################
  1522. const TQString KabTemplateFile=locate("data", "kab/template.kab");
  1523. kdDebug(KAB_KDEBUG_AREA)
  1524. << "AddressBook::createNew: template file is \""
  1525. << (const char*)KabTemplateFile.utf8() << "\"." << endl;
  1526. QConfigDB db;
  1527. // -----
  1528. if(KabTemplateFile.isEmpty()
  1529. || !db.setFileName(KabTemplateFile, true, true))
  1530. {
  1531. KMessageBox::error(this,
  1532. i18n("Cannot find kab's template file.\n"
  1533. "You cannot create new files."),
  1534. i18n("File Error"));
  1535. return InternError;
  1536. }
  1537. if(!db.load())
  1538. {
  1539. KMessageBox::error(this,
  1540. i18n("Cannot read kab's template file.\n"
  1541. "You cannot create new files."),
  1542. i18n("Format Error"));
  1543. return InternError;
  1544. }
  1545. if(!db.setFileName(filename, false, false))
  1546. {
  1547. KMessageBox::error(this,
  1548. i18n("Cannot create the file\n\"")
  1549. +filename+"\"\n"+
  1550. i18n("Could not create the new file."),
  1551. i18n("File Error"));
  1552. return PermDenied;
  1553. }
  1554. if(!db.save())
  1555. {
  1556. KMessageBox::error(this,
  1557. i18n("Cannot save the file\n\"")
  1558. +filename+"\"\n"+
  1559. i18n("Could not create the new file."),
  1560. i18n("File Error"));
  1561. return InternError;
  1562. }
  1563. // -----
  1564. return NoError;
  1565. // ###########################################################################
  1566. }
  1567. AddressBook::ErrorCode
  1568. AddressBook::createConfigFile()
  1569. {
  1570. // ###########################################################################
  1571. const TQString ConfigTemplateFile=locate("data", "kab/template.config");
  1572. kdDebug(KAB_KDEBUG_AREA)
  1573. << "AddressBook::createConfigFile: config template file is \""
  1574. << (const char*)ConfigTemplateFile.utf8() << "\"." << endl;
  1575. const TQString filename= locateLocal( "data", STD_CONFIGFILENAME);
  1576. QConfigDB db;
  1577. // -----
  1578. if(ConfigTemplateFile.isEmpty()
  1579. || !db.setFileName(ConfigTemplateFile, true, true))
  1580. {
  1581. KMessageBox::error(this,
  1582. i18n("Cannot find kab's configuration template file.\n"
  1583. "kab cannot be configured."),
  1584. i18n("File Error"));
  1585. return InternError;
  1586. }
  1587. if(!db.load())
  1588. {
  1589. KMessageBox::error(this,
  1590. i18n("Cannot read kab's configuration template file.\n"
  1591. "kab cannot be configured."),
  1592. i18n("File Error"));
  1593. return InternError;
  1594. }
  1595. if(!db.setFileName(filename, false, false))
  1596. {
  1597. KMessageBox::error(this,
  1598. i18n("Cannot create the file\n\"")
  1599. +filename+"\"\n"+
  1600. i18n("Could not create the new configuration file."),
  1601. i18n("File Error"));
  1602. return PermDenied;
  1603. }
  1604. if(!db.save())
  1605. {
  1606. KMessageBox::error(this,
  1607. i18n("Cannot save the file\n\"")
  1608. +filename+"\"\n"+
  1609. i18n("Could not create the new configuration file."),
  1610. i18n("File Error"));
  1611. return InternError;
  1612. }
  1613. // -----
  1614. return NoError;
  1615. // ###########################################################################
  1616. }
  1617. AddressBook::ErrorCode
  1618. AddressBook::loadConfigFile()
  1619. {
  1620. // ###########################################################################
  1621. TQString file = locateLocal( "data", STD_CONFIGFILENAME);
  1622. if(config->setFileName(file, true, true))
  1623. {
  1624. if(config->load())
  1625. {
  1626. return NoError;
  1627. } else {
  1628. KMessageBox::information(this,
  1629. i18n("Cannot load kab's local configuration file.\n"
  1630. "There may be a formatting error.\n"
  1631. "kab cannot be configured."),
  1632. i18n("File Error"));
  1633. return InternError;
  1634. }
  1635. } else {
  1636. KMessageBox::information(this,
  1637. i18n("Cannot find kab's local configuration file.\n"
  1638. "kab cannot be configured."),
  1639. i18n("File Error"));
  1640. return NoSuchFile;
  1641. }
  1642. // ###########################################################################
  1643. }
  1644. AddressBook::ErrorCode
  1645. AddressBook::makeVCardFromEntry(const Entry&, const TQString&)
  1646. {
  1647. // ###########################################################################
  1648. return NotImplemented;
  1649. // ###########################################################################
  1650. }
  1651. AddressBook::ErrorCode
  1652. AddressBook::makeEntryFromVCard(const TQString&, Entry&)
  1653. {
  1654. // ###########################################################################
  1655. return NotImplemented;
  1656. // ###########################################################################
  1657. }
  1658. TQString
  1659. AddressBook::getStandardFileName()
  1660. {
  1661. // ###########################################################################
  1662. return locateLocal( "data", STD_USERFILENAME);
  1663. // ###########################################################################
  1664. }
  1665. TQString AddressBook::phoneType(AddressBook::Telephone phone)
  1666. {
  1667. switch(phone)
  1668. {
  1669. case Fixed: return i18n("fixed"); break;
  1670. case Mobile: return i18n("mobile"); break;
  1671. case Fax: return i18n("fax"); break;
  1672. case Modem: return i18n("modem"); break;
  1673. default: return i18n("general");
  1674. }
  1675. }
  1676. void AddressBook::externalChange()
  1677. {
  1678. updateMirrorMap();
  1679. }
  1680. Section* AddressBook::configurationSection()
  1681. {
  1682. Section *section;
  1683. if(data!=0)
  1684. {
  1685. if(data->get(LOCAL_CONFIG_SECTION, section))
  1686. {
  1687. return section;
  1688. } else {
  1689. return 0;
  1690. }
  1691. } else {
  1692. return 0;
  1693. }
  1694. }
  1695. AddressBook::ErrorCode AddressBook::Entry::get(const char* fieldname, TQVariant& field)
  1696. {
  1697. // "title", "rank", "fn", "nameprefix", "firstname", "middlename", "lastname",
  1698. // "birthday", "comment", "talk", "emails", "keywords", "telephone",
  1699. // "urls", "user1", "user2", "user3", "user4", "custom"
  1700. int dummy=0;
  1701. // -----
  1702. if(fieldname==Fields[dummy++])
  1703. { // the title
  1704. field=title;
  1705. return NoError;
  1706. }
  1707. if(fieldname==Fields[dummy++])
  1708. { // the rank
  1709. field=rank;
  1710. return NoError;
  1711. }
  1712. if(fieldname==Fields[dummy++])
  1713. { // the formatted name
  1714. field=fn;
  1715. return NoError;
  1716. }
  1717. if(fieldname==Fields[dummy++])
  1718. { // the nameprefix
  1719. field=nameprefix;
  1720. return NoError;
  1721. }
  1722. if(fieldname==Fields[dummy++])
  1723. { // the firstname
  1724. field=firstname;
  1725. return NoError;
  1726. }
  1727. if(fieldname==Fields[dummy++])
  1728. { // the middle name
  1729. field=middlename;
  1730. return NoError;
  1731. }
  1732. if(fieldname==Fields[dummy++])
  1733. { // the last name
  1734. field=lastname;
  1735. return NoError;
  1736. }
  1737. if(fieldname==Fields[dummy++])
  1738. { // the birthday
  1739. field=TQString(birthday.toString());
  1740. return NoError;
  1741. }
  1742. if(fieldname==Fields[dummy++])
  1743. { // the comment
  1744. field=comment;
  1745. return NoError;
  1746. }
  1747. if(fieldname==Fields[dummy++])
  1748. { // the talk addresses
  1749. field=talk;
  1750. return NoError;
  1751. }
  1752. if(fieldname==Fields[dummy++])
  1753. { // the email addresses
  1754. field=emails;
  1755. return NoError;
  1756. }
  1757. if(fieldname==Fields[dummy++])
  1758. { // the keywords
  1759. field=keywords;
  1760. return NoError;
  1761. }
  1762. if(fieldname==Fields[dummy++])
  1763. { // the telephones
  1764. field=telephone;
  1765. return NoError;
  1766. }
  1767. if(fieldname==Fields[dummy++])
  1768. { // the urls
  1769. field=URLs;
  1770. return NoError;
  1771. }
  1772. if(fieldname==Fields[dummy++])
  1773. { // the user field 1
  1774. field=user1;
  1775. return NoError;
  1776. }
  1777. if(fieldname==Fields[dummy++])
  1778. { // the user field 2
  1779. field=user2;
  1780. return NoError;
  1781. }
  1782. if(fieldname==Fields[dummy++])
  1783. { // the user field 3
  1784. field=user3;
  1785. return NoError;
  1786. }
  1787. if(fieldname==Fields[dummy++])
  1788. { // the user field 4
  1789. field=user4;
  1790. return NoError;
  1791. }
  1792. if(fieldname==Fields[dummy++])
  1793. { // the custom fields (app specific)
  1794. field=custom;
  1795. return NoError;
  1796. }
  1797. // ----- we did not find that field:
  1798. return NoSuchField;
  1799. }
  1800. AddressBook::ErrorCode AddressBook::Entry::Address::get(const char* fieldname,
  1801. TQVariant& field)
  1802. {
  1803. // "headline", "position",
  1804. // "org", "orgunit", "orgsubunit",
  1805. // "deliverylabel", "address", "zip", "town", "country", "state"
  1806. int dummy=0;
  1807. // -----
  1808. if(fieldname==Fields[dummy++])
  1809. { // the headline
  1810. field=headline;
  1811. return NoError;
  1812. }
  1813. if(fieldname==Fields[dummy++])
  1814. { // the position
  1815. field=position;
  1816. return NoError;
  1817. }
  1818. if(fieldname==Fields[dummy++])
  1819. { // the organization
  1820. field=org;
  1821. return NoError;
  1822. }
  1823. if(fieldname==Fields[dummy++])
  1824. { // the organizational unit
  1825. field=orgUnit;
  1826. return NoError;
  1827. }
  1828. if(fieldname==Fields[dummy++])
  1829. { // the organizational subunit
  1830. field=orgSubUnit;
  1831. return NoError;
  1832. }
  1833. if(fieldname==Fields[dummy++])
  1834. { // the delivery label
  1835. field=deliveryLabel;
  1836. return NoError;
  1837. }
  1838. if(fieldname==Fields[dummy++])
  1839. { // the address
  1840. field=address;
  1841. return NoError;
  1842. }
  1843. if(fieldname==Fields[dummy++])
  1844. { // the zip code
  1845. field=zip;
  1846. return NoError;
  1847. }
  1848. if(fieldname==Fields[dummy++])
  1849. { // the town
  1850. field=town;
  1851. return NoError;
  1852. }
  1853. if(fieldname==Fields[dummy++])
  1854. { // the country
  1855. field=country;
  1856. return NoError;
  1857. }
  1858. if(fieldname==Fields[dummy++])
  1859. { // the state
  1860. field=state;
  1861. return NoError;
  1862. }
  1863. // ----- we did not find that field:
  1864. return NoSuchField;
  1865. }
  1866. Section* AddressBook::categoriesSection()
  1867. {
  1868. const TQString Predefines[]= {
  1869. i18n("Business"),
  1870. i18n("Private"),
  1871. i18n("Dates") };
  1872. size_t Size=sizeof(Predefines)/sizeof(Predefines[0]);
  1873. Section* section;
  1874. Section* categories;
  1875. KeyValueMap *keys;
  1876. // -----
  1877. if(data->get(KAB_CATEGORY_KEY, section))
  1878. {
  1879. // it exists, go ahead
  1880. return section;
  1881. } else {
  1882. kdDebug(KAB_KDEBUG_AREA)
  1883. << "AddressBook::categoriesSection: creating categories structure." << endl;
  1884. // it does not exist - create it
  1885. if(!data->createSection(KAB_CATEGORY_KEY))
  1886. {
  1887. kdDebug(KAB_KDEBUG_AREA)
  1888. << "AddressBook::categoriesSection: error creating categories section."
  1889. << endl;
  1890. return 0;
  1891. }
  1892. data->get(KAB_CATEGORY_KEY, section);
  1893. // add the predefined categories:
  1894. categories=new Section;
  1895. keys=categories->getKeys();
  1896. for(size_t count=0; count<Size; ++count)
  1897. {
  1898. TQStringList values;
  1899. values.append(Predefines[count]);
  1900. keys->insert(TQCString().setNum(count), values);
  1901. }
  1902. section->add(KAB_CATEGORY_KEY, categories);
  1903. keys=section->getKeys();
  1904. keys->insert("NextAvailableCatKey", (long)Size);
  1905. }
  1906. save();
  1907. if(data->get(KAB_CATEGORY_KEY, section))
  1908. return section;
  1909. return 0; // might not happen
  1910. }
  1911. AddressBook::ErrorCode AddressBook::categories(CategoriesMap& cat)
  1912. { // WORK_TO_DO: use a permanent cached map and update on changed()
  1913. kdDebug(KAB_KDEBUG_AREA, !cat.isEmpty())
  1914. << "AddressBook::categories: warning - categories map is supposed to be empty!"
  1915. << endl;
  1916. Section *section;
  1917. Section *categories;
  1918. KeyValueMap* keys;
  1919. int key;
  1920. bool rc;
  1921. TQStringList values;
  1922. StringStringMap::iterator pos;
  1923. // ----- query categories section:
  1924. section=categoriesSection();
  1925. TQ_CHECK_PTR(section);
  1926. // -----
  1927. if(!section->find(KAB_CATEGORY_KEY, categories))
  1928. {
  1929. kdDebug(KAB_KDEBUG_AREA)
  1930. << "AddressBook::categories: error in database structure."
  1931. << endl;
  1932. return InternError;
  1933. }
  1934. // ----- everything is set up, create the categories map:
  1935. // use an iterator to walk over all elements of categories key-value-map:
  1936. keys=categories->getKeys();
  1937. for(pos=keys->begin(); pos!=keys->end(); ++pos)
  1938. {
  1939. if(!keys->get((*pos).first, values))
  1940. {
  1941. kdDebug(KAB_KDEBUG_AREA)
  1942. << "AddressBook::categories: internal error querying categories."
  1943. << endl;
  1944. } else {
  1945. key=(*pos).first.toInt(&rc);
  1946. if(rc)
  1947. {
  1948. cat.insert(key, values[0]);
  1949. } else {
  1950. kdDebug(KAB_KDEBUG_AREA)
  1951. << "AddressBook::categories: error - non-integer category key - ignored."
  1952. << endl;
  1953. }
  1954. }
  1955. }
  1956. return NoError;
  1957. }
  1958. #include "addressbook.moc"