ARB
asciiprint.cxx
Go to the documentation of this file.
1 // ================================================================ //
2 // //
3 // File : asciiprint.cxx //
4 // Purpose : show/print ASCII text //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // ================================================================ //
10 
11 #include "asciiprint.hxx"
12 
13 #include <aw_window.hxx>
14 #include <aw_root.hxx>
15 #include <aw_question.hxx>
16 #include <aw_awar.hxx>
17 #include <aw_msg.hxx>
18 #include <arbdbt.h>
19 
20 #define AWAR_APRINT "tmp/aprint/"
21 #define AWAR_APRINT_TITLE AWAR_APRINT "title"
22 #define AWAR_APRINT_TEXT AWAR_APRINT "text"
23 #define AWAR_APRINT_PAPER_SIZE AWAR_APRINT "paper_size"
24 #define AWAR_APRINT_MAGNIFICATION AWAR_APRINT "magnification"
25 #define AWAR_APRINT_SX AWAR_APRINT "source_columns"
26 #define AWAR_APRINT_SY AWAR_APRINT "source_rows"
27 #define AWAR_APRINT_DX AWAR_APRINT "dest_cols"
28 #define AWAR_APRINT_DY AWAR_APRINT "dest_rows"
29 #define AWAR_APRINT_ORIENTATION AWAR_APRINT "orientation"
30 #define AWAR_APRINT_PAGES AWAR_APRINT "pages"
31 #define AWAR_APRINT_PRINTTO AWAR_APRINT "printto"
32 #define AWAR_APRINT_PRINTER AWAR_APRINT "printer"
33 #define AWAR_APRINT_FILE AWAR_APRINT "file"
34 
35 
40 };
41 
42 
46 };
47 
53 };
54 
55 static double awt_aps_get_xy_ratio(AW_root *awr) {
56  // AWT_asciiprint_paper_size psize = (AWT_asciiprint_paper_size)awr->awar(AWAR_APRINT_PAPER_SIZE)->read_int();
58  double res = 1.0;
59  switch (ori) {
61  res = 112.0/90.0;
62  break;
64  res = 112.0/50.0;
65  break;
67  res = 103.0/90.0;
68  break;
69  }
70  return res;
71 }
72 
75  switch (ori) {
77  return 80;
79  return 60;
81  return 80;
82  }
83  return -1;
84 }
85 
86 
88  int mag = awr->awar(AWAR_APRINT_MAGNIFICATION)->read_int();
89  if (mag < 25) {
91  return;
92  }
93  if (mag > 250) {
95  return;
96  }
97 
98  int x = awr->awar(AWAR_APRINT_SX)->read_int() * mag / 100;
99  int y = awr->awar(AWAR_APRINT_SY)->read_int() * mag / 100;
100  int default_lpp = awt_aps_get_default_lines_per_page(awr);
101  double xy_ratio = awt_aps_get_xy_ratio(awr);
102  int default_cpp = int(default_lpp * xy_ratio);
103 
104  awr->awar(AWAR_APRINT_DX)->write_float(float(x)/default_cpp);
105  awr->awar(AWAR_APRINT_DY)->write_float(float(y)/default_lpp);
106  x += default_cpp-1;
107  y += default_lpp-1;
108  x /= default_cpp;
109  y /= default_lpp;
110 
111  awr->awar(AWAR_APRINT_PAGES)->write_int(x* y);
112 }
113 
114 
116  int x = awr->awar(AWAR_APRINT_SX)->read_int();
117 
118  int dx = int(awr->awar(AWAR_APRINT_DX)->read_float()+.5);
119  if (dx < 1) dx = 1;
120  if (dx > 99) dx = 99;
121 
122  int default_lpp = awt_aps_get_default_lines_per_page(awr);
123  double xy_ratio = awt_aps_get_xy_ratio(awr);
124  int default_cpp = int(default_lpp * xy_ratio);
125  int mag = 100 * default_cpp * dx / x;
128 }
129 
131  int y = awr->awar(AWAR_APRINT_SY)->read_int();
132 
133  int dy = int(awr->awar(AWAR_APRINT_DY)->read_float()+.5);
134  if (dy < 1) dy = 1;
135  if (dy > 99) dy = 99;
136 
137  int default_lpp = awt_aps_get_default_lines_per_page(awr);
138  int mag = 100 * default_lpp * dy / y;
141 }
142 
145 }
148 }
149 static void awt_aps_text_changed(AW_root *awr) {
150  char *text = awr->awar(AWAR_APRINT_TEXT)->read_string();
151  {
152  char *rtext = GBS_replace_tabs_by_spaces(text);
153  delete text;
154  text = rtext;
155  }
156  int maxx, y;
157  maxx = 1; y = 0;
158  char *s;
159  char *ns;
160  for (s = text; s; s=ns) {
161  ns = strchr(s, '\n');
162  if (ns) {
163  ns[0] = 0;
164  ns++;
165  }
166  int slen = strlen(s);
167  if (slen > maxx) {
168  maxx = slen;
169  }
170  y++;
171  }
172  if (!y) y++;
173  awr->awar(AWAR_APRINT_SX)->write_int(maxx);
174  awr->awar(AWAR_APRINT_SY)->write_int(y);
175  delete text;
177 }
178 
179 static void write_file(const char *filename, const char *file) {
180  fprintf(stderr, "Printing to ASCII file '%s'\n", filename);
181  FILE *f = fopen(filename, "r");
182  if (f) {
183  fclose(f);
184  if (aw_question("overwrite_file", GBS_global_string("File '%s' already exist", filename), "Overwrite,Cancel")) {
185  return;
186  }
187  }
188  f = fopen(filename, "w");
189  if (!f) {
190  aw_message(GBS_global_string("Cannot write to '%s'", filename));
191  return;
192  }
193  fprintf(f, "%s", file);
194  fclose(f);
195 }
196 
197 static char *printFile(AW_root *awr) {
198  const char *home = GB_getenv("HOME");
199  const char *name = awr->awar(AWAR_APRINT_FILE)->read_char_pntr();
200  return GBS_global_string_copy("%s/%s", home, name);
201 }
202 
203 static void awt_aps_go(AW_window *aww) {
204  AW_root *awr = aww->get_root();
205  char *text = awr->awar(AWAR_APRINT_TEXT)->read_string();
206 
207  freeset(text, GBS_replace_tabs_by_spaces(text));
208 
210  if (dest == AWT_APRINT_DEST_FILE_ASCII) {
211  char *file = printFile(awr);
212  write_file(file, text);
213  free(file);
214  }
215  else {
216  char *tmp_file;
217  FILE *tmpf;
218  {
219  char *name = GB_unique_filename("arb_aprint", "txt");
220  tmpf = GB_fopen_tempfile(name, "wt", &tmp_file);
221  free(name);
222  }
223 
224  GB_ERROR error = NULp;
225  if (!tmpf) {
226  error = GBS_global_string("awt_aps_go: %s", GB_await_error());
227  }
228  else {
229  char *y_begin = text;
230  int last_y = 0;
231 
232  double xy_ratio = awt_aps_get_xy_ratio(awr);
233  int mag = awr->awar(AWAR_APRINT_MAGNIFICATION)->read_int();
234 
235  int default_lpp = awt_aps_get_default_lines_per_page(awr);
236  int default_cpp = int(default_lpp * xy_ratio);
237  default_cpp = default_cpp * 100 / mag;
238  default_lpp = default_lpp * 100 / mag;
239 
240  int text_width = awr->awar(AWAR_APRINT_SX)->read_int();
241  int text_height = awr->awar(AWAR_APRINT_SY)->read_int();
242 
243  int x;
244  int y;
245 
246  for (y = 0; y < text_height; y += default_lpp) {
247  while (last_y < y) {
248  last_y ++;
249  y_begin = strchr(y_begin, '\n');
250  if (!y_begin) break;
251  y_begin++;
252  }
253  if (!y_begin) break;
254 
255  for (x = 0; x < text_width; x += default_cpp) {
256  char *line = y_begin;
257  int i;
258  for (i=0; i<default_lpp; i++) {
259  if (line) {
260  char *next_line = strchr(line, '\n');
261  int line_length;
262  if (next_line) {
263  line_length = next_line - line; // exclusive '\n'
264  next_line ++;
265  }
266  else {
267  line_length = strlen(line);
268  }
269  if (line_length > x + default_cpp) {
270  line_length = x + default_cpp;
271  }
272  if (line_length > x) {
273  fwrite(line + x, sizeof(char), line_length - x, tmpf);
274  }
275  line = next_line;
276  }
277  fprintf(tmpf, "\n");
278  }
279  }
280  }
281  fclose(tmpf);
282 
283  char *a2ps_call = NULp;
284  {
286  const char *oristring = "";
287  switch (ori) {
289  oristring = "-p -1 ";
290  break;
292  oristring = "-l -1 ";
293  break;
295  oristring = "-p -2 ";
296  break;
297  }
298  const char *header = awr->awar(AWAR_APRINT_TITLE)->read_char_pntr();
299  char *quotedHeaderArg = GBK_singlequote(GBS_global_string("-H%s", header));
300  a2ps_call = GBS_global_string_copy("arb_a2ps -ns -nP %s %s -l%i %s",
301  quotedHeaderArg, oristring, default_lpp, tmp_file);
302  free(quotedHeaderArg);
303  }
304 
305  const char *scall = NULp;
306  switch (dest) {
308  char *printer = awr->awar(AWAR_APRINT_PRINTER)->read_string();
309  scall = GBS_global_string("%s |%s; rm -f %s", a2ps_call, printer, tmp_file);
310  free(printer);
311  break;
312  }
314  char *file = printFile(awr);
315  char *quotedFile = GBK_singlequote(file);
316  fprintf(stderr, "Printing to PS file %s\n", quotedFile);
317  scall = GBS_global_string("%s >%s;rm -f %s", a2ps_call, quotedFile, tmp_file);
318  free(quotedFile);
319  free(file);
320  break;
321  }
323  char *tmp_file2;
324  {
325  char *name_only;
326  GB_split_full_path(tmp_file, NULp, NULp, &name_only, NULp);
327  tmp_file2 = GB_create_tempfile(GBS_global_string("%s.ps", name_only));
328  free(name_only);
329  }
330 
331  if (!tmp_file2) error = GB_await_error();
332  else {
333  scall = GBS_global_string("%s >%s;(%s %s;rm -f %s %s)&",
334  a2ps_call, tmp_file2,
335  GB_getenvARB_GS(), tmp_file2,
336  tmp_file, tmp_file2);
337  free(tmp_file2);
338  }
339  break;
340  }
341  default:
342  arb_assert(0);
343  break;
344  }
345 
346  if (scall) error = GBK_system(scall);
347  free(a2ps_call);
348  }
349  if (error) aw_message(error);
350  free(tmp_file);
351  }
352  free(text);
353 }
354 
355 static void cutExt(char *name, const char *removeExt) {
356  char *found = strstr(name, removeExt);
357  if (found && strcmp(found, removeExt) == 0) {
358  found[0] = 0;
359  }
360 }
361 static char *correct_extension(const char *name, const char *newExt) {
362  char *noExt = ARB_strdup(name);
363  cutExt(noExt, ".ps");
364  cutExt(noExt, ".txt");
365 
366  char *result = ARB_alloc<char>(strlen(noExt)+strlen(newExt)+1);
367  strcpy(result, noExt);
368  strcat(result, newExt);
369  if (strcmp(name, result) == 0) freenull(result);
370 
371  free(noExt);
372  return result;
373 }
374 
375 static void aps_correct_filename(AW_root *aw_root) {
376  int type = aw_root->awar(AWAR_APRINT_PRINTTO)->read_int();
377  if (type == AWT_APRINT_DEST_FILE_PS || type == AWT_APRINT_DEST_FILE_ASCII) {
378  AW_awar *awar_name = aw_root->awar(AWAR_APRINT_FILE);
379  const char *name = awar_name->read_char_pntr();
380  char *new_name = NULp;
381 
382  if (type == AWT_APRINT_DEST_FILE_PS) {
383  new_name = correct_extension(name, ".ps");
384  }
385  else {
387  new_name = correct_extension(name, ".txt");
388  }
389  if (new_name) {
390  awar_name->write_string(new_name);
391  free(new_name);
392  }
393  }
394 }
395 
396 void AWT_create_ascii_print_window(AW_root *awr, const char *text_to_print, const char *title) {
397  static AW_window_simple *aws = NULp;
398 
399  awr->awar_string(AWAR_APRINT_TEXT)->write_string(text_to_print);
400  if (title) {
402  }
403  if (aws) {
405  }
406  else {
407  aws = new AW_window_simple;
408  aws->init(awr, "PRINT", "PRINT");
409  aws->load_xfig("awt/ascii_print.fig");
412 
415  awr->awar_int(AWAR_APRINT_PAGES, 1);
416  awr->awar_int(AWAR_APRINT_SX, 1);
417  awr->awar_int(AWAR_APRINT_SY, 1);
418 
419  awr->awar_float(AWAR_APRINT_DX, 1.0);
420  awr->awar_float(AWAR_APRINT_DY, 1.0);
421 
423 
427 
428  {
429  char *print_command;
430  if (getenv("PRINTER")) {
431  print_command = GBS_eval_env("lpr -h -P$(PRINTER)");
432  }
433  else {
434  print_command = ARB_strdup("lpr -h");
435  }
436 
437  awr->awar_string(AWAR_APRINT_PRINTER, print_command);
438  free(print_command);
439  }
440 
442 
443  aws->at("close");
444  aws->callback(AW_POPDOWN);
445  aws->create_button("CLOSE", "CLOSE");
446 
447  aws->at("help");
448  aws->callback(makeHelpCallback("asciiprint.hlp"));
449  aws->create_button("HELP", "HELP");
450 
451  aws->at("go");
452  aws->callback(awt_aps_go);
453  aws->create_button("PRINT", "PRINT");
454 
455  aws->at("title");
456  aws->create_input_field(AWAR_APRINT_TITLE);
457 
458  aws->at("text");
459  aws->create_text_field(AWAR_APRINT_TEXT);
460 
461  aws->button_length(5);
462  aws->at("rows");
463  aws->create_button(NULp, AWAR_APRINT_SY);
464 
465  aws->at("columns");
466  aws->create_button(NULp, AWAR_APRINT_SX);
467 
468  aws->at("magnification");
469  aws->create_input_field(AWAR_APRINT_MAGNIFICATION, 4);
470 
471  aws->at("paper_size");
472  {
473  aws->create_toggle_field(AWAR_APRINT_PAPER_SIZE, AW_HORIZONTAL);
474  aws->insert_toggle("A4", "A", int(AWT_APRINT_PAPERSIZE_A4));
475  aws->insert_toggle("US", "U", int(AWT_APRINT_PAPERSIZE_US));
476  aws->update_toggle_field();
477  }
478 
479  aws->at("orientation");
480  {
481  aws->create_toggle_field(AWAR_APRINT_ORIENTATION, AW_HORIZONTAL);
482  aws->insert_toggle("#print/portrait.xpm", "P", int(AWT_APRINT_ORIENTATION_PORTRAIT));
483  aws->insert_toggle("#print/landscape.xpm", "P", int(AWT_APRINT_ORIENTATION_LANDSCAPE));
484  aws->update_toggle_field();
485  }
486 
487 
488  aws->at("pages");
489  aws->create_button(NULp, AWAR_APRINT_PAGES);
490 
491  aws->at("dcol");
492  aws->callback(awt_aps_set_magnification_to_fit_xpage); // @@@ used as INPUTFIELD_CB (see #559)
493  aws->create_input_field(AWAR_APRINT_DX, 4);
494 
495  aws->at("drows");
496  aws->callback(awt_aps_set_magnification_to_fit_ypage); // @@@ used as INPUTFIELD_CB (see #559)
497  aws->create_input_field(AWAR_APRINT_DY, 4);
498 
499 
500  aws->at("printto");
501  aws->create_toggle_field(AWAR_APRINT_PRINTTO);
502  aws->insert_toggle("Printer", "P", int(AWT_APRINT_DEST_PRINTER));
503  aws->insert_toggle("File (Postscript)", "F", int(AWT_APRINT_DEST_FILE_PS));
504  aws->insert_toggle("File (ASCII)", "A", int(AWT_APRINT_DEST_FILE_ASCII));
505  aws->insert_toggle("Preview", "V", int(AWT_APRINT_DEST_PREVIEW));
506  aws->update_toggle_field();
507 
508  aws->at("printer");
509  aws->create_input_field(AWAR_APRINT_PRINTER, 16);
510 
511  aws->at("filename");
512  aws->create_input_field(AWAR_APRINT_FILE, 16);
513  }
514  aws->activate();
515 }
516 
517 
518 void AWT_show_file(AW_root *awr, const char *filename) {
519  char *text = GB_read_file(filename);
520  if (!text) {
522  }
523  else {
524  AWT_create_ascii_print_window(awr, text, filename);
525  free(text);
526  }
527 }
GB_ERROR GBK_system(const char *system_command)
Definition: arb_msg.cxx:571
#define arb_assert(cond)
Definition: arb_assert.h:245
const char * GB_ERROR
Definition: arb_core.h:25
string result
GB_TYPES type
#define AWAR_APRINT_TEXT
Definition: asciiprint.cxx:22
#define AWAR_APRINT_PRINTER
Definition: asciiprint.cxx:32
static int awt_aps_get_default_lines_per_page(AW_root *awr)
Definition: asciiprint.cxx:73
static char * y[maxsp+1]
static void aps_correct_filename(AW_root *aw_root)
Definition: asciiprint.cxx:375
#define AWAR_APRINT_PAGES
Definition: asciiprint.cxx:30
void AWT_show_file(AW_root *awr, const char *filename)
Definition: asciiprint.cxx:518
#define AWAR_APRINT_SY
Definition: asciiprint.cxx:26
static void awt_aps_calc_pages_needed(AW_root *awr)
Definition: asciiprint.cxx:87
static double awt_aps_get_xy_ratio(AW_root *awr)
Definition: asciiprint.cxx:55
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
long read_int() const
Definition: AW_awar.cxx:184
#define AWAR_APRINT_PAPER_SIZE
Definition: asciiprint.cxx:23
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
const char * title
Definition: readseq.c:22
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
char * GBS_replace_tabs_by_spaces(const char *text)
Definition: adstring.cxx:923
#define AWAR_APRINT_DX
Definition: asciiprint.cxx:27
GB_CSTR GB_getenvARB_GS(void)
Definition: adsocket.cxx:641
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
#define AWAR_APRINT_TITLE
Definition: asciiprint.cxx:21
void AWT_create_ascii_print_window(AW_root *awr, const char *text_to_print, const char *title)
Definition: asciiprint.cxx:396
static char * correct_extension(const char *name, const char *newExt)
Definition: asciiprint.cxx:361
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
char * GB_create_tempfile(const char *name)
Definition: adsocket.cxx:1213
#define AWAR_APRINT_FILE
Definition: asciiprint.cxx:33
static void cutExt(char *name, const char *removeExt)
Definition: asciiprint.cxx:355
AWT_asciiprint_paper_size
Definition: asciiprint.cxx:43
AW_awar * awar_float(const char *var_name, float default_value=0.0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:560
static void error(const char *msg)
Definition: mkptypes.cxx:96
FILE * GB_fopen_tempfile(const char *filename, const char *fmode, char **res_fullname)
Definition: adsocket.cxx:1167
static void awt_aps_go(AW_window *aww)
Definition: asciiprint.cxx:203
static char * printFile(AW_root *awr)
Definition: asciiprint.cxx:197
#define AWAR_APRINT_DY
Definition: asciiprint.cxx:28
AWT_asciiprint_destination
Definition: asciiprint.cxx:48
char * read_string() const
Definition: AW_awar.cxx:198
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
#define AWAR_APRINT_ORIENTATION
Definition: asciiprint.cxx:29
float read_float() const
Definition: AW_awar.cxx:177
GB_CSTR GB_getenv(const char *env)
Definition: adsocket.cxx:710
char * GB_unique_filename(const char *name_prefix, const char *suffix)
Definition: adsocket.cxx:1224
int aw_question(const char *unique_id, const char *question, const char *buttons, bool sameSizeButtons, const char *helpfile)
Definition: AW_question.cxx:26
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
char * GBK_singlequote(const char *arg)
Definition: arb_msg.cxx:599
#define AWAR_APRINT_MAGNIFICATION
Definition: asciiprint.cxx:24
const char * name_only(const char *fullpath)
Definition: AWTI_import.cxx:46
static void write_file(const char *filename, const char *file)
Definition: asciiprint.cxx:179
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
AW_root * get_root()
Definition: aw_window.hxx:359
static void awt_aps_set_magnification_to_fit_ypage(AW_root *awr)
Definition: asciiprint.cxx:130
char * GBS_eval_env(GB_CSTR p)
Definition: adstring.cxx:212
void GB_split_full_path(const char *fullpath, char **res_dir, char **res_fullname, char **res_name_only, char **res_suffix)
Definition: adsocket.cxx:1259
static int line
Definition: arb_a2ps.c:296
#define NULp
Definition: cxxforward.h:116
GB_ERROR write_string(const char *aw_string)
static void awt_aps_text_changed(AW_root *awr)
Definition: asciiprint.cxx:149
#define AWAR_APRINT_PRINTTO
Definition: asciiprint.cxx:31
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
GB_ERROR write_float(float aw_float)
AWT_asciiprint_orientation
Definition: asciiprint.cxx:36
GB_ERROR write_int(long aw_int)
#define AWAR_APRINT_SX
Definition: asciiprint.cxx:25
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
char * GB_read_file(const char *path)
Definition: adsocket.cxx:288
static void awt_aps_set_magnification_to_fit_xpage(AW_root *awr)
Definition: asciiprint.cxx:115
GB_write_int const char s
Definition: AW_awar.cxx:154