1
2 // ------------------------------------------------------------------
3 // GoldED+
4 // Copyright (C) 1990-1999 Odinn Sorensen
5 // Copyright (C) 1999-2000 Alexander S. Aganichev
6 // ------------------------------------------------------------------
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 // MA 02111-1307 USA
21 // ------------------------------------------------------------------
22 // $Id: gedoit.cpp,v 1.30 2011/02/17 23:22:23 stas_degteff Exp $
23 // ------------------------------------------------------------------
24 // Various major job handling funcs
25 // ------------------------------------------------------------------
26
27 #include <golded.h>
28 #include <gutlclip.h>
29
30 // ------------------------------------------------------------------
31
32 static gfile prnfp;
33 static int prnheader;
34
35
36 // ------------------------------------------------------------------
37
SaveLines(int mode,const char * savefile,GMsg * msg,int margin,bool clip)38 void SaveLines(int mode, const char* savefile, GMsg* msg, int margin, bool clip) {
39
40 int prn=NO;
41 char fnam[GMAXPATH];
42 char* prnacc;
43
44 if(mode == MODE_APPEND) {
45 prnacc = "at";
46 mode = MODE_WRITE;
47 }
48 else
49 prnacc = "wt";
50
51 strcpy(fnam, "PRN");
52 if(mode == MODE_WRITE and streql(savefile, "\001PRN"))
53 prn = YES;
54 else
55 {
56 strcpy(fnam, savefile);
57 strschg_environ(fnam, sizeof(fnam));
58 prnfp.Fopen(fnam, prnacc, CFG->sharemode);
59 }
60 int lines=0;
61 if (prnfp.isopen())
62 {
63 char *old_msg_txt = throw_strdup(msg->txt);
64 #ifdef OLD_STYLE_HEADER
65 if(mode == MODE_WRITE) {
66 if(prnheader) {
67 DispHeader(msg, prn, prnfp, margin);
68 if(prn)
69 lines = 6;
70 }
71 }
72 #else
73 if(mode == MODE_WRITE) {
74 if(AA->LoadMsg(msg, msg->msgno, margin) == false) {
75 msg->txt = throw_strdup("");
76 msg->TextToLines(margin);
77 }
78 }
79 else if((mode == MODE_SAVE) or (mode == MODE_SAVENOCTRL)) {
80 msg->TextToLines(margin);
81 }
82 TemplateToText(((mode == MODE_WRITE) and prnheader) ? ((prnheader & WRITE_ONLY_HEADER) ? MODE_HEADER : MODE_WRITEHEADER) : MODE_WRITE, msg, msg, AA->WTpl(), CurrArea);
83 msg->TextToLines(margin, false);
84 #endif
85 int n = 0;
86 Line** lin = msg->line;
87 if(lin) {
88 Line* line = lin[n];
89 while(line) {
90 uint lineisctrl = line->type & (GLINE_TEAR|GLINE_ORIG|GLINE_KLUDGE);
91 if(not ((mode == MODE_SAVENOCTRL) and lineisctrl)) {
92 if(mode == MODE_WRITE) {
93 for(std::string::iterator p = line->txt.begin(); p != line->txt.end(); p++) {
94 // Replace control codes, except the ANSI escape code
95 if(iscntrl(*p)) {
96 // only allow ESC in file write
97 if(prn or (*p != '\x1B')) {
98 *p = (*p == CTRL_A) ? '@' : '.';
99 }
100 }
101 }
102 }
103 const char *ptr = line->txt.c_str();
104 prnfp.Fwrite(ptr, strlen(ptr));
105 if (mode == MODE_NEW)
106 {
107 if(EDIT->HardLines()) {
108 if(line->type & GLINE_HARD) {
109 if (not ((line->type & (GLINE_TEAR|GLINE_ORIG|GLINE_KLUDGE|GLINE_QUOT)) or strblank(ptr)))
110 {
111 prnfp.Fwrite(EDIT->HardLine(), strlen(EDIT->HardLine()));
112 }
113 }
114 }
115 }
116 prnfp.Fwrite(prn ? NL : "\n", prn ? sizeof(NL) : 1);
117 if (prn)
118 {
119 lines++;
120 if (lines%CFG->printlength == 0 and CFG->switches.get(printformfeed))
121 prnfp.Fwrite("\f", 1);
122 }
123 }
124 line = lin[++n];
125 }
126 }
127 // Add an empty line and formfeed at the bottom
128 if (mode == MODE_WRITE)
129 prnfp.Fwrite(prn ? NL : "\n", prn ? sizeof(NL) : 1);
130
131 // Add formfeed if requested
132 if ((prn and CFG->switches.get(printformfeed)) or
133 (not prn and not clip and CFG->switches.get(formfeedseparator)))
134 {
135 prnfp.Fwrite("\f", 1);
136 }
137
138 prnfp.Fclose();
139
140 throw_release(msg->txt);
141 msg->txt = old_msg_txt;
142 }
143 else
144 {
145 char buf[256];
146 gsprintf(PRINTF_DECLARE_BUFFER(buf), LNG->CouldNotOpen, fnam);
147 w_info(buf);
148 waitkeyt(10000);
149 w_info(NULL);
150 }
151 }
152
153
154 // ------------------------------------------------------------------
155
WriteMsgs(GMsg * msg)156 static void WriteMsgs(GMsg* msg) {
157
158 int prnmargin;
159
160 if(AA->Msgn.Tags() == 0)
161 return;
162
163 GFTRK("WriteMsgs");
164
165 char buf[256];
166 char fname[GMAXPATH], ofname[GMAXPATH];
167
168 int overwrite = NO;
169
170 GMenuDomarks MenuDomarks;
171 int source = AA->Mark.Count() ? MenuDomarks.Run(LNG->Write) : WRITE_CURRENT;
172
173 if(source != WRITE_QUIT) {
174
175 GMenuWriteMsg MenuWriteMsg;
176 int target = MenuWriteMsg.Run();
177
178 if(target != WRITE_QUIT) {
179
180 prnheader = (target & (WRITE_NO_HEADER|WRITE_ONLY_HEADER)) ^ WRITE_NO_HEADER;
181
182 if(target & WRITE_PRINTER)
183 prnmargin = CFG->printmargin;
184 else
185 prnmargin = 79;
186
187 if(source == WRITE_MARKED) {
188 if(target & WRITE_FILE) {
189 do {
190 overwrite = NO;
191 strcpy(CFG->outputfile, AA->Outputfile());
192 if(not edit_pathname(CFG->outputfile, sizeof(Path), LNG->WriteMsgs, H_WriteMessage))
193 goto Finish;
194 if(is_dir(CFG->outputfile)) {
195 AddBackslash(CFG->outputfile);
196 strcat(CFG->outputfile, "golded.txt");
197 }
198 AA->SetOutputfile(CFG->outputfile);
199 w_infof(" %s ", AA->Outputfile());
200 if(stricmp(AA->Outputfile(), "PRN") and strnicmp(AA->Outputfile(), "LPT", 3))
201 if(fexist(AA->Outputfile())) {
202 GMenuOverwrite MenuOverwrite;
203 overwrite = MenuOverwrite.Run();
204 }
205 } while(overwrite == -1);
206 }
207 else if(target & WRITE_PRINTER) {
208 #ifdef __UNIX__
209 prnfp.Popen(CFG->printdevice, "w");
210 #else
211 prnfp.Fopen(CFG->printdevice, "wt", CFG->sharemode);
212 #endif
213 if (prnfp.isopen())
214 prnfp.Fwrite(CFG->printinit+1, CFG->printinit[0]);
215 }
216 else if(target & WRITE_CLIPBRD) {
217 overwrite = YES;
218 strcpy(ofname, AA->Outputfile());
219 mktemp(strcpy(fname, AddPath(CFG->temppath, "GDXXXXXX")));
220 AA->SetOutputfile(fname);
221 }
222 w_info(NULL);
223 w_progress(MODE_NEW, C_INFOW, 0, AA->Mark.Count(), LNG->Writing);
224 for(uint n=0; n<AA->Mark.Count(); n++) {
225 if(overwrite and n)
226 overwrite = NO; // Overwrite only the first time
227 if(kbxhit()) {
228 if(kbxget() == Key_Esc) {
229 HandleGEvent(EVTT_JOBFAILED);
230 break;
231 }
232 }
233 update_statuslinef(LNG->WritingMsg, "ST_WRITINGMSG", n+1, AA->Mark.Count());
234 w_progress(MODE_UPDATE, C_INFOW, n+1, AA->Mark.Count(), LNG->Writing);
235 AA->LoadMsg(msg, AA->Mark[n], prnmargin);
236 if (target & WRITE_PRINTER)
237 {
238 if (prnfp.isopen())
239 SaveLines(MODE_WRITE, "\001PRN", msg, prnmargin);
240 }
241 else {
242 SaveLines(overwrite ? MODE_WRITE : MODE_APPEND, AA->Outputfile(), msg, prnmargin, make_bool(target & WRITE_CLIPBRD));
243 }
244 }
245 if (prnfp.isopen())
246 prnfp.Fwrite(CFG->printreset+1, CFG->printreset[0]);
247 if (target & WRITE_CLIPBRD)
248 {
249 AA->SetOutputfile(ofname);
250
251 gclipbrd clipbrd;
252 gfile fp(fname, "rb");
253
254 if (fp.isopen())
255 {
256 long len = fp.FileLength();
257 char* buf = (char*) throw_malloc(len+1);
258 buf[len] = NUL;
259 fp.Fread(buf, len);
260
261 clipbrd.writeclipbrd(buf);
262
263 throw_free(buf);
264
265 fp.Fclose();
266 }
267
268 remove(fname);
269 }
270 w_progress(MODE_QUIT, BLACK_|_BLACK, 0, 0, NULL);
271 }
272 else if(source == WRITE_CURRENT) {
273 if(target & WRITE_FILE) {
274 do {
275 overwrite = NO;
276 strcpy(CFG->outputfile, AA->Outputfile());
277 if(edit_pathname(CFG->outputfile, sizeof(Path), LNG->WriteMsgs, H_WriteMessage)) {
278 if(is_dir(CFG->outputfile)) {
279 AddBackslash(CFG->outputfile);
280 strcat(CFG->outputfile, "golded.txt");
281 }
282 AA->SetOutputfile(CFG->outputfile);
283 w_infof(" %s ", AA->Outputfile());
284 if(stricmp(AA->Outputfile(), "PRN") and strnicmp(AA->Outputfile(), "LPT", 3)) {
285 if(fexist(AA->Outputfile())) {
286 GMenuOverwrite MenuOverwrite;
287 overwrite = MenuOverwrite.Run();
288 if(overwrite == -1) // Escape was hit
289 continue;
290 }
291 }
292 gsprintf(PRINTF_DECLARE_BUFFER(buf), LNG->WritingFile, AA->Outputfile());
293 w_info(buf);
294 AA->LoadMsg(msg, msg->msgno, prnmargin);
295 SaveLines(overwrite ? MODE_WRITE : MODE_APPEND, AA->Outputfile(), msg, prnmargin);
296 w_info(NULL);
297 }
298 } while(overwrite == -1);
299 }
300 else if(target & WRITE_PRINTER) {
301 w_info(LNG->WritingPRN);
302 AA->LoadMsg(msg, msg->msgno, prnmargin);
303 #ifdef __UNIX__
304 prnfp.Popen(CFG->printdevice, "w");
305 #else
306 prnfp.Fopen(CFG->printdevice, "wt", CFG->sharemode);
307 #endif
308 if (prnfp.isopen())
309 {
310 prnfp.Fwrite(CFG->printinit+1, CFG->printinit[0]);
311 SaveLines(MODE_WRITE, "\001PRN", msg, prnmargin);
312 prnfp.Fwrite(CFG->printreset+1, CFG->printreset[0]);
313 }
314 w_info(NULL);
315 }
316 else if(target & WRITE_CLIPBRD) {
317 w_info(LNG->Wait);
318
319 mktemp(strcpy(fname, AddPath(CFG->temppath, "GDXXXXXX")));
320
321 AA->LoadMsg(msg, msg->msgno, prnmargin);
322 SaveLines(MODE_WRITE, fname, msg, prnmargin, true);
323
324 gclipbrd clipbrd;
325 gfile fp(fname, "rb");
326
327 if (fp.isopen())
328 {
329 long len = fp.FileLength();
330 char* buf = (char*) throw_malloc(len+1);
331 buf[len] = NUL;
332 fp.Fread(buf, len);
333
334 clipbrd.writeclipbrd(buf);
335
336 throw_free(buf);
337
338 fp.Fclose();
339 }
340
341 remove(fname);
342 w_info(NULL);
343 }
344 }
345 }
346 }
347
348 Finish:
349
350 w_info(NULL);
351
352 #ifdef __UNIX__
353 prnfp.Pclose();
354 #else
355 prnfp.Fclose();
356 #endif
357
358 GFTRK(0);
359 }
360
361
362 // ------------------------------------------------------------------
363
WriteMsg(GMsg * msg)364 void WriteMsg(GMsg* msg) {
365
366 if(AA->Msgn.Count())
367 WriteMsgs(msg);
368 }
369
370
371 // ------------------------------------------------------------------
372 // Get name of current quotebuffer filename
373
GetCurrQuotebuf(char * quotebuf)374 char* GetCurrQuotebuf(char* quotebuf) {
375
376 if(*AA->Quotebuffile()) {
377 strcpy(quotebuf, AA->Quotebuffile());
378 MakePathname(quotebuf, CFG->goldpath, quotebuf);
379 }
380 else
381 {
382 if (AA->basetype() == "EZYCOM")
383 sprintf(quotebuf, "%sgld%05u.qbf", CFG->ezycom.msgbasepath, AA->board());
384 else if ((AA->basetype() == "FTS1") || (AA->basetype() == "OPUS"))
385 sprintf(quotebuf, "%s%s", AA->path(), "golded.qbf");
386 else if (AA->basetype() == "GOLDBASE")
387 sprintf(quotebuf, "%sgoldg%03u.qbf", CFG->goldbasepath, AA->board());
388 else if (AA->basetype() == "HUDSON")
389 sprintf(quotebuf, "%sgoldh%03u.qbf", CFG->hudsonpath, AA->board());
390 else
391 sprintf(quotebuf, "%s%s", AA->path(), ".qbf");
392 }
393
394 return quotebuf;
395 }
396
397
398 // ------------------------------------------------------------------
399
QuoteBuf(GMsg * msg)400 void QuoteBuf(GMsg* msg) {
401
402 if(AA->Msgn.Count()) {
403
404 Path quotebuf;
405 char openmode[4];
406
407 TemplateToText(MODE_QUOTEBUF, msg, msg, AA->Tpl(), CurrArea);
408 msg->TextToLines(-CFG->quotemargin, false);
409 msg->charsetlevel = LoadCharset(CFG->xlatlocalset, CFG->xlatlocalset);
410 msg->LinesToText();
411
412 GetCurrQuotebuf(quotebuf);
413 w_infof(" %s ", quotebuf);
414
415 switch(CFG->quotebufmode) {
416
417 case QBUF_ASK:
418 *openmode = NUL;
419 if(fexist(quotebuf)) {
420 GMenuOverwrite MenuOverwrite;
421 switch(MenuOverwrite.Run()) {
422 case true:
423 strcpy(openmode, "wt");
424 break;
425 case false:
426 strcpy(openmode, "at");
427 break;
428 default:
429 *openmode = NUL;
430 }
431 }
432 else {
433 strcpy(openmode, "wt");
434 }
435 break;
436
437 case QBUF_APPEND:
438 strcpy(openmode, "at");
439 break;
440
441 case QBUF_OVERWRITE:
442 strcpy(openmode, "wt");
443 break;
444 }
445
446 if (*openmode)
447 {
448 gfile fp(quotebuf, openmode, CFG->sharemode);
449 if (fp.isopen())
450 {
451 strchg(msg->txt, 0x0D, 0x0A);
452 fp.Fputs(msg->txt);
453 }
454
455 HandleGEvent(EVTT_JOBDONE);
456 waitkeyt(1000);
457 }
458 w_info(NULL);
459 }
460 }
461
462
463 // ------------------------------------------------------------------
464
465