~ubuntu-branches/ubuntu/utopic/bbdb/utopic

« back to all changes in this revision

Viewing changes to .pc/debian-changes/bits/bbdb-gnokii.el

  • Committer: Package Import Robot
  • Author(s): Barak A. Pearlmutter
  • Date: 2014-02-24 12:17:32 UTC
  • mfrom: (13.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140224121732-y107ua2xbj8xpcau
Tags: 2.36-4
* engage dh autoreconf, rm ./configure, relax regarding ./configure +x bit
* updates to debian/README.Debian and debian/README.source
* remove CVS keyword expansion artifacts
* add savannah repo pointers to bbdb.texinfo
* remove PHONY stuff in debian/rules
* remove stray old-style quasiquote in macro
* allow emacs24 to satisfy dependencies
* bump standards version, dh version
* single debian patch source option

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;; bbdb-gnokii.el --- Export phone entries from BBDB to gnokii contacts file.
 
2
 
 
3
;;
 
4
;; Copyright (C) 2000, 2003, 2004, 2005, 2006
 
5
;;                           Martin Schwenke, Reiner Steib, Len Trigg
 
6
;; Authors: Martin Schwenke <martin@meltin.net>,
 
7
;;          Reiner Steib <Reiner.Steib@gmx.de>,
 
8
;;          Len Trigg <len@reeltwo.com>
 
9
;; Maintainer: Martin Schwenke <martin@meltin.net>
 
10
;; Created: 23 August 2000
 
11
;; $Id: bbdb-gnokii.el,v 1.16 2006/04/19 13:02:09 martins Exp $
 
12
;; Keywords: BBDB, Nokia, gnokii
 
13
;; X-URL: http://meltin.net/hacks/emacs/
 
14
 
 
15
;; This program is free software; you can redistribute it and/or modify
 
16
;; it under the terms of the GNU General Public License as published by
 
17
;; the Free Software Foundation; either version 2, or (at your option)
 
18
;; any later version.
 
19
;;
 
20
;; This program is distributed in the hope that it will be useful,
 
21
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
22
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
23
;; GNU General Public License for more details.
 
24
;;
 
25
;; If you have not received a copy of the GNU General Public License
 
26
;; along with this software, it can be obtained from the GNU Project's
 
27
;; World Wide Web server (http://www.gnu.org/copyleft/gpl.html), from
 
28
;; its FTP server (ftp://ftp.gnu.org/pub/gnu/GPL), by sending an electronic
 
29
;; mail to this program's maintainer or by writing to the Free Software
 
30
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
31
 
 
32
 
 
33
;;; Commentary:
 
34
;;
 
35
;; Exports BBDB phone entries to a contacts file that can be used by
 
36
;; gnokii to write them to a Nokia mobile phone.
 
37
;;
 
38
;; No responsibility for blowing up your phone... blah, blah, blah...
 
39
;; I recommend dumping your phone book to a file (using xgnokii, say)
 
40
;; and keeping it in a safe place until you are sure that
 
41
;; bbdb-gnokii.el doesn't do anything stupid.
 
42
;;
 
43
;; The latest version of this file is available via:
 
44
;;
 
45
;;   http://meltin.net/hacks/emacs/
 
46
;;
 
47
;; The gnokii web site is
 
48
;;
 
49
;;   http://www.gnokii.org/
 
50
;;
 
51
;; bbdb-gnokii.el is loosely based on JWZ's bbdb-pilot-jwz.el.
 
52
;;
 
53
;; gnokii expects a file with the following format:
 
54
;;
 
55
;;    name;number;memory_type;entry_location;caller_group_number;\
 
56
;;    subentry_type;subentry_number_type;subentry_id;subentry_text
 
57
;;
 
58
;; The length and syntax of "name" and "number" are limited, so some
 
59
;; munging goes on.  You can adjust the munging to your needs by
 
60
;; customizing the variables `bbdb-gnokii-firstname-transform',
 
61
;; `bbdb-gnokii-lastname-transform' and
 
62
;; `bbdb-gnokii-location-transform'.
 
63
;;
 
64
;; The default settings of these variables reflect Martin's preferences.
 
65
;; Here is a combination of alternative settings used by Reiner:
 
66
;;
 
67
;;   (setq
 
68
;;    ;; Use long firstnames and lastnames and a short location:
 
69
;;    bbdb-gnokii-firstname-transform 'bbdb-gnokii-transform-word
 
70
;;    bbdb-gnokii-lastname-transform  12
 
71
;;    bbdb-gnokii-location-transform  'bbdb-gnokii-transform-location
 
72
;;    bbdb-gnokii-max-name-length     16)
 
73
;;
 
74
;; The memory_type specifies where to write the contacts (phone memory
 
75
;; or SIM card).  See variable `bbdb-gnokii-default-memory-type' and
 
76
;; it's documentation for details.
 
77
 
 
78
;; Configuration:
 
79
;;
 
80
;; Add this to your ~/.emacs or equivalent:
 
81
;;
 
82
;;   (autoload
 
83
;;     'bbdb-gnokii-export
 
84
;;     "bbdb-gnokii"
 
85
;;     "Export phone entries from BBDB to a Gnokii contacts file."
 
86
;;     t)
 
87
;;
 
88
;; If you want to add some standard entries to your phone, you can put
 
89
;; them in a file and set the following variable:
 
90
;;
 
91
;;   (setq bbdb-gnokii-extras-file
 
92
;;         (expand-file-name "~/.bbdb-gnokii-extras.txt"))
 
93
;;
 
94
;; The contents of the specified file get appended to the file
 
95
;; generated from the BBDB (cf. `bbdb-gnokii-extras-file-position').
 
96
;; My phone vendor preloads a bunch of their numbers into the SIM
 
97
;; card, and I'm keeping them until I'm sure they're not useful!
 
98
;;
 
99
;; Entries are only extracted from the BBDB for entries that have a
 
100
;; gnokii field.  In general, if this field is present, then all of
 
101
;; the phone numbers (except those that have locations listed in
 
102
;; `bbdb-gnokii-exclude-locations') will be exported.
 
103
;;
 
104
;; For example:
 
105
;;
 
106
;;   Fred Smith - Widget, Inc.
 
107
;;         mobile: (04) 1234 5678
 
108
;;           home: (02) 1234 5678
 
109
;;         gnokii: t
 
110
;;
 
111
;; will have 2 items exported:
 
112
;;
 
113
;; Fred S mobile;0412345678;...
 
114
;; Fred S home;0212345678;...
 
115
;;
 
116
;; For entries with a name, the default generated name is the first
 
117
;; word of firstname, space, first letter of lastname.
 
118
;;
 
119
;; For entries without a name, but with a company, the default
 
120
;; generated name is the first word of the company name.
 
121
;;
 
122
;; The phone number locations are only appended if there is more than
 
123
;; 1 phone entry exported.
 
124
;;
 
125
;; If the gnokii field contains a string in double-quotes, then it
 
126
;; will be used as the name.
 
127
;;
 
128
;; If the gnokii field contains something like location=X then the
 
129
;; number for location will be put into speed-dial location X.  All
 
130
;; other entries are put between `bbdb-gnokii-general-min-location'
 
131
;; and `bbdb-gnokii-general-max-location'.
 
132
;;
 
133
;; If the gnokii field contains something like (Y) then the entry will
 
134
;; belong to caller group Y, otherwise
 
135
;; `bbdb-gnokii-default-caller-group' is used.
 
136
;;
 
137
;; So,
 
138
;;
 
139
;;   Fred Smith - Widget, Inc.
 
140
;;         mobile: (04) 1234 5678
 
141
;;           home: (02) 1234 5678
 
142
;;            fax: (02) 8765 4321
 
143
;;         gnokii: "Freddy" (0) mobile=2 home=3
 
144
;;
 
145
;; will have 2 items exported:
 
146
;;
 
147
;; Freddy mobile;0412345678;...;0;
 
148
;; Freddy home;0212345678;...;0;
 
149
;;
 
150
;; No item is exported for the fax number because it is a member of
 
151
;; `bbdb-gnokii-exclude-locations'.
 
152
;;
 
153
;; If the gnokii field contains "skip=foo", the phone number corresponding to
 
154
;; the location "foo" will not be exported.
 
155
;;
 
156
;; You can also export a whole BBDB record to a single gnokii entry by
 
157
;; setting `bbdb-gnokii-phonebook-style' to `multi' or `mega'.  In
 
158
;; this style the default phone number can be set by specifying the
 
159
;; associated location in the BBDB gnokii field.  For example, if the
 
160
;; gnokii field contains "[work]" then the phone number with location
 
161
;; "work" will be the default one.  If no default location is
 
162
;; specified in the gnokii field, then the order of preference is
 
163
;; determined by `bbdb-gnokii-preferred-phone-locations'.  If
 
164
;; `bbdb-gnokii-phonebook-style' is set to `mega', an email address
 
165
;; and postal address are also added to the gnokii entry, when
 
166
;; available.
 
167
 
 
168
;; See the variables and code below for more details.  You may check all
 
169
;; customizable variables using `M-x customize-group RET bbdb-gnokii RET'.
 
170
 
 
171
 
 
172
 
 
173
;;; History:
 
174
 
 
175
;; $Log: bbdb-gnokii.el,v $
 
176
;; Revision 1.16  2006/04/19 13:02:09  martins
 
177
;; Function bbdb-gnokii-do-name now just uses firstname if lastname is
 
178
;; not set.  Suggested by Magnus Henoch <mange@freemail.hu>.
 
179
;;
 
180
;; Revision 1.15  2005/06/06 09:52:49  martins
 
181
;; Added support for gnokii entries with multiple phone numbers using
 
182
;; subentries, implemented using a variation and subset of code by Len
 
183
;; Trigg: new variables bbdb-gnokii-phonebook-style and
 
184
;; bbdb-gnokii-preferred-phone-locations; removed variable
 
185
;; bbdb-gnokii-insert-extra-fields (replaced by
 
186
;; bbdb-gnokii-phonebook-style); removed defstruct bbdb-gnokii; replaced
 
187
;; functions bbdb-gnokii-convert and bbdb-gnokii-format with new function
 
188
;; bbdb-gnokii-format-record, which has most of the implementation
 
189
;; details for this feature; new functions bbdb-gnokii-format-address,
 
190
;; bbdb-gnokii-phones-find-location, bbdb-gnokii-get-default-phone;
 
191
;; retain '+' in phone number in function bbdb-gnokii-fix-phone;
 
192
;; bbdb-gnokii-export just calls bbdb-gnokii-format-record for each
 
193
;; record, instead of converting and then formatting; added Len Trigg to
 
194
;; to copyright and authors.
 
195
;;
 
196
;; Revision 1.14  2004/03/30 12:01:29  martins
 
197
;; After discussion with Reiner, changed the names of the following
 
198
;; variables:
 
199
;;
 
200
;;   bbdb-gnokii-default-group  -> bbdb-gnokii-default-caller-group
 
201
;;   bbdb-gnokii-default-memtype        -> bbdb-gnokii-default-memory-type
 
202
;;   bbdb-gnokii-general-maxpos -> bbdb-gnokii-general-max-location
 
203
;;   bbdb-gnokii-general-minpos -> bbdb-gnokii-general-min-location
 
204
;;   bbdb-gnokii-speed-maxpos   -> bbdb-gnokii-speed-dial-max-location
 
205
;;   bbdb-gnokii-speed-minpos   -> bbdb-gnokii-speed-dial-min-location
 
206
;;
 
207
;; for consistency with gnokii documentation, and changed associated
 
208
;; documentation accordingly.  In struct bbdb-gnokii- changed name of
 
209
;; member `mempos' to `location'.  Also changed function names:
 
210
;;
 
211
;;   bbdb-gnokii-do-mempos              -> bbdb-gnokii-do-location
 
212
;;   bbdb-gnokii-do-group               -> bbdb-gnokii-do-caller-group
 
213
;;
 
214
;; Revision 1.13  2004/03/02 00:50:53  martins
 
215
;; Documentation cleanups by Reiner Steib <Reiner.Steib@gmx.de>.
 
216
;;
 
217
;; Revision 1.12  2004/02/27 03:40:59  martins
 
218
;; bbdb-gnokii-default-memtype now has default value of "SM" (for
 
219
;; compatibility with xgnokii >= 0.6) - documentation and customisation
 
220
;; choices have also been improved.  bbdb-gnokii-default-group's
 
221
;; documentation and customisation choices have also been improved.
 
222
;; Changes implemented by Reiner Steib <Reiner.Steib@gmx.de>.
 
223
;;
 
224
;; Revision 1.11  2004/02/25 01:16:08  martins
 
225
;; Added RCS Log section in History and imported previous entries.
 
226
;; Thanks again to Reiner.
 
227
;;
 
228
;; Revision  1.10  2004/02/07 11:47:04  martins
 
229
;; Replaced uses of bbdb-gnokii-extra-tag with bbdb-gnokii-extra-tags.
 
230
;; Oops.
 
231
 
 
232
;; Revision  1.9  2004/02/07 11:40:31  martins
 
233
;; `bbdb-gnokii-extra-tags': New variable for Siemens C35 used in
 
234
;; `bbdb-gnokii-export'.  Exchanged defun and defalias:
 
235
;; bbdb-gnokii-export vs. bbdb-to-gnokii-file.  Changed documentation
 
236
;; section to mention bbdb-gnokii-export, not bbdb-to-gnokii.  Renamed
 
237
;; function bbdb-record-to-gnokii-records to bbdb-gnokii-convert.  Minor
 
238
;; cosmetic fixes.  Thanks to Reiner Steib <Reiner.Steib@gmx.de>.
 
239
 
 
240
;; Revision  1.8  2004/02/06 03:07:33  martins
 
241
;; Merged changes from Reiner Steib <reiner.steib@gmx.de>: Made
 
242
;; variables customizable.  Did some checkdoc fixes.  Made many things
 
243
;; more flexible, especially the shortening of firstname, lastname and
 
244
;; location strings.  Added `bbdb-gnokii-add-field'.  Also replaced
 
245
;; variable `bbdb-gnokii-maxpos' with `bbdb-gnokii-general-minpos' and
 
246
;; `bbdb-gnokii-general-maxpos'.  Added information about where to get
 
247
;; latest version.  Various documentation fixes.  Added variable
 
248
;; `bbdb-gnokii-insert-extra-fields'.  Various documentation fixes.
 
249
;; Removed declarations of variables `bbdb-gnokii-mempos' and
 
250
;; `bbdb-gnokii-speed-done' (since they are bound in a `let').
 
251
 
 
252
;; Revision  1.7  2003/07/01 01:44:29  martins
 
253
;; Added extra fields to output, which seem to be required for newer
 
254
;; phones/gnokiis.
 
255
 
 
256
;; Revision  1.6  2003/06/30 01:58:10  martins
 
257
;; (bbdb-gnokii-do-name): Handle case where lastname is empty.
 
258
 
 
259
;; Revision  1.5  2001/02/12 00:10:45  martin
 
260
;; Changed e-mail address.
 
261
 
 
262
;; Revision  1.4  2000/10/04 00:41:58  martins
 
263
;; Changed default-memtype back to "A".
 
264
 
 
265
;; Revision  1.3  2000/08/25 02:58:15  martins
 
266
;; - Added documentation and stuff at top.
 
267
;; - Changed spelling from Gnokii to gnokii.
 
268
;; - Changed default memory type to work with command-line gnokii.
 
269
;; - Reduced allowable length of names.
 
270
;; - Added bbdb-gnokii-exclude-locations and associated filtering.
 
271
;;   Thanks to Chris Yeoh.
 
272
;; - Added various comments.
 
273
 
 
274
;; Revision  1.2  2000/08/24 11:52:57  martins
 
275
;; Fixed RCS Id string.
 
276
 
 
277
;; Revision  1.1  2000/08/24 11:52:39  martins
 
278
;; Initial revision
 
279
 
 
280
 
 
281
;;; Code:
 
282
(require 'bbdb)
 
283
 
 
284
;; Only for `bbdb-gnokii-add-field':
 
285
(autoload 'bbdb-merge-interactively "bbdb-snarf" nil nil)
 
286
(autoload 'bbdb-add-new-field "bbdb-com" nil nil)
 
287
 
 
288
(defgroup bbdb-gnokii nil
 
289
  "Sync BBDB and gnokii."
 
290
  :group 'bbdb)
 
291
 
 
292
(defcustom bbdb-gnokii-transform-word-regexp
 
293
  (if (string-match "[[:word:]]" "x")
 
294
      "[^-[:word:]]"
 
295
    ;; old Emacsen (e.g. Emacs 20) don't support character classes.
 
296
    "[^-A-Za-z]")
 
297
  "Regexp used to shorten names in `bbdb-gnokii-transform-word'."
 
298
  :group 'bbdb-gnokii
 
299
  :type '(choice (const :tag "first word" "[^-[:word:]]")
 
300
                 (const :tag "ascii" "[^-A-Za-z]")
 
301
                 (regexp :tag "Other")))
 
302
 
 
303
(defun bbdb-gnokii-transform-max (name &optional limit)
 
304
  "Limit NAME to LIMIT characters."
 
305
  (if (> (length name) limit)
 
306
      (substring name 0 limit)
 
307
    name))
 
308
 
 
309
(defun bbdb-gnokii-transform-word (name &optional regexp)
 
310
  "Shorten NAME to first word.
 
311
`bbdb-gnokii-transform-word-regexp' is used unless REGEXP is given."
 
312
  (substring name
 
313
             0 (string-match (or regexp bbdb-gnokii-transform-word-regexp) name)))
 
314
 
 
315
(defun bbdb-gnokii-transform-location (location)
 
316
  "Shorten LOCATION field."
 
317
  ;; The default BBDB location "Office" and "Other" both give "O"
 
318
  (if (string= name "Other")
 
319
      "o"
 
320
    (bbdb-gnokii-transform-max location 1)))
 
321
 
 
322
(defcustom bbdb-gnokii-firstname-transform 'bbdb-gnokii-transform-word
 
323
  "How to transform the lastname field to short variant.
 
324
If a function, call it with the name as it's argument.  If a number, use
 
325
substring with maximal length number."
 
326
  :group 'bbdb-gnokii
 
327
  :type '(choice (const bbdb-gnokii-transform-word)
 
328
                 (function)
 
329
                 (integer)))
 
330
 
 
331
(defcustom bbdb-gnokii-lastname-transform 1
 
332
  "How to transform the lastname field to short variant.
 
333
If a function, call it with the name as it's argument.  If a number, use
 
334
substring with maximal length number."
 
335
  :group 'bbdb-gnokii
 
336
  :type '(choice (const bbdb-gnokii-transform-word)
 
337
                 (function)
 
338
                 (integer)))
 
339
 
 
340
(defcustom bbdb-gnokii-location-transform 10
 
341
  "Transform the location field to short variant.
 
342
If a function, call it with the name as it's argument.  If a number, use
 
343
substring with maximal length number."
 
344
  :group 'bbdb-gnokii
 
345
  :type '(choice (const bbdb-gnokii-transform-location)
 
346
                 (function)
 
347
                 (integer)))
 
348
 
 
349
(defun bbdb-gnokii-apply-transform (transform name)
 
350
  "Apply transformation TRANSFORM to NAME and return a shortened name."
 
351
  (cond
 
352
   ((functionp transform)
 
353
    (funcall transform name))
 
354
   ((natnump transform)
 
355
    (bbdb-gnokii-transform-max name transform))
 
356
   (t name)))
 
357
 
 
358
(defcustom bbdb-gnokii-extras-file nil
 
359
  "Name of file containing extra entries to add to gnokii."
 
360
  :group 'bbdb-gnokii
 
361
  :type '(choice (const :tag "None" nil)
 
362
                 (file)))
 
363
 
 
364
(defcustom bbdb-gnokii-extra-tags nil
 
365
  "List of two string elements: \"\(\"tag\" \"indicator\"\)\" or nil.
 
366
For each occurance of the form \"location=tag\" in the BBDB gnokii field, the
 
367
gnokii string \"indicator\" will be appended to the generated name in the
 
368
gnokii file.  In some Siemens phones \(C35 and possibly others\), the
 
369
indicator \"!\" is used to specify a \"VIP entry\"."
 
370
  :group 'bbdb-gnokii
 
371
  :type '(choice (const :tag "Siemens C35 style" ("vip" "!"))
 
372
                 (list (symbol :tag "BBDB tag")
 
373
                       (symbol :tag "Gnokii string"))))
 
374
 
 
375
(defcustom bbdb-gnokii-default-output-file nil
 
376
  "Name of the default output file.
 
377
If the filename contains the string \"%s\", it will be replaced
 
378
with the current date in ISO format (YYYY-MM-DD)."
 
379
  :group 'bbdb-gnokii
 
380
  :type '(choice (const :tag "None" nil)
 
381
                 (file)))
 
382
 
 
383
(defcustom bbdb-gnokii-extras-file-position 'bottom
 
384
  "Where to insert `bbdb-gnokii-extras-file'."
 
385
  :group 'bbdb-gnokii
 
386
  :type '(choice (const :tag "Top" top)
 
387
                 (const :tag "Bottom" bottom)))
 
388
 
 
389
(defcustom bbdb-gnokii-inserted-hook nil
 
390
  "Hook run after all records from BBDB were inserted into the output buffer.
 
391
The hook is called in the output buffer immediately before saving the buffer."
 
392
  :group 'bbdb-gnokii
 
393
  :type 'hook)
 
394
 
 
395
(defcustom bbdb-gnokii-confirm-kill nil
 
396
  "Ask for confirmation before killing the output buffer."
 
397
  :group 'bbdb-gnokii
 
398
  :type 'boolean)
 
399
 
 
400
(defcustom bbdb-gnokii-phonebook-style 'single
 
401
  "Style for phonebook entries.
 
402
This affects the number of phone numbers per gnokii entry and the way
 
403
the name is constructed.  `single' (the default) allows only a single
 
404
phone number per gnokii entry, and also generates a subentry for that
 
405
phone number.  `ancient' also allows only a single phone number per
 
406
gnokii entry, but generates no subentry - older versions of gnokii
 
407
seem to work like this.  `multiple' causes all phone numbers for a
 
408
BBDB entry to be put into a single gnokki entry, using multiple
 
409
subentries - in this case the location is also never appended to the
 
410
name.  `mega' is like multiple but causes the 1st email address and
 
411
postal address to also be put into the gnokii entry.  Note that
 
412
`multiple' and `mega' probably won't work well with
 
413
`bbdb-gnokii-default-memory-type' set to \"SM\"."
 
414
  :type '(choice (const :tag "Single with subentry"      single)
 
415
                 (const :tag "Single without subentry"   ancient)
 
416
                 (const :tag "Multiple subentries"       multiple)
 
417
                 (const :tag "Subentries, email, postal" mega)))
 
418
 
 
419
(defcustom bbdb-gnokii-speed-dial-min-location 1
 
420
  "Minimum memory location allowed for speed dial entries.
 
421
See also `bbdb-gnokii-general-min-location',
 
422
`bbdb-gnokii-general-max-location' and
 
423
`bbdb-gnokii-speed-dial-max-location'.  The range for speed dial
 
424
entries should not overlap with the range for general entries, or
 
425
entries found in `bbdb-gnokii-extras-file'."
 
426
  :group 'bbdb-gnokii
 
427
  :type 'integer)
 
428
 
 
429
(defcustom bbdb-gnokii-speed-dial-max-location 9
 
430
  "Maximum memory location allowed for speed dial entries.
 
431
See also `bbdb-gnokii-general-min-location',
 
432
`bbdb-gnokii-general-max-location' and
 
433
`bbdb-gnokii-speed-dial-min-location'.  The range for speed dial
 
434
entries should not overlap with the range for general entries, or
 
435
entries found in `bbdb-gnokii-extras-file'."
 
436
  :group 'bbdb-gnokii
 
437
  :type 'integer)
 
438
 
 
439
(defcustom bbdb-gnokii-general-min-location 10
 
440
  "Minimum memory location allowed for general BBDB to gnokii entries.
 
441
See also `bbdb-gnokii-general-max-location',
 
442
`bbdb-gnokii-speed-dial-min-location' and
 
443
`bbdb-gnokii-speed-dial-max-location'.  The range for speed dial
 
444
entries should not overlap with the range for general entries, or
 
445
entries found in `bbdb-gnokii-extras-file'."
 
446
  :group 'bbdb-gnokii
 
447
  :type 'integer)
 
448
 
 
449
(defcustom bbdb-gnokii-general-max-location 89
 
450
  "Maximum memory location allowed for general BBDB to gnokii entries.
 
451
See also `bbdb-gnokii-general-min-location',
 
452
`bbdb-gnokii-speed-dial-min-location' and
 
453
`bbdb-gnokii-speed-dial-max-location'.  The range for speed dial
 
454
entries should not overlap with the range for general entries, or
 
455
entries found in `bbdb-gnokii-extras-file'."
 
456
  :group 'bbdb-gnokii
 
457
  :type 'integer)
 
458
 
 
459
(defcustom bbdb-gnokii-default-memory-type "SM"
 
460
  "Default type of phone memory to use for BBDB to gnokii entries.
 
461
\"SM\" is for SIM card, \"ME\" for the phone memory.  In versions prior to
 
462
0.6, `xgnokii' used \"A\" is for SIM card and \"B\" for the phone memory.
 
463
Please see the documentation of gnokii and xgnokii for valid values."
 
464
  :group 'bbdb-gnokii
 
465
  :type '(choice (const :tag "SIM card" "SM")
 
466
                 (const :tag "phone memory" "ME")
 
467
                 (const :tag "SIM card (for old xgnokii)" "A")
 
468
                 (const :tag "phone memory (for old xgnokii)" "B")
 
469
                 ;; Other valid memory types probably aren't writable.
 
470
                 (string :tag "Other")))
 
471
 
 
472
(defcustom bbdb-gnokii-default-caller-group 5
 
473
  "Default caller group to put BBDB to gnokii entries into.
 
474
 
 
475
If the gnokii field contains something like \"\(N\)\" then the entry will
 
476
belong to caller group N, otherwise `bbdb-gnokii-default-caller-group'
 
477
is used.  Possible values are 0 \(Family\), 1 \(VIP\), 2 \(Friends\),
 
478
3 \(Colleagues\), 4 \(Other group\), 5 \(No group\).  Note that these
 
479
are defaults, you are able to change these manually in your phone.
 
480
See also \"caller_group_number\" in the documentation of gnokii."
 
481
  :group 'bbdb-gnokii
 
482
  :type '(choice (const :tag "0 (Family)" 0)
 
483
                 (const :tag "1 (VIP)" 1)
 
484
                 (const :tag "2 (Friends)" 2)
 
485
                 (const :tag "3 (Colleagues)" 3)
 
486
                 (const :tag "4 (Other group)" 4)
 
487
                 (const :tag "5 (No group)" 5)
 
488
                 (integer :tag "Other")))
 
489
 
 
490
(defcustom bbdb-gnokii-max-name-length 17
 
491
  "Maximum allowable length of name field."
 
492
  :group 'bbdb-gnokii
 
493
  :type 'integer)
 
494
 
 
495
(defcustom bbdb-gnokii-exclude-locations '("fax")
 
496
  "List of locations for phone numbers to exclude."
 
497
  :group 'bbdb-gnokii
 
498
  :type '(choice (const :tag "None" nil)
 
499
                 (const :tag "Fax" '("fax"))
 
500
                 (repeat (string :tag "Field"))))
 
501
 
 
502
(defcustom bbdb-gnokii-preferred-phone-locations '("mobile" "home" "work")
 
503
  "List of locations for choosing default phone number in multi-phone entries.
 
504
The phone number associated with earliest location in this list is used.
 
505
Otherwise, the first phone number is used." 
 
506
  :group 'bbdb-gnokii
 
507
  :type '(choice (repeat (string :tag "Field"))))
 
508
 
 
509
(defconst bbdb-gnokii-label-type-alist
 
510
  '(("home"   .  2)
 
511
    ("mobile" .  3)
 
512
    ("fax"    .  4)
 
513
    ("office" .  6)
 
514
    ("work"   .  6)
 
515
    ("."      . 10))
 
516
  "Alist mapping BBDB phones labels to gnokii phone number types.")
 
517
 
 
518
(defun bbdb-gnokii-format-record (record)
 
519
  "Convert a BBDB RECORD to text in the current buffer."
 
520
 
 
521
  (let ((allphones (bbdb-record-phones record))
 
522
        (allnet (bbdb-record-net record))
 
523
        (alladdresses (bbdb-record-addresses record))
 
524
        (stuff (if (listp (bbdb-record-raw-notes record))
 
525
                   (cdr (assq 'gnokii (bbdb-record-raw-notes record)))))
 
526
        (subentry-id 0)
 
527
        name useloc phones default-phone print-escape-newlines)
 
528
 
 
529
    (setq name (bbdb-gnokii-do-name (bbdb-record-lastname record)
 
530
                                    (bbdb-record-firstname record)
 
531
                                    (bbdb-record-company record)
 
532
                                    stuff))
 
533
 
 
534
    ;; Filter out unwanted phone locations and find default phone number.
 
535
    (while allphones
 
536
      (let ((p (car allphones)))
 
537
        (if (not (or (member (bbdb-phone-location p)
 
538
                             bbdb-gnokii-exclude-locations)
 
539
                     (string-match (concat "\\<skip=\\("
 
540
                                           (bbdb-phone-location p)
 
541
                                           "\\)\\>")
 
542
                                   (or stuff ""))))
 
543
          (add-to-list 'phones p)))
 
544
      (setq allphones (cdr allphones)))
 
545
 
 
546
    (if (memq bbdb-gnokii-phonebook-style '(multiple mega))
 
547
        (setq default-phone (bbdb-gnokii-get-default-phone phones stuff)))
 
548
 
 
549
    ;; Only continue if they have a name, a gnokii field and some
 
550
    ;; phone numbers.
 
551
    (if (and name stuff phones)
 
552
        (progn
 
553
          ;; Only add the location to name if there is >1 phone number
 
554
          ;; and we're not doing multiple-subentries.
 
555
          (setq useloc (and (> (length phones) 1)
 
556
                            (memq bbdb-gnokii-phonebook-style
 
557
                                       '(ancient single))))
 
558
          ;; Create records.
 
559
          (while phones
 
560
            (let* ((location (bbdb-phone-location (car phones)))
 
561
                   (loc (bbdb-gnokii-apply-transform
 
562
                         bbdb-gnokii-location-transform
 
563
                         location))
 
564
                   (num (bbdb-gnokii-fix-phone
 
565
                         (bbdb-phone-string (car phones))))
 
566
                   (default-loc (or (and default-phone
 
567
                                         (bbdb-gnokii-apply-transform
 
568
                                          bbdb-gnokii-location-transform
 
569
                                          (bbdb-phone-location default-phone)))
 
570
                                    loc))
 
571
                   (default-num (or (and default-phone
 
572
                                         (bbdb-gnokii-fix-phone
 
573
                                          (bbdb-phone-string default-phone)))
 
574
                                    num))
 
575
                   (name (if useloc (concat name " " loc) name)))
 
576
              (if (> (length name) bbdb-gnokii-max-name-length)
 
577
                  ;; Don't error out on long entries, truncate them instead.
 
578
                  (progn
 
579
                    (message
 
580
                     (concat
 
581
                      "Name \"%s\" is too long.  "
 
582
                      "Maybe you want to edit gnokii field.")
 
583
                     name)
 
584
                    (setq
 
585
                     name
 
586
                     (cond
 
587
                      ;; Make sure we don't strip location:
 
588
                      (useloc
 
589
                       (concat
 
590
                        (bbdb-gnokii-transform-max
 
591
                         name (- bbdb-gnokii-max-name-length
 
592
                                 (1+ (length loc))))
 
593
                        " " loc))
 
594
                      (t
 
595
                       (bbdb-gnokii-transform-max
 
596
                        name bbdb-gnokii-max-name-length))))))
 
597
              ;; Checking for bbdb-gnokii-extra-tags:
 
598
              (when (and (car  bbdb-gnokii-extra-tags)
 
599
                         (cadr bbdb-gnokii-extra-tags)
 
600
                         location
 
601
                         (string-match
 
602
                          (concat
 
603
                           "\\<" location
 
604
                           "="
 
605
                           (regexp-quote (car bbdb-gnokii-extra-tags))
 
606
                           "\\>")
 
607
                          stuff))
 
608
                ;; extra entry found, changing label:
 
609
                (setq name
 
610
                      (concat (bbdb-gnokii-transform-max
 
611
                               name (- bbdb-gnokii-max-name-length 1))
 
612
                              (cadr bbdb-gnokii-extra-tags))))
 
613
 
 
614
              (if (= subentry-id 0)
 
615
                  (insert (format "%s;%s;%s;%s;%s"
 
616
                                  name
 
617
                                  default-num
 
618
                                  bbdb-gnokii-default-memory-type
 
619
                                  (bbdb-gnokii-do-location stuff default-loc)
 
620
                                  (bbdb-gnokii-do-caller-group stuff))))
 
621
              (if (not (eq bbdb-gnokii-phonebook-style 'ancient))
 
622
                  (insert (format ";11;%d;%d;%s" 
 
623
                                  (assoc-default location
 
624
                                                 bbdb-gnokii-label-type-alist
 
625
                                                 'string-match nil)
 
626
                                  subentry-id
 
627
                                  num)))
 
628
 
 
629
              ;; Continute along list of phone numbers.
 
630
              (setq phones (cdr phones))
 
631
              ;; If doing multiple per entry, increment subentry-id count.
 
632
              (if (memq bbdb-gnokii-phonebook-style '(multiple mega))
 
633
                  (setq subentry-id (1+ subentry-id))
 
634
                (insert "\n"))))
 
635
 
 
636
          (when (eq bbdb-gnokii-phonebook-style 'mega)
 
637
            ;; First email address?
 
638
            (when allnet
 
639
              (insert (format ";8;0;%d;%s" subentry-id (car allnet)))
 
640
              (setq subentry-id (1+ subentry-id)))
 
641
            ;; First postal address?
 
642
            (when alladdresses
 
643
              (insert (format ";9;0;%d;%s" subentry-id
 
644
                              (bbdb-gnokii-format-address (car alladdresses))))
 
645
              (setq subentry-id (1+ subentry-id))))
 
646
          (if (memq bbdb-gnokii-phonebook-style '(multiple mega))
 
647
              (insert "\n"))
 
648
          ))))
 
649
 
 
650
(defun bbdb-gnokii-format-address (address)
 
651
  "Generates a single-line representation of an address."
 
652
  (let (st field)
 
653
    (cond ((>= bbdb-file-format 6)
 
654
           (setq st (bbdb-join (bbdb-address-streets address) "\\n")))
 
655
          (t
 
656
           (setq st (bbdb-address-street1 address))
 
657
           (if (> (length (bbdb-address-street2 address)) 0)
 
658
               (setq st (concat st "\\n" (bbdb-address-street2 address))))
 
659
           (if (> (length (bbdb-address-street3 address)) 0)
 
660
               (setq st (concat st "\\n" (bbdb-address-street3 address))))))
 
661
    (setq field (bbdb-address-city address))
 
662
    (if (> (length field) 0) (setq st (concat st "\\n" field)))
 
663
    (setq field (bbdb-address-state address))
 
664
    (if (> (length field) 0) (setq st (concat st "\\n" field)))
 
665
    (setq field (bbdb-address-zip-string address))
 
666
    (if (> (length field) 0) (setq st (concat st "\\n" field)))
 
667
    (setq field (bbdb-address-country address))
 
668
    (if (> (length field) 0) (setq st (concat st "\\n" field)))
 
669
    st))
 
670
 
 
671
(defun bbdb-gnokii-do-name (lastname firstname company stuff)
 
672
  "Construct a name from the given arguments."
 
673
 
 
674
  (let (name)
 
675
 
 
676
    (cond
 
677
 
 
678
     ((and stuff
 
679
           (string-match "\"\\([^\"]+\\)\"" stuff))
 
680
      (setq name (substring stuff (match-beginning 1) (match-end 1))))
 
681
 
 
682
     (firstname
 
683
      ;; Yay, they have a name!  Default is first word of firstname,
 
684
      ;; space, first letter of lastname.
 
685
      (setq name
 
686
            (bbdb-gnokii-apply-transform
 
687
             bbdb-gnokii-firstname-transform firstname))
 
688
      (when (> (length lastname) 0)
 
689
        (setq name
 
690
              (concat name
 
691
                      " "
 
692
                      (setq name
 
693
                            (bbdb-gnokii-apply-transform
 
694
                             bbdb-gnokii-lastname-transform lastname))))))
 
695
     (company
 
696
      ;; Yay, first word of company name!
 
697
      ;; Maybe this should be made customizable, too (Reiner Steib).
 
698
      (setq name (substring company 0 (string-match " " company)))))
 
699
    name))
 
700
 
 
701
 
 
702
(defun bbdb-gnokii-do-location (stuff loc)
 
703
  "Calculate the `location' field for a gnokii record.
 
704
The field content STUFF and the location LOC are used."
 
705
 
 
706
  (let (num)
 
707
    (if (and stuff
 
708
             (string-match (concat "\\<" loc "=\\([0-9]+\\)") stuff))
 
709
        (progn
 
710
          (setq num (string-to-number
 
711
                     (substring stuff (match-beginning 1) (match-end 1))))
 
712
          (if (or (< num bbdb-gnokii-speed-dial-min-location)
 
713
                  (> num bbdb-gnokii-speed-dial-max-location)
 
714
                  (member num bbdb-gnokii-speed-done))
 
715
              (error
 
716
               "Speed dial location %d out of range or duplicate for %s"
 
717
               num name)
 
718
            (add-to-list 'bbdb-gnokii-speed-done num)))
 
719
      (if (> bbdb-gnokii-location bbdb-gnokii-general-max-location)
 
720
          (error "Too many records to fit in SIM card!"))
 
721
      (setq num bbdb-gnokii-location)
 
722
      (setq bbdb-gnokii-location (+ bbdb-gnokii-location 1)))
 
723
    num))
 
724
 
 
725
(defun bbdb-gnokii-do-caller-group (bbdb-field)
 
726
  "Calculate the caller `group' field for given BBDB-FIELD."
 
727
 
 
728
  (let (group)
 
729
    (if (and bbdb-field
 
730
             (string-match "(\\([0-9]+\\))" bbdb-field))
 
731
        (setq group (string-to-number
 
732
                     (substring bbdb-field (match-beginning 1) (match-end 1))))
 
733
      (setq group bbdb-gnokii-default-caller-group))
 
734
    group))
 
735
 
 
736
(defun bbdb-gnokii-phones-find-location (location phones)
 
737
  "Return the phone element in PHONES with given LOCATION, nil if not found."
 
738
  (let ((ps phones)
 
739
        ret)
 
740
    (while (and (not ret) ps)
 
741
      (if (string= location (bbdb-phone-location (car ps)))
 
742
          (setq ret (car ps)))
 
743
      (setq ps (cdr ps)))
 
744
    ret))
 
745
 
 
746
(defun bbdb-gnokii-get-default-phone (phones stuff)
 
747
  "Get the default phone entry for a record."
 
748
 
 
749
  (let* ((loc (and stuff
 
750
                 (string-match "\\[\\([^]]+\\)\\]" stuff)
 
751
                 (substring stuff (match-beginning 1) (match-end 1))))
 
752
         (locs bbdb-gnokii-preferred-phone-locations)
 
753
         ret)
 
754
 
 
755
    (if loc
 
756
        (setq ret (bbdb-gnokii-phones-find-location loc phones)))
 
757
 
 
758
    (while (and (not ret) locs)
 
759
      (setq ret (bbdb-gnokii-phones-find-location (car locs) phones))
 
760
      (setq locs (cdr locs)))
 
761
    (or ret (car phones))))
 
762
 
 
763
(defun bbdb-gnokii-fix-phone (phone)
 
764
  "Change phone number PHONE to gnokii compatible form."
 
765
 
 
766
  (let ((chars phone)
 
767
        out)
 
768
    (while (> (length chars) 0)
 
769
      (let ((h (substring chars 0 1)))
 
770
      (if (string-match "[+0-9]" h)
 
771
          (setq out (concat out h)))
 
772
      (setq chars (substring chars 1))))
 
773
    out))
 
774
 
 
775
;;;###autoload
 
776
(defalias 'bbdb-to-gnokii-file 'bbdb-gnokii-export)
 
777
 
 
778
;;;###autoload
 
779
(defun bbdb-gnokii-export (filename &optional records)
 
780
  "Export phone entries from BBDB to a gnokii contacts file FILENAME.
 
781
Unless RECORDS is given, all BBDB entries are processed."
 
782
  (interactive
 
783
   (list (let ((default (if (stringp bbdb-gnokii-default-output-file)
 
784
                            (format bbdb-gnokii-default-output-file
 
785
                                    (format-time-string "%Y-%m-%d" (current-time)))
 
786
                          default-directory)))
 
787
           (read-file-name "Output file: "
 
788
                           (file-name-directory default)
 
789
                           default
 
790
                           nil
 
791
                           (file-name-nondirectory default)))))
 
792
  (or records (setq records (bbdb-records)))
 
793
  (save-excursion
 
794
    (set-buffer (find-file-noselect filename))
 
795
    (erase-buffer)
 
796
    (let ((len (length records))
 
797
          (i 0)
 
798
          (bbdb-gnokii-location bbdb-gnokii-general-min-location)
 
799
          bbdb-gnokii-speed-done)
 
800
      (while records
 
801
        (message "%d%%..." (/ (* 100 i) len))
 
802
        (bbdb-gnokii-format-record (car records))
 
803
        (setq records (cdr records)
 
804
              i (1+ i))))
 
805
    (when (and bbdb-gnokii-extras-file
 
806
               (file-readable-p bbdb-gnokii-extras-file))
 
807
      (cond ((eq bbdb-gnokii-extras-file-position 'top)
 
808
             (goto-char (point-min)))
 
809
            ((eq bbdb-gnokii-extras-file-position 'bottom)
 
810
             (goto-char (point-max))))
 
811
      (insert-file-contents bbdb-gnokii-extras-file))
 
812
    (run-hooks 'bbdb-gnokii-inserted-hook)
 
813
    (save-buffer)
 
814
    ;; Useful especially when testing.
 
815
    (when (or (not bbdb-gnokii-confirm-kill)
 
816
              (y-or-n-p "Kill output buffer? "))
 
817
      (kill-buffer (current-buffer))))
 
818
  filename)
 
819
 
 
820
;;;###autoload
 
821
(defun bbdb-gnokii-add-field (&optional records)
 
822
  "Go through all RECORDS and ask for adding a gnokii field.
 
823
If RECORDS is nil, go thru all records.  If a BBDB record has an
 
824
expire field in YYYY-MM-DD format \(e.g. \"expire=2003-12-31\"\),
 
825
the record is skipped if it is older than today."
 
826
  (interactive)
 
827
  (or records (setq records (bbdb-records)))
 
828
  (bbdb-add-new-field 'gnokii)
 
829
  (dolist (record records)
 
830
    ;; Go thru all records, check if we have a phone and no gnokii field.
 
831
    (if (bbdb-record-phones record)
 
832
        (let* ((have-gnokii
 
833
                (and (listp (bbdb-record-raw-notes record))
 
834
                     (cdr (assq 'gnokii (bbdb-record-raw-notes record)))))
 
835
               (expire
 
836
                (and (listp (bbdb-record-raw-notes record))
 
837
                     (cdr (assq 'expire (bbdb-record-raw-notes record)))))
 
838
               (name (bbdb-record-name record))
 
839
               (is-expired (and
 
840
                            expire
 
841
                            (string-lessp expire
 
842
                                          (format-time-string
 
843
                                           "%Y-%m-%d" (current-time))))))
 
844
          (message "In record `%s': gnokii=`%s', expire=`%s', is-exp=`%s'"
 
845
                   name have-gnokii expire is-expired)
 
846
          (cond
 
847
           (is-expired
 
848
            (message "In record `%s': is expired." name))
 
849
           (have-gnokii
 
850
            (message "In record `%s': already has gnokii field." name))
 
851
           ((y-or-n-p (format "Add gnokii field to `%s'? " name))
 
852
            (bbdb-merge-interactively name;; name
 
853
                                      nil ;; company
 
854
                                      nil ;; net
 
855
                                      nil ;; addrs
 
856
                                      nil ;; phones
 
857
                                      '((gnokii . "t")))
 
858
            (message "In record `%s': gnokii field added." name))
 
859
           (t
 
860
            (message "In record `%s': gnokii refused interactively." name))))
 
861
      (message "In record `%s': no phone found." (bbdb-record-name record)))))
 
862
 
 
863
(provide 'bbdb-gnokii)
 
864
 
 
865
;;; bbdb-gnokii.el ends here