]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/spine_labels.js
Add font-weight to label settings to support boldness
[Evergreen.git] / Open-ILS / xul / staff_client / server / cat / spine_labels.js
1         function my_init() {
2             try {
3                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
4                 if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
5                 JSAN.errorLevel = "die"; // none, warn, or die
6                 JSAN.addRepository('/xul/server/');
7                 JSAN.use('util.error'); g.error = new util.error();
8                 g.error.sdump('D_TRACE','my_init() for spine_labels.xul');
9
10                 JSAN.use('util.network'); g.network = new util.network();
11
12                 g.cgi = new CGI();
13
14                 g.barcodes = [];
15                 if (g.cgi.param('barcodes')) {
16                     g.barcodes = g.barcodes.concat( JSON2js(g.cgi.param('barcodes')) );
17                 }
18                 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.stash_retrieve();
19                 if (g.data.temp_barcodes_for_labels) {
20                     g.barcodes = g.barcodes.concat( g.data.temp_barcodes_for_labels );
21                     g.data.temp_barcodes_for_labels = null; g.data.stash('temp_barcodes_for_labels');
22                 }
23
24                 JSAN.use('circ.util');
25                 g.cols = circ.util.columns( {} );
26                 g.col_map = {};
27                 for (var i = 0; i < g.cols.length; i++) {
28                     g.col_map[ g.cols[i].id ] = { 'regex' : new RegExp('%' + g.cols[i].id + '%',"g"), 'render' : g.cols[i].render };
29                 }
30
31                 g.volumes = {};
32
33                 for (var i = 0; i < g.barcodes.length; i++) {
34                     var copy = g.network.simple_request( 'FM_ACP_RETRIEVE_VIA_BARCODE.authoritative', [ g.barcodes[i] ] );
35                     if (typeof copy.ilsevent != 'undefined') throw(copy);
36                     if (!g.volumes[ copy.call_number() ]) {
37                         var volume = g.network.simple_request( 'FM_ACN_RETRIEVE.authoritative', [ copy.call_number() ] );
38                         if (typeof volume.ilsevent != 'undefined') throw(volume);
39                         var record = g.network.simple_request('MODS_SLIM_RECORD_RETRIEVE.authoritative', [ volume.record() ]);
40                         volume.record( record );
41                         g.volumes[ volume.id() ] = volume;
42                     }
43                     if (g.volumes[ copy.call_number() ].copies()) {
44                         var copies = g.volumes[ copy.call_number() ].copies();
45                         copies.push( copy );
46                         g.volumes[ copy.call_number() ].copies( copies );
47                     } else {
48                         g.volumes[ copy.call_number() ].copies( [ copy ] );
49                     }
50                 }
51
52                 generate();
53
54                 if (typeof xulG != 'undefined') $('close').hidden = true;
55
56             } catch(E) {
57                 try {
58                     g.error.standard_unexpected_error_alert('/xul/server/cat/spine_labels.xul',E);
59                 } catch(F) {
60                     alert('FIXME: ' + js2JSON(E));
61                 }
62             }
63         }
64
65         function show_macros() {
66             JSAN.use('util.functional');
67             alert( util.functional.map_list( g.cols, function(o) { return '%' + o.id + '%'; } ).join(" ") );
68         }
69
70         function $(id) { return dojo.byId(id); }
71
72         function generate(override) {
73             try {
74                 var idx = 0;
75                 JSAN.use('util.text');
76                 JSAN.use('util.money');
77                 JSAN.use('util.widgets');
78                 var pn = $('panel');
79                 $('preview').disabled = false;
80
81                 /* Grab from OU settings, then fall back to hardcoded defaults */
82                 var label_cfg = {};
83                 label_cfg.spine_width = Number($('lw').value); /* spine label width */
84                 if (!label_cfg.spine_width) {
85                     label_cfg.spine_width = g.data.hash.aous['cat.spine.line.width'] || 8;
86                     $('lw').value = label_cfg.spine_width;
87                 }
88                 label_cfg.spine_length = Number($('ll').value); /* spine label length */
89                 if (!label_cfg.spine_length) {
90                     label_cfg.spine_length = g.data.hash.aous['cat.spine.line.height'] || 9;
91                     $('ll').value = label_cfg.spine_length;
92                 }
93                 label_cfg.spine_left_margin = Number($('lm').value); /* left margin */
94                 if (!label_cfg.spine_left_margin) {
95                     label_cfg.spine_left_margin = g.data.hash.aous['cat.spine.line.margin'] || 11;
96                     $('lm').value = label_cfg.spine_left_margin;
97                 }
98                 label_cfg.font_size = Number( $('pt').value );  /* font size */
99                 if (!label_cfg.font_size) {
100                     label_cfg.font_size = g.data.hash.aous['cat.label.font.size'] || 10;
101                     $('pt').value = label_cfg.font_size;
102                 }
103                 label_cfg.font_weight = $('font_weight').value;  /* font weight */
104                 if (!label_cfg.font_weight) {
105                     label_cfg.font_weight = g.data.hash.aous['cat.label.font.weight'] || 'normal';
106                     $('font_weight').value = label_cfg.font_weight;
107                 }
108                 label_cfg.font_family = g.data.hash.aous['cat.label.font.family'] || 'monospace';
109                 label_cfg.pocket_width = Number($('plw').value) || 28; /* pocket label width */
110                 label_cfg.pocket_length = Number($('pll').value) || 9; /* pocket label length */
111
112                 if (override) {
113                     var gb = $('acn_' + g.volumes[override.acn].id());
114                     util.widgets.remove_children('acn_' + g.volumes[override.acn].id());
115                     generate_labels(g.volumes[override.acn], gb, label_cfg, override);
116                 } else {
117                     util.widgets.remove_children('panel');
118                     for (var i in g.volumes) {
119                         var vb = document.createElement('vbox'); pn.appendChild(vb);
120                         vb.setAttribute('name','template');
121                         vb.setAttribute('acn_id',g.volumes[i].id());
122                         var ds = document.createElement('description'); vb.appendChild(ds);
123                         ds.appendChild( document.createTextNode( g.volumes[i].label() ) );
124                         var ds2 = document.createElement('description'); vb.appendChild(ds2);
125                         ds2.appendChild( document.createTextNode( g.volumes[i].copies().length + ' ' + (
126                             g.volumes[i].copies().length == 1 ? $("catStrings").getString('staff.cat.spine_labels.copy') : $("catStrings").getString('staff.cat.spine_labels.copies')) ) );
127                         ds2.setAttribute('style','color: green');
128                         var hb = document.createElement('hbox'); vb.appendChild(hb);
129
130                         var gb = document.createElement('groupbox');
131                         hb.appendChild(gb); 
132                         gb.setAttribute('id','acn_' + g.volumes[i].id());
133
134                         generate_labels(g.volumes[i], gb, label_cfg, override);
135
136                         idx++;
137                     }
138                 }
139             } catch(E) {
140                 g.error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.spine_labels.generate.std_unexpeceted_err'),E);
141             }
142         }
143
144         function generate_labels(volume, label_node, label_cfg, override) {
145             var names;
146
147             if (override && volume.id() == override.acn) {
148                 /* If we're calling ourself, we'll have an altered label */
149                 names = String(override.label).split(/\s+/);
150             } else {
151                 /* take the call number and split it on whitespace */
152                 names = String(volume.label()).split(/\s+/);
153             }
154             var j = 0;
155             while (j < label_cfg.spine_length || j < label_cfg.pocket_length) {
156                 var hb2 = document.createElement('hbox'); label_node.appendChild(hb2);
157                 
158                 /* spine */
159                 if (j < label_cfg.spine_length) {
160                     var tb = document.createElement('textbox'); hb2.appendChild(tb); 
161                     tb.value = '';
162                     tb.setAttribute('class','plain');
163                     tb.setAttribute('style',
164                         'font-family: ' + label_cfg.font_family
165                         + '; font-size: ' + label_cfg.font_size
166                         + '; font-weight: ' + label_cfg.font_weight
167                     );
168                     tb.setAttribute('size',label_cfg.spine_width+1);
169                     tb.setAttribute('maxlength',label_cfg.spine_width);
170                     tb.setAttribute('name','spine');
171                     var spine_row_id = 'acn_' + volume.id() + '_spine_' + j;
172                     tb.setAttribute('id',spine_row_id);
173                     var name = names.shift();
174                     if (name) {
175                         name = String( name );
176                         /* if the name is greater than the label width... */
177                         if (name.length > label_cfg.spine_width) {
178                             /* then try to split it on periods */
179                             var sname = name.split(/\./);
180                             if (sname.length > 1) {
181                                 /* if we can, then put the periods back in on each splitted element */
182                                 if (name.match(/^\./)) sname[0] = '.' + sname[0];
183                                 for (var k = 1; k < sname.length; k++) sname[k] = '.' + sname[k];
184                                 /* and put all but the first one back into the names array */
185                                 names = sname.slice(1).concat( names );
186                                 /* if the name fragment is still greater than the label width... */
187                                 if (sname[0].length > label_cfg.spine_width) {
188                                     /* then just truncate and throw the rest back into the names array */
189                                     tb.value = sname[0].substr(0,label_cfg.spine_width);
190                                     names = [ sname[0].substr(label_cfg.spine_width) ].concat( names );
191                                 } else {
192                                     /* otherwise we're set */
193                                     tb.value = sname[0];
194                                 }
195                             } else {
196                                 /* if we can't split on periods, then just truncate and throw the rest back into the names array */
197                                 tb.value = name.substr(0,label_cfg.spine_width);
198                                 names = [ name.substr(label_cfg.spine_width) ].concat( names );
199                             }
200                         } else {
201                             /* otherwise we're set */
202                             tb.value = name;
203                         }
204                     }
205                     dojo.connect($(spine_row_id), 'onkeypress', 'spine_label_key_events');
206                 }
207
208                 /* pocket */
209                 if ($('pl').checked && j < label_cfg.pocket_length) {
210                     var tb2 = document.createElement('textbox'); hb2.appendChild(tb2); 
211                     tb2.value = '';
212                     tb2.setAttribute('class','plain');
213                     tb2.setAttribute('style',
214                         'font-family: ' + label_cfg.font_family
215                         + '; font-size: ' + label_cfg.font_size
216                         + '; font-weight: ' + label_cfg.font_weight
217                     );
218                     tb2.setAttribute('size',label_cfg.pocket_width+1); tb2.setAttribute('maxlength',label_cfg.pocket_width);
219                     tb2.setAttribute('name','pocket');
220                     if ($('title').checked && $('title_line').value == j + 1 && instanceOf(volume.record(),mvr)) {
221                         if (volume.record().title()) {
222                             tb2.value = util.text.wrap_on_space( volume.record().title(), label_cfg.pocket_width )[0];
223                         } else {
224                             tb2.value = '';
225                         }
226                     }
227                     if ($('title_r').checked && $('title_r_line').value == j + 1 && instanceOf(volume.record(),mvr)) {
228                         if (volume.record().title()) {
229                             tb2.value = ( ($('title_r_indent').checked ? ' ' : '') + util.text.wrap_on_space( volume.record().title(), label_cfg.pocket_width )[1]).substr(0,label_cfg.pocket_width);
230                         } else {
231                             tb2.value = '';
232                         }
233                     }
234                     if ($('author').checked && $('author_line').value == j + 1 && instanceOf(volume.record(),mvr)) {
235                         if (volume.record().author()) {
236                             tb2.value = volume.record().author().substr(0,label_cfg.pocket_width);
237                         } else {
238                             tb2.value = '';
239                         }
240                     }
241                     if ($('call_number').checked && $('call_number_line').value == j + 1) {
242                         tb2.value = volume.label().substr(0,label_cfg.pocket_width);
243                     }
244                     if ($('owning_lib_shortname').checked && $('owning_lib_shortname_line').value == j + 1) {
245                         var lib = volume.owning_lib();
246                         if (!instanceOf(lib,aou)) lib = g.data.hash.aou[ lib ];
247                         tb2.value = lib.shortname().substr(0,label_cfg.pocket_width);
248                     }
249                     if ($('owning_lib').checked && $('owning_lib_line').value == j + 1) {
250                         var lib = volume.owning_lib();
251                         if (!instanceOf(lib,aou)) lib = g.data.hash.aou[ lib ];
252                         tb2.value = lib.name().substr(0,label_cfg.pocket_width);
253                     }
254                     if ($('shelving_location').checked && $('shelving_location_line').value == j + 1) {
255                         tb2.value = '%location%';
256                     }
257                     if ($('barcode').checked && $('barcode_line').value == j + 1) {
258                         tb2.value = '%barcode%';
259                     }
260                     if ($('custom1').checked && $('custom1_line').value == j + 1) {
261                         tb2.value = $('custom1_tb').value;
262                     }
263                     if ($('custom2').checked && $('custom2_line').value == j + 1) {
264                         tb2.value = $('custom2_tb').value;
265                     }
266                     if ($('custom3').checked && $('custom3_line').value == j + 1) {
267                         tb2.value = $('custom3_tb').value;
268                     }
269                     if ($('custom4').checked && $('custom4_line').value == j + 1) {
270                         tb2.value = $('custom4_tb').value;
271                     }
272                 }
273
274                 j++;
275             }
276         }
277
278         function spine_label_key_events (event) {
279
280             /* Current value of the inpux box */
281             var line_value = event.target.value;
282
283             /* Cursor positions */
284             var sel_start = event.target.selectionStart;
285             var sel_end = event.target.selectionEnd;
286
287             /* Identifiers for this row: "acn_ID_spine_ROW" */
288             var atts = event.target.id.split('_');
289             var row_id = {
290                 "acn": atts[1],
291                 "spine": atts[3],
292                 "prefix": 'acn_' + atts[1] + '_spine_'
293             };
294
295             switch (event.charOrCode) {
296                 case dojo.keys.ENTER : {
297                     /* Create a new row by inserting a space at the
298                      * current cursor point, then regenerating the
299                      * label
300                      */
301                     if (sel_start == sel_end) {
302                         /* Special case if the cursor is at the start of the line */
303                         if (sel_start == 0) {
304                             line_value = ' ' + line_value;
305                         } else {
306                             line_value = line_value.substr(0, sel_start) + ' ' + line_value.substr(sel_end);
307                         }
308                     } else {
309                         line_value = line_value.substr(0, sel_start) + ' ' + line_value.substr(sel_end);
310                     }
311                     event.target.value = line_value;
312
313                     /* Recreate the label */
314                     var new_label = '';
315                     var chunk;
316                     var x = 0;
317                     while (chunk = $(row_id.prefix + x)) {
318                         if (x > 0) {
319                             new_label += ' ' + chunk.value;
320                         } else {
321                             new_label = chunk.value;
322                         }
323                         x++;
324                     }
325                     generate({"acn": row_id.acn, "label": new_label});
326                     $(row_id.prefix + row_id.spine).focus();
327                     break;
328                 }
329
330                 case dojo.keys.BACKSPACE : {
331                     /* Delete line if at the start of an input box */
332                     if (sel_start == 0) {
333                         var new_label = '';
334                         var chunk;
335                         var x = 0;
336                         while (x <= (row_id.spine - 1) && (chunk = $(row_id.prefix + x))) {
337                             if (x > 0) {
338                                 new_label += ' ' + chunk.value;
339                             } else {
340                                 new_label = chunk.value;
341                             }
342                             x++;
343                         }
344
345                         if (chunk = $(row_id.prefix + x)) {
346                             new_label += chunk.value;
347                             x++;
348                         }
349
350                         while (chunk = $(row_id.prefix + x)) {
351                             new_label += ' ' + chunk.value;
352                             x++;
353                         }
354                         generate({"acn": row_id.acn, "label": new_label});
355                         $(row_id.prefix + row_id.spine).focus();
356                     }
357                     break;
358                 }
359
360                 case dojo.keys.DELETE : {
361                     /* Delete line if at the end of an input box */
362                     if (sel_start == event.target.textLength) {
363                         var new_label = '';
364                         var chunk;
365                         var x = 0;
366                         while (x <= row_id.spine && (chunk = $(row_id.prefix + x))) {
367                             if (x > 0) {
368                                 new_label += ' ' + chunk.value;
369                             } else {
370                                 new_label = chunk.value;
371                             }
372                             x++;
373                         }
374
375                         if (chunk = $(row_id.prefix + x)) {
376                             new_label += chunk.value;
377                             x++;
378                         }
379
380                         while (chunk = $(row_id.prefix + x)) {
381                             new_label += ' ' + chunk.value;
382                             x++;
383                         }
384                         generate({"acn": row_id.acn, "label": new_label});
385                         $(row_id.prefix + row_id.spine).focus();
386                     }
387                     break;
388                 }
389
390                 case dojo.keys.UP_ARROW : {
391                     /* Move to the previous row */
392                     var prev_row = $(row_id.prefix + (parseInt(row_id.spine) - 1));
393                     if (prev_row) {
394                         prev_row.focus();
395                     }
396                     break;
397                 }
398
399                 case dojo.keys.DOWN_ARROW : {
400                     /* Move to the next row */
401                     var next_row = $(row_id.prefix + (parseInt(row_id.spine) + 1));
402                     if (next_row) {
403                         next_row.focus();
404                     }
405                     break;
406                 }
407             }
408         }
409
410         function expand_macros(text,copy,volume,record) {
411             var my = { 'acp' : copy, 'acn' : volume, 'mvr' : record };
412             var obj = { 'data' : g.data };
413             for (var i in g.col_map) {
414                 var re = g.col_map[i].regex;
415                 if (text.match(re)) {
416                     try {
417                         text = text.replace(re, (typeof g.col_map[i].render == 'function' ? g.col_map[i].render(my) : eval( g.col_map[i].render ) ) );
418                     } catch(E) {
419                         g.error.sdump('D_ERROR','spine_labels.js, expand_macros() = ' + E);
420                     }
421                 }
422             }
423             return text;
424         }
425
426         function preview(idx) {
427             try {
428                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
429                     var pt = Number( $('pt').value );  /* font size */
430                     if (!pt) {
431                         pt = g.data.hash.aous['cat.spine.font.size'] || 10;
432                         $('pt').value = pt;
433                     }
434                     var ff = g.data.hash.aous['cat.spine.font.family'] || 'monospace';
435                     var fw = $('font_weight').value;  /* font weight */
436                     if (!fw) {
437                         fw = g.data.hash.aous['cat.label.font.weight'] || 'normal';
438                     }
439                     var lm = Number($('lm').value); /* left margin */
440                     if (!lm) {
441                         lm = g.data.hash.aous['cat.spine.line.margin'] || 11;
442                     }
443                     var mm = Number($('mm').value); if (mm == NaN) mm = 2; /* middle margin */
444                     var lw = Number($('lw').value); /* spine label width */
445                     if (!lw) {
446                         lw = g.data.hash.aous['cat.spine.line.width'] || 8;
447                         $('lw').value = lw;
448                     }
449                     var ll = Number($('ll').value); /* spine label length */
450                     if (!ll) {
451                         ll = g.data.hash.aous['cat.spine.line.height'] || 9;
452                         $('ll').value = ll;
453                     }
454                     var plw = Number($('plw').value) || 28; var pll = Number($('pll').value) || 9; /* pocket label width and length */
455                     var html = "<html><head>";
456                     html += "<link type='text/css' rel='stylesheet' href='" + xulG.url_prefix('/xul/server/skin/print.css') + "'></link>"
457                     html += "<link type='text/css' rel='stylesheet' href='data:text/css,pre{font-family:" + ff + ";font-size:" + pt + "pt; font-weight: " + fw + ";}'></link>";
458                     html += "<title>Spine Labels</title></head><body>\n";
459                     var nl = document.getElementsByAttribute('name','template');
460                     for (var i = 0; i < nl.length; i++) {
461                         if (typeof idx == 'undefined' || idx == null) { } else {
462                             if (idx != i) continue;
463                         }
464                         var volume = g.volumes[ nl[i].getAttribute('acn_id') ];
465
466                         for (var j = 0; j < volume.copies().length; j++) {
467                             var copy = volume.copies()[j];
468                             if (i == 0 && j == 0) {
469                                 html += '<pre class="first_pre">\n';
470                             } else {
471                                 html += '<pre class="not_first_pre">\n';
472                             }
473                             var gb = nl[i].getElementsByTagName('groupbox')[0];
474                             var nl2 = gb.getElementsByAttribute('name','spine');
475                             for (var k = 0; k < nl2.length; k++) {
476                                 for (var m = 0; m < lm; m++) html += ' ';
477                                 html += util.text.preserve_string_in_html(expand_macros( nl2[k].value, copy, volume, volume.record() ).substr(0,lw));
478                                 if ($('pl').checked) {
479                                     var sib = nl2[k].nextSibling;
480                                     if (sib) {
481                                         for (var m = 0; m < lw - nl2[k].value.length; m++) html += ' ';
482                                         for (var m = 0; m < mm; m++) html += ' ';
483                                         html += util.text.preserve_string_in_html(expand_macros( sib.value, copy, volume, volume.record() ).substr(0,plw));
484                                     }
485                                 }
486                                 html += '\n';
487                             }
488                             html += '</pre hex="0C">\n';
489                         }
490                     }
491                     html += '</body></html>';
492                     var loc = ( urls.XUL_BROWSER );
493                     xulG.new_tab(
494                         loc,
495                         {
496                             'tab_name' : $("catStrings").getString('staff.cat.spine_labels.preview.title')
497                         },
498                         { 
499                             'url' : 'data:text/html;charset=utf-8,'+window.escape(html),
500                             'html_source' : html,
501                             'show_print_button' : 1,
502                             'no_xulG' : 1
503                         }
504                     );
505             } catch(E) {
506                 g.error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.spine_labels.preview.std_unexpected_err'),E);
507             }
508         }
509
510