1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/stk.c,v 1.7 2011/05/16 16:21:59 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_STK_C_
22 
23 #include "tgifdefs.h"
24 
25 #include "align.e"
26 #include "attr.e"
27 #include "box.e"
28 #include "button.e"
29 #include "choice.e"
30 #include "cmd.e"
31 #include "color.e"
32 #include "cursor.e"
33 #include "dialog.e"
34 #include "drawing.e"
35 #include "dup.e"
36 #include "file.e"
37 #include "font.e"
38 #include "grid.e"
39 #include "mainmenu.e"
40 #include "mark.e"
41 #include "menu.e"
42 #include "msg.e"
43 #include "names.e"
44 #include "navigate.e"
45 #include "obj.e"
46 #include "page.e"
47 #include "pattern.e"
48 #include "raster.e"
49 #include "rect.e"
50 #include "ruler.e"
51 #include "scroll.e"
52 #include "select.e"
53 #include "setup.e"
54 #include "stk.e"
55 #include "strtbl.e"
56 #include "text.e"
57 #include "util.e"
58 #include "version.e"
59 #include "wb.e"
60 
61 struct ObjRec	*tgifObj=NULL;
62 struct StkRec	*topStk=NULL;
63 
AncesterModified()64 int AncesterModified()
65 {
66    struct StkRec *stk_ptr;
67 
68    for (stk_ptr = topStk; stk_ptr != NULL; stk_ptr = stk_ptr->next) {
69       if (stk_ptr->file_mod) {
70          return TRUE;
71       }
72    }
73    return FALSE;
74 }
75 
InitTgifObj()76 void InitTgifObj()
77 {
78    tgifObj = (struct ObjRec *)malloc(sizeof(struct ObjRec));
79    if (tgifObj == NULL) FailAllocMessage();
80    memset(tgifObj, 0, sizeof(struct ObjRec));
81    tgifObj->type = OBJ_BOX;
82    tgifObj->x = tgifObj->y = 0;
83    tgifObj->color = 0;
84    tgifObj->id = (-1);
85    tgifObj->dirty = FALSE;
86    tgifObj->rotation = 0;
87    tgifObj->marked = tgifObj->locked = FALSE;
88    tgifObj->obbox.ltx = tgifObj->obbox.lty = 0;
89    tgifObj->obbox.rbx = tgifObj->obbox.rby = 0;
90    tgifObj->bbox.ltx = tgifObj->bbox.lty = 0;
91    tgifObj->bbox.rbx = tgifObj->bbox.rby = 0;
92    tgifObj->next = tgifObj->prev = NULL;
93    tgifObj->fattr = tgifObj->lattr = NULL;
94    tgifObj->invisible = FALSE;
95    tgifObj->trans_pat = FALSE;
96    tgifObj->detail.b = (struct BoxRec *)malloc(sizeof(struct BoxRec));
97    if (tgifObj->detail.b == NULL) FailAllocMessage();
98    memset(tgifObj->detail.b, 0, sizeof(struct BoxRec));
99    tgifObj->detail.b->fill = NONEPAT;
100    tgifObj->detail.b->pen = NONEPAT;
101    tgifObj->detail.b->width = 0;
102    tgifObj->detail.b->dash = 0;
103 }
104 
InitStk()105 void InitStk()
106 {
107    curSymDir[0] = '\0';
108    InitTgifObj();
109 }
110 
SaveFileInfo()111 struct StkRec *SaveFileInfo()
112 {
113    struct StkRec *stk_ptr;
114 
115    stk_ptr = (struct StkRec *)malloc(sizeof(struct StkRec));
116    if (stk_ptr == NULL) FailAllocMessage();
117    memset(stk_ptr, 0, sizeof(struct StkRec));
118 
119    stk_ptr->next = topStk;
120    stk_ptr->sel = (topSel == NULL ? NULL : topSel->obj);
121    stk_ptr->first = topObj;
122    stk_ptr->last = botObj;
123    stk_ptr->file_mod = fileModified;
124    stk_ptr->id = objId;
125    stk_ptr->page_style = pageStyle;
126 
127    stk_ptr->orig_x = drawOrigX;
128    stk_ptr->orig_y = drawOrigY;
129    stk_ptr->zoom = zoomScale;
130    stk_ptr->zoomed = zoomedIn;
131    stk_ptr->grid_system = gridSystem;
132    stk_ptr->english_grid = xyEnglishGrid;
133    stk_ptr->metric_grid = xyMetricGrid;
134    stk_ptr->snap_on = snapOn;
135    stk_ptr->color = colorIndex;
136    stk_ptr->h_align = horiAlign;
137    stk_ptr->v_align = vertAlign;
138    stk_ptr->line_w = lineWidth;
139    stk_ptr->line_s = lineStyle;
140    stk_ptr->trans_pat = transPat;
141    stk_ptr->fill = objFill;
142    stk_ptr->pen = penPat;
143    stk_ptr->just = textJust;
144    stk_ptr->v_space = textVSpace;
145    stk_ptr->font = curFont;
146    stk_ptr->f_style = curStyle;
147    stk_ptr->f_sz_unit = curSzUnit;
148    stk_ptr->print_mag = printMag;
149    stk_ptr->grid_shown = gridShown;
150    stk_ptr->move_mode = moveMode;
151    stk_ptr->rcb_radius = rcbRadius;
152    stk_ptr->underline_on = curUnderlineOn;
153    stk_ptr->underline_y_offset = curUnderlineYOffset;
154    stk_ptr->overline_on = curOverlineOn;
155    stk_ptr->overline_y_offset = curOverlineYOffset;
156    stk_ptr->first_file_attr = tgifObj->fattr;
157    stk_ptr->last_file_attr = tgifObj->lattr;
158 
159    stk_ptr->first_page = firstPage;
160    stk_ptr->last_page = lastPage;
161    stk_ptr->cur_page = curPage;
162    stk_ptr->cur_page_num = curPageNum;
163    stk_ptr->last_page_num = lastPageNum;
164    stk_ptr->cols = paperCol;
165    stk_ptr->rows = paperRow;
166    stk_ptr->page_layout_mode = pageLayoutMode;
167 
168    stk_ptr->color_dump = colorDump;
169    stk_ptr->one_page_width = onePageWidth;
170    stk_ptr->one_page_height = onePageHeight;
171 
172    stk_ptr->first_cmd = firstCmd;
173    stk_ptr->last_cmd = lastCmd;
174    stk_ptr->cur_cmd = curCmd;
175    stk_ptr->history_count = historyCount;
176 
177    strcpy(stk_ptr->dir, curDir);
178    stk_ptr->name_valid = curFileDefined;
179    if (stk_ptr->name_valid) strcat(stk_ptr->name, curFileName);
180    strcpy(stk_ptr->sym_dir, curSymDir);
181    strcpy(stk_ptr->domain, curDomainName);
182 
183    stk_ptr->saved_comments = savedComments;
184    stk_ptr->saved_comments_len = savedCommentsLen;
185 
186    stk_ptr->file_bg_pixel = myFileBgPixel;
187    stk_ptr->file_fg_pixel = myFileFgPixel;
188    stk_ptr->file_bg_color_str = myFileBgColorStr;
189    stk_ptr->file_fg_color_str = myFileFgColorStr;
190    stk_ptr->file_bg_gif_url = myFileBgGifURL;
191    stk_ptr->file_bg_pixmap_w = myFileBgPixmapW;
192    stk_ptr->file_bg_pixmap_h = myFileBgPixmapH;
193    stk_ptr->file_bg_pixmap = myFileBgPixmap;
194    myFileBgPixel = myFileFgPixel = INVALID;
195    myFileBgColorStr = myFileFgColorStr = myFileBgGifURL = NULL;
196    myFileBgPixmap = None;
197 
198    return stk_ptr;
199 }
200 
ResetFileInfo()201 void ResetFileInfo()
202 {
203    ClearBgColorInfo(FALSE);
204    ClearBgPixmapInfo(FALSE);
205 
206    tgifObj->fattr = NULL;
207    tgifObj->lattr = NULL;
208 
209    firstCmd = lastCmd = curCmd = NULL;
210    historyCount = 0;
211 
212    topObj = botObj = NULL;
213    firstPage = lastPage = curPage = NULL;
214    lastPageNum = 0;
215    InitPage();
216 
217    savedComments = NULL;
218    savedCommentsLen = 0;
219 }
220 
PushIcon()221 int PushIcon()
222 {
223    struct StkRec *stk_ptr;
224    struct ObjRec *obj_ptr;
225    char sym_name[MAXPATHLENGTH], path_name[MAXPATHLENGTH];
226    char file_name[MAXPATHLENGTH], *rest;
227    int read_status, short_name;
228    FILE *fp;
229    int tmp_linenum, interrupted, is_pin;
230    char tmp_filename[MAXPATHLENGTH], tmp_filefullpath[MAXPATHLENGTH];
231 
232    if (gstWBInfo.do_whiteboard) {
233       MsgBox(TgLoadString(STID_PUSH_IN_WB), TOOL_NAME, INFO_MB);
234       return FALSE;
235    }
236    if (topSel == NULL || topSel != botSel ||
237       (topSel->obj->type != OBJ_ICON && topSel->obj->type != OBJ_PIN)) {
238       MsgBox(TgLoadString(STID_SEL_ONE_ICON_OBJ_TO_PUSH), TOOL_NAME, INFO_MB);
239       return FALSE;
240    }
241    is_pin = (topSel->obj->type==OBJ_PIN);
242 
243    strcpy(sym_name, topSel->obj->detail.r->s);
244    if (*sym_name == DIR_SEP) {
245       char *psz=UtilStrRChr(sym_name, DIR_SEP), *psz1=sym_name;
246 
247       *psz = '\0';
248       strcpy(path_name, sym_name);
249       *psz++ = DIR_SEP;
250       while (*psz != '\0') *psz1++ = *psz++;
251       *psz1 = '\0';
252    } else {
253       if (!GetSymbolPath(sym_name, is_pin, path_name)) {
254          sprintf(gszMsgBox, TgLoadString(STID_CANT_FND_SYM_FILE_IN_PATH),
255                sym_name, is_pin ? PIN_FILE_EXT : SYM_FILE_EXT, curDomainPath);
256          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
257          return FALSE;
258       }
259    }
260    strcat(sym_name, ".");
261    if (is_pin) {
262       strcat(sym_name, PIN_FILE_EXT);
263    } else {
264       strcat(sym_name, SYM_FILE_EXT);
265    }
266    sprintf(file_name, "%s%c%s", path_name, DIR_SEP, sym_name);
267 
268    if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
269 
270    if ((fp=fopen(file_name, "r")) == NULL) {
271       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FOR_READ_PUSH),
272             (short_name ? rest : file_name));
273       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
274       return FALSE;
275    }
276 
277    strcpy(tmp_filefullpath, scanFileFullPath);
278    strcpy(tmp_filename, scanFileName);
279    tmp_linenum = scanLineNum;
280    UtilStrCpyN(scanFileFullPath, sizeof(scanFileFullPath), file_name);
281    strcpy(scanFileName, (short_name ? rest : file_name));
282    scanLineNum = 0;
283 
284    HighLightReverse();
285 
286    stk_ptr = SaveFileInfo();
287    ResetFileInfo();
288    if (usePaperSizeStoredInFile) ResetOnePageSize();
289 
290    topStk = stk_ptr;
291 
292    sprintf(gszMsgBox, TgLoadCachedString(CSTID_PUSHING_INTO_NAMED),
293          (short_name ? rest : file_name));
294    Msg(gszMsgBox);
295    CleanUpDrawingWindow();
296    XClearWindow(mainDisplay, drawWindow);
297    somethingHighLighted = FALSE;
298    SetFileModified(FALSE);
299 
300    SetWatchCursor(drawWindow);
301    SetWatchCursor(mainWindow);
302    numRedrawBBox = 0;
303    ShowInterrupt(1);
304    interrupted = FALSE;
305    readingPageNum = loadedCurPageNum = 0;
306    foundGoodStateObject = FALSE;
307    while ((read_status=ReadObj(fp, &obj_ptr)) == TRUE) {
308       if (obj_ptr != NULL) {
309          obj_ptr->tmp_parent = NULL;
310          AdjForOldVersion(obj_ptr);
311          AddObj(NULL, topObj, obj_ptr);
312          if (!interrupted &&
313                (PointInBBox(obj_ptr->x, obj_ptr->y, drawWinBBox) ||
314                BBoxIntersect(obj_ptr->bbox, drawWinBBox))) {
315             if (!DrawObj(drawWindow, obj_ptr)) interrupted = TRUE;
316             if (CheckInterrupt(TRUE)) interrupted = TRUE;
317          }
318       }
319    }
320    fclose(fp);
321 
322    if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
323       RedrawColorWindow();
324    }
325    if (interrupted) Msg(TgLoadString(STID_USER_INTR_ABORT_DRAW));
326    HideInterrupt();
327 
328    strcpy(scanFileFullPath, tmp_filefullpath);
329    strcpy(scanFileName, tmp_filename);
330    scanLineNum = tmp_linenum;
331 
332    SetDefaultCursor(mainWindow);
333    SetDefaultCursor(drawWindow);
334 
335    if (read_status == INVALID) {
336       sprintf(gszMsgBox, TgLoadString(STID_FILE_VER_ABORT_PUSH),
337             fileVersion, TOOL_NAME, homePageURL);
338       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
339       DrawPaperBoundary(drawWindow);
340       RedrawGridLines(drawWindow);
341       return FALSE;
342    }
343    if (loadedCurPageNum > 0 && curPage != NULL) {
344       GotoPageNum(loadedCurPageNum);
345    }
346    CheckFileAttrsInLoad();
347 
348    strcpy(curFileName, sym_name);
349    strcpy(curSymDir, path_name);
350    curFileDefined = TRUE;
351    if (!curDirIsLocal) {
352       strcpy(curDir, curLocalDir);
353       *curLocalDir = '\0';
354       curDirIsLocal = TRUE;
355    }
356 
357    sprintf(gszMsgBox, TgLoadCachedString(CSTID_CUR_FILE_IS),
358          (short_name ? rest : file_name));
359    Msg(gszMsgBox);
360 
361    RedrawTitleWindow();
362    UpdateAllPinnedMenus();
363    if (!navigatingBackAndForth) CommitNavigate();
364    return foundGoodStateObject;
365 }
366 
RestoreFileInfo(StkPtr)367 void RestoreFileInfo(StkPtr)
368    struct StkRec *StkPtr;
369 {
370    char fname[MAXPATHLENGTH], *rest;
371 
372    fileModified = StkPtr->file_mod;
373    objId = StkPtr->id;
374 
375    CleanUpComments();
376    CleanUpDrawingWindow();
377 
378    drawOrigX = StkPtr->orig_x;
379    drawOrigY = StkPtr->orig_y;
380    zoomScale = StkPtr->zoom;
381    zoomedIn = StkPtr->zoomed;
382    gridSystem = StkPtr->grid_system;
383    xyEnglishGrid = StkPtr->english_grid;
384    xyMetricGrid = StkPtr->metric_grid;
385    snapOn = StkPtr->snap_on;
386    colorIndex = StkPtr->color;
387    horiAlign = StkPtr->h_align;
388    vertAlign = StkPtr->v_align;
389    lineWidth = StkPtr->line_w;
390    lineStyle = StkPtr->line_s;
391    transPat = StkPtr->trans_pat;
392    objFill = StkPtr->fill;
393    penPat = StkPtr->pen;
394    textJust = StkPtr->just;
395    textVSpace = StkPtr->v_space;
396    curFont = StkPtr->font;
397    curStyle = StkPtr->f_style;
398    curSzUnit = StkPtr->f_sz_unit;
399    printMag = StkPtr->print_mag;
400    gridShown = StkPtr->grid_shown;
401    moveMode = StkPtr->move_mode;
402    rcbRadius = StkPtr->rcb_radius;
403    curUnderlineOn = StkPtr->underline_on;
404    curUnderlineYOffset = StkPtr->underline_y_offset;
405    curOverlineOn = StkPtr->overline_on;
406    curOverlineYOffset = StkPtr->overline_y_offset;
407    tgifObj->fattr = StkPtr->first_file_attr;
408    tgifObj->lattr = StkPtr->last_file_attr;
409 
410    CleanUpCmds();
411    firstCmd = StkPtr->first_cmd;
412    lastCmd = StkPtr->last_cmd;
413    curCmd = StkPtr->cur_cmd;
414    historyCount = StkPtr->history_count;
415 
416    firstPage = StkPtr->first_page;
417    lastPage = StkPtr->last_page;
418    curPage = StkPtr->cur_page;
419    curPageNum = StkPtr->cur_page_num;
420    lastPageNum = StkPtr->last_page_num;
421    paperCol = StkPtr->cols;
422    paperRow = StkPtr->rows;
423    pageLayoutMode = StkPtr->page_layout_mode;
424 
425    colorDump = StkPtr->color_dump;
426    onePageWidth = StkPtr->one_page_width;
427    onePageHeight = StkPtr->one_page_height;
428 
429    if (usePaperSizeStoredInFile) SetPSPageWidthHeight();
430 
431    curPage->top = topObj = StkPtr->first;
432    curPage->bot = botObj = StkPtr->last;
433    strcpy(curDomainName, StkPtr->domain);
434    strcpy(curSymDir, StkPtr->sym_dir);
435    curFileDefined = StkPtr->name_valid;
436    if (curFileDefined) {
437       strcpy(curFileName, StkPtr->name);
438       if (*curSymDir == '\0') {
439          sprintf(fname, "%s%c%s", StkPtr->dir, DIR_SEP, curFileName);
440       } else {
441          sprintf(fname, "%s%c%s", curSymDir, DIR_SEP, curFileName);
442       }
443       if (IsPrefix(bootDir, fname, &rest)) {
444          sprintf(gszMsgBox, TgLoadString(STID_POP_BACK_TO_NAMED), ++rest);
445       } else {
446          sprintf(gszMsgBox, TgLoadString(STID_POP_BACK_TO_NAMED), fname);
447       }
448       if (!deserializingFile) Msg(gszMsgBox);
449 
450       SetCurDir(fname);
451    } else {
452       if (!deserializingFile) Msg(TgLoadString(STID_POP_BACK_TO_PARENT_UNDEF));
453    }
454 
455    if (strcmp(curDir, StkPtr->dir) != 0) {
456       strcpy(curDir, StkPtr->dir);
457       UpdateDirInfo();
458    }
459 
460    savedComments = StkPtr->saved_comments;
461    savedCommentsLen = StkPtr->saved_comments_len;
462 
463    ClearBgColorInfo(FALSE);
464    ClearBgPixmapInfo(FALSE);
465 
466    myFileBgPixel = StkPtr->file_bg_pixel;
467    myFileFgPixel = StkPtr->file_fg_pixel;
468    myFileBgColorStr = StkPtr->file_bg_color_str;
469    myFileFgColorStr = StkPtr->file_fg_color_str;
470    myFileBgGifURL = StkPtr->file_bg_gif_url;
471    myFileBgPixmapW = StkPtr->file_bg_pixmap_w;
472    myFileBgPixmapH = StkPtr->file_bg_pixmap_h;
473    myFileBgPixmap = StkPtr->file_bg_pixmap;
474    if (myFileBgColorStr != NULL) {
475       if (!SetFileBgColor()) {
476          ClearBgColorInfo(FALSE);
477       }
478    } else if (myFileBgGifURL != NULL) {
479       if (!SetFileBgPixmap()) {
480          ClearBgColorInfo(FALSE);
481       }
482    }
483 }
484 
PopIcon()485 void PopIcon()
486 {
487    if (topStk == NULL) {
488       MsgBox(TgLoadString(STID_ALREADY_AT_TOP_LEVEL), TOOL_NAME, INFO_MB);
489       return;
490    }
491    while (fileModified) {
492       XBell(mainDisplay, 0);
493       switch (MsgBox(TgLoadString(STID_FILE_MOD_SAVE_BEFORE_POP), TOOL_NAME,
494             YNC_MB)) {
495       case MB_ID_YES: SaveFile(); break;
496       case MB_ID_NO: SetFileModified(FALSE); break;
497       case MB_ID_CANCEL: return;
498       }
499    }
500    AdjustNavigate();
501    RestoreFileInfo(topStk);
502    ResetOnePageSize();
503 
504    topSel = botSel = (struct SelRec *)malloc(sizeof(struct SelRec));
505    if (topSel == NULL) FailAllocMessage();
506    topSel->next = NULL;
507    topSel->prev = NULL;
508    topSel->obj = topStk->sel;
509    UpdSelBBox();
510 
511    if (UpdPageStyle(topStk->page_style)) {
512       UpdDrawWinBBox();
513       AdjSplineVs();
514    }
515    UpdDrawWinWH();
516    SetCanvasFont();
517 
518    RedrawRulers();
519    RedrawScrollBars();
520    RedrawChoiceWindow();
521    RedrawTitleWindow();
522    UpdDrawWinBBox();
523    UpdateAllPinnedMenus();
524 
525    free(topStk);
526    topStk = topStk->next;
527    ClearAndRedrawDrawWindow();
528    XSync(mainDisplay, True);
529    justDupped = FALSE;
530 }
531 
CleanUpTgifObj()532 void CleanUpTgifObj()
533 {
534    if (tgifObj != NULL) {
535       DelAllAttrs(tgifObj->fattr);
536       FreeBoxObj(tgifObj);
537    }
538    tgifObj = NULL;
539 }
540 
CleanUpStk()541 void CleanUpStk()
542 {
543    register struct StkRec *next_stk;
544 
545    for ( ; topStk != NULL; topStk = next_stk) {
546       next_stk = topStk->next;
547       firstPage = topStk->first_page;
548       lastPage = topStk->last_page;
549       CleanUpPage();
550       free(topStk);
551    }
552    curSymDir[0] = '\0';
553    CleanUpTgifObj();
554 }
555