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