/* * Create a toolbar with buttons, return toolbar widget. */ Widget create_toolbar(Widget parent, Widget menu_bar) { #if HAVE_XPM size_t alloc_len = 0, n; size_t alloc_step = 16; const char *c_ptr, *e_ptr; #endif /* HAVE_XPM */ Widget tool_bar; resource.toolbar_unusable = False; tool_bar_frame = XtVaCreateWidget("toolBarFrame", xmFrameWidgetClass, parent, XmNshadowType, XmSHADOW_OUT, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, menu_bar, NULL); tool_bar = XtVaCreateManagedWidget("toolBar", xmRowColumnWidgetClass, tool_bar_frame, XmNchildType, XmFRAME_WORKAREA_CHILD, XmNrowColumnType, XmWORK_AREA, XmNorientation, XmHORIZONTAL, XmNtraversalOn, False, XmNisHomogeneous, False, XmNpacking, XmPACK_TIGHT, XmNspacing, 0, /* override to use SEPARATOR(n) instead */ XmNadjustLast, True, NULL); #if HAVE_XPM /* parse toolbar_translations, create the widgets and assign the actions */ for (n = 0, c_ptr = resource.toolbar_translations; c_ptr != NULL && *c_ptr != '\0'; c_ptr = e_ptr, n++) { char **line_items = NULL; int extra_space; size_t len, curr, item_count = 0; if ((e_ptr = strchr(c_ptr, '\n')) == NULL /* ... and in case last line doesn't end with \n ... */ && (e_ptr = strchr(c_ptr, '\0')) == NULL) { break; } if (e_ptr == c_ptr) { XDVI_WARNING((stderr, "Skipping empty line in toolbarTranslations resource.")); e_ptr++; continue; } len = e_ptr - c_ptr; TRACE_GUI((stderr, "LEN %lu: |%.*s|", (unsigned long)len, (int)len, c_ptr)); line_items = split_line(c_ptr, SEP_CHAR, 0, len, &item_count); if (globals.debug & DBG_GUI) { int k; for (k = 0; line_items[k] != NULL; k++) { fprintf(stderr, "ITEM %d of %lu: |%s|\n", k, (unsigned long)item_count, line_items[k]); } } while (alloc_len <= n + 1) { alloc_len += alloc_step; toolbar_buttons = xrealloc(toolbar_buttons, alloc_len * sizeof *toolbar_buttons); } if (item_count == 1 && sscanf(line_items[0], "SPACER(%d)", &extra_space) == 1) { TRACE_GUI((stderr, "creating spacer of witdh %d at %lu", extra_space, (unsigned long)n)); create_toolbar_separator(tool_bar, &(toolbar_buttons[n].button), extra_space); toolbar_buttons[n].type = TB_SEPARATOR; } else if (item_count == 4) { Pixmap sens, insens; int idx = strtoul(line_items[0], (char **)NULL, 10); struct xdvi_action *action; sens = insens = 0; /* make compiler happy ... */ TRACE_GUI((stderr, "creating pixmap at %d", idx)); if (!create_pixmap(tool_bar, idx, &sens, &insens)) { free(toolbar_buttons); toolbar_buttons = NULL; break; } TRACE_GUI((stderr, "creating button %ld", (unsigned long)n)); if (!create_toolbar_button(tool_bar, &(toolbar_buttons[n].button), &sens, &insens)) { free(toolbar_buttons); toolbar_buttons = NULL; break; } toolbar_buttons[n].type = TB_BUTTON; if (compile_action(line_items[3], &action)) { char *long_tooltip = xstrdup(line_items[1]); toolbar_buttons[n].tip = xstrdup(line_items[2]); /* char *short_tooltip = xstrdup(line_items[2]); */ command_call[0].closure = (XtPointer) action; /* eventually save this widget in list of `special' buttons that need to toggle between sensitive/insensitive */ button_info_save(action, toolbar_buttons[n].button); XtVaSetValues(toolbar_buttons[n].button, XmNactivateCallback, (XtArgVal)command_call, NULL); XtAddEventHandler(toolbar_buttons[n].button, EnterWindowMask | LeaveWindowMask, False, enter_leave, long_tooltip); } else { XDVI_WARNING((stderr, "Invalid action \"%s\" in toolbarTranslations resource:\n\"%.*s\"", line_items[3], (int)len, c_ptr)); } } else { XDVI_WARNING((stderr, "Skipping malformed line \"%.*s\" in toolbarTranslations resource " "(%lu instead of 4 items).", (int)len, c_ptr, (unsigned long)item_count)); toolbar_buttons[n].button = 0; } for (curr = 0; curr < item_count; curr++) { free(line_items[curr]); } free(line_items); line_items = NULL; if (*e_ptr != '\0') e_ptr++; } #else if ((resource.expert_mode & XPRT_SHOW_SCROLLBARS) != 0) { XDVI_WARNING((stderr, "This version has been compiled without XPM support. " "Disabling the toolbar, which needs XPM.")); } #endif /* HAVE_XPM */ if (toolbar_buttons == NULL) { resource.toolbar_unusable = True; resource.expert_mode ^= XPRT_SHOW_TOOLBAR; } else { #if HAVE_XPM toolbar_buttons[n].button = 0; /* terminate info */ #endif } return tool_bar; }
void CScriptEdit::CheckScript(int messages) { CString tmpstr; CString linestr; CString line; trigger trigger; action action; int i; int triggeroraction; int startline, endline; int num_or; bool tr_override; int commentpos; if(m_bcs) { tmpstr.Format("Edit script: %s%s",itemname, the_script.m_changed?"*":""); } else { tmpstr.Format("Edit script source: %s%s",itemname, the_script.m_changed?"*":""); } SetWindowText(tmpstr); if(!(messages&FORCED_CHECK) ) { if(editflg&NOCHECK) return; if(!m_text_control.GetModify()) return; } m_text_control.SetModify(false); m_count=m_text_control.GetLineCount(); if(m_errors) delete [] m_errors; triggeroraction=TA_IF; if(m_count<0) { m_errors=new int[1]; m_errors[0]=m_count; m_firsterror=0; endline=m_count=1; } else { m_firsterror=-1; m_errors=new int[m_count]; if(messages&WHOLE_CHECK) { startline=0; endline=m_count; } else { startline=m_text_control.GetFirstVisibleLine(); endline=min(m_count,startline+LINES); while(startline>0) { if(GetLine(startline)=="IF") break; startline--; } } num_or=0; tr_override=false; for(i=startline;i<endline;i++) { line=GetLine(i); commentpos=line.Find("//"); if(commentpos>=0) { tmpstr=line.Left(commentpos); } else tmpstr=line; tmpstr.TrimRight(); tmpstr.TrimLeft(); if(!tmpstr.IsEmpty()) { switch(triggeroraction) { case TA_ACTION: m_errors[i]=match_string(tmpstr, "END",0,-130); if(!m_errors[i]) { triggeroraction=TA_IF; break; } m_errors[i]=match_string(tmpstr, "RESPONSE #%d",m_indent,-110); if(!m_errors[i]) { triggeroraction=TA_ACTION; break; } m_errors[i]=compile_action(tmpstr, action, 0); format_line(tmpstr,m_indent*2); break; case TA_TRIGGER: m_errors[i]=match_string(tmpstr, "THEN",0,-120); if(!m_errors[i]) { if(num_or) { m_errors[i]=CE_INCOMPLETE_OR; } if(tr_override) { m_errors[i]=CE_INCOMPLETE_TROVERRIDE; } triggeroraction=TA_RESPONSE; break; } m_errors[i]=compile_trigger(tmpstr, trigger); format_line(tmpstr, num_or?m_indent+2:m_indent); if((trigger.opcode&0x1fff)==TR_OR) { if(num_or) m_errors[i]=CE_INCOMPLETE_OR; num_or=trigger.bytes[0]; } else { if(num_or) num_or--; } if((trigger.opcode==TR_OVERRIDE) && is_this_bgee()) { if(tr_override) m_errors[i]=CE_INCOMPLETE_TROVERRIDE; else tr_override=true; } else { //override object??? tr_override=false; } break; case TA_IF: m_errors[i]=match_string(tmpstr, "IF",0,-100); triggeroraction=TA_TRIGGER; num_or=0; tr_override=false; break; case TA_RESPONSE: m_errors[i]=match_string(tmpstr, "RESPONSE #%d",m_indent,-110); triggeroraction=TA_ACTION; break; } if(m_errors[i]) { if(m_firsterror==-1) m_firsterror=i; } } else m_errors[i]=0; if(commentpos>=0) line=tmpstr+line.Mid(commentpos); else line=tmpstr; } } if(messages&SHOW_MESSAGES) { if(m_firsterror>=0) { for(i=m_firsterror;i<endline;i++) { if(m_errors[i]) { tmpstr.Format("Error in script line #%d: %s",i+1,get_compile_error(m_errors[i]) ); if(MessageBox(tmpstr,"Dialog editor",MB_ICONEXCLAMATION|MB_OKCANCEL)==IDCANCEL) { m_firsterror=i; //positioning to the cancelled line break; } } } } } }
int CChitemDlg::check_dialog(int check_or_scan) { CString *lines; CString tmp; journal_type journal; int fh; int ret, gret; int linecount; int i,j; trigger trigger; action action; int num_or, strref; int first, last; loc_entry tmploc; bool got_continue; bool warn = (chkflg&WARNINGS)==0; gret=0; if(check_or_scan!=SCANNING) { if(check_or_scan==CHECKING) //no JOURNAL { //checking state headers for(i=0;i<the_dialog.statecount;i++) { switch(check_reference(the_dialog.dlgstates[i].actorstr,1,1,0)) { case 1: log("Actor has invalid text in state #%d",i); gret=TREESTATE|i; break; case 2: case 5: log("Actor has no included text in state #%d",i); gret=TREESTATE|i; } if(chkflg&NOSTRUCT) continue; if(the_dialog.dlgstates[i].trnumber<1) { log("No transitions in state #%d",i); gret=TREESTATE|i; continue; } num_or=the_dialog.dlgstates[i].trnumber+the_dialog.dlgstates[i].trindex; if(num_or<1 || num_or>the_dialog.transcount) { log("Invalid last index of transitions (%d) in state #%d",num_or,i); gret=TREESTATE|i; continue; } got_continue = false; first = the_dialog.dlgstates[i].trindex; last = first + the_dialog.dlgstates[i].trnumber; for (j=first;j<last;j++) { num_or=the_dialog.dlgtrans[j].flags; if(!(num_or&HAS_TEXT)) { if ((j!=first) && got_continue && !(num_or&HAS_TRIGGER) ) { log("Unconditional continue in state #%d (response #%d) overlaps a previous continue!", i, j); //gret=TREESTATE|i; gret=TRANSSTATE|j; } got_continue = true; } } } } //checking transition headers for(i=0;i<the_dialog.transcount;i++) { num_or=the_dialog.dlgtrans[i].flags; if(the_dialog.dlgtrans[i].playerstr<=0) { if(num_or&HAS_TEXT) { log("Transition #%d has no player string set, despite flags.",i); gret=TRANSSTATE|i; } } else { if(!(num_or&HAS_TEXT) ) { log("Transition #%d has player string set, but no flags.",i); gret=TRANSSTATE|i; } } //checking transition trigger reference j=the_dialog.dlgtrans[i].trtrindex; if(j<0 || j>=the_dialog.header.numtrtrigger) { if(num_or&HAS_TRIGGER) { log("Transition #%d has a wrong trigger index (%d).",i,j); gret=TRANSSTATE|i; } } else if(j) { if(!(num_or&HAS_TRIGGER) && warn) { log("Transition #%d has trigger index (%d), but no flags.",i,j); gret=TRANSSTATE|i; } } //checking action reference j=the_dialog.dlgtrans[i].actionindex; if(j<0 || j>=the_dialog.header.numaction) { if((num_or&HAS_ACTION) ) { log("Transition #%d has a wrong action index (%d).",i,j); gret=TRANSSTATE|i; } } else if(j) { if(!(num_or&HAS_ACTION) && warn) { log("Transition #%d has action index (%d), but no flags.",i,j); gret=TRANSSTATE|i; } } //checking journal string ref strref=the_dialog.dlgtrans[i].journalstr; if(strref<=0) { if(num_or&HAS_JOURNAL) { log("Transition #%d has no journal string set, despite flags.",i); gret=TRANSSTATE|i; } } else { if(!(num_or&HAS_JOURNAL) ) { log("Transition #%d has journal string set, but no flags.",i); gret=TRANSSTATE|i; } else { if((check_or_scan==JOURNAL)) { if((num_or&(HAS_QUEST|HAS_SOLVED))==HAS_QUEST) { if(journals.Lookup(strref,journal)) { if(!journal.string.IsEmpty()) { if (journal.string.Find(itemname)<0) { journal.string+=", "+itemname; } journal.type|=HAS_QUEST; journals[strref]=journal; } } else { journal.type=HAS_QUEST; journal.string=itemname; journals[strref]=journal; } } else { journal.type=0; journals.Lookup(strref,journal); journal.type|=num_or&(HAS_QUEST|HAS_SOLVED); journal.string=""; journals[strref]=journal; } continue; } } switch(check_reference(strref,2,10,0) ) { case 1: log("Invalid journal string in transition #%d (reference: %d).",i, strref); gret=TRANSSTATE|i; break; case 2: log("Deleted journal string in transition #%d (reference: %d).",i, strref); gret=TRANSSTATE|i; break; case 3: //if this isn't a quest journal entry, don't complain about missing title if ((num_or&(HAS_QUEST|HAS_SOLVED))!=0) { log("Titleless journal string in transition #%d (reference: %d).",i, strref); gret=TRANSSTATE|i; } break; } } //checking dialog linkage RetrieveResref(tmp,the_dialog.dlgtrans[i].nextdlg); num_or=the_dialog.dlgtrans[i].stateindex; if(the_dialog.dlgtrans[i].flags&LEAF_NODE) { if(!tmp.IsEmpty()) { log("External dialog linkage %s:%d for leaf node (state #%d)",tmp,num_or,i); gret=TRANSSTATE|i; } } else { if(tmp==SELF_REFERENCE) { if(the_dialog.header.numstates<=num_or) { log("Invalid internal link to state %d in transition %d",num_or,i); gret=TRANSSTATE|i; } } else { if(dialogs.Lookup(tmp,tmploc) ) { fh=locate_file(tmploc,0); if(the_dialog.CheckExternalLink(fh,num_or) ) { log("Invalid external link to %s:state %d in transition %d",tmp,num_or,i); gret=TRANSSTATE|i; } close(fh); } else { log("Invalid dialog reference: %s in transition %d",tmp,i); gret=TRANSSTATE|i; } } } } } //syntax checking scripts if(check_or_scan!=JOURNAL) { for(i=0;i<the_dialog.sttriggercount;i++) { lines=explode(the_dialog.sttriggers[i], '\n', linecount); if(linecount==-1) { log("Out of memory"); return -1; } num_or=0; for(j=0;j<linecount;j++) { if(lines[j].IsEmpty()) { ret=-44; //empty top level condition } else { ret=compile_trigger(lines[j], trigger); if(!pst_compatible_var()) { if((trigger.opcode&0x3fff)==TR_OR) { if(num_or) { ret=-42; } num_or=trigger.bytes[0]; if (num_or<2 && check_or_scan!=SCANNING) { ret=-47; } } else if(num_or) num_or--; } } if(ret) { if(check_or_scan!=SCANNING) { log("Invalid top level condition: %s at line #%d in %d. state trigger block (%s)", lines[j],j+1,i, get_compile_error(ret)); gret=STATETR|i; //found errors } } else { ret=check_or_scan_trigger(&trigger, handle_trigger(trigger.opcode), check_or_scan, j); if(ret && (check_or_scan!=SCANNING) ) { log("Top level condition was: %s", lines[j]); gret=STATETR|i; } } } if(num_or) { log("Error: %s",get_compile_error(-42)); gret=STATETR|i; } if(lines) delete[] lines; } for(i=0;i<the_dialog.trtriggercount;i++) { lines=explode(the_dialog.trtriggers[i], '\n', linecount); if(linecount==-1) { log("Out of memory"); return -1; } num_or=0; for(j=0;j<linecount;j++) { ret=compile_trigger(lines[j], trigger); if(!pst_compatible_var()) { if((trigger.opcode&0x3fff)==TR_OR) { if(num_or) ret=-42; num_or=trigger.bytes[0]; if (num_or<2 && check_or_scan!=SCANNING) { ret=-47; } } else if(num_or) num_or--; } if(ret) { if(check_or_scan!=SCANNING) { log("Invalid trigger: %s in line #%d in %d. transition trigger block (%s)",lines[j],j+1,i, get_compile_error(ret)); gret=TRANSTR|i; } } else { ret=check_or_scan_trigger(&trigger, handle_trigger(trigger.opcode), check_or_scan, j); if(ret && (check_or_scan!=SCANNING) ) { tmp = lasterrormsg; log("Transition trigger was: %s", lines[j]); lasterrormsg = tmp + "\n" + lasterrormsg; gret=TRANSTR|i; } } } if(num_or) { log("Invalid trigger: in line #%d in %d. transition trigger block (%s)",j, i, get_compile_error(-42)); gret=TRANSTR|i; } if(lines) delete[] lines; } } //num_or stores the previous action opcode initializing it to non-special num_or=0; for(i=0;i<the_dialog.actioncount;i++) { lines=explode(the_dialog.actions[i], '\n', linecount); if(linecount==-1) { log("Out of memory"); return -1; } for(j=0;j<linecount;j++) { ret=compile_action(lines[j], action, false); if(ret) { if(check_or_scan!=CHECKING) continue; log("Invalid action: %s in line #%d in %d. action block (%s)", lines[j],j+1,i,get_compile_error(ret)); gret=ACTIONBL|i; } else { if(check_or_scan!=JOURNAL) { ret=check_or_scan_action(&action, handle_action(action.opcode), check_or_scan, j); if(check_or_scan!=CHECKING) continue; if(ret) { log("Action was: %s", lines[j]); gret=ACTIONBL|i; continue; } } } if(check_or_scan==JOURNAL) { switch(action.opcode) { case AC_REMOVE_JOURNAL_IWD:case AC_QUESTDONE_IWD: if(has_xpvar()) { journal.type=0; journals.Lookup(action.bytes[0], journal); journal.string=""; journal.type|=HAS_SOLVED; journals[action.bytes[0]]=journal; } break; case AC_REMOVE_JOURNAL_BG: case AC_QUESTDONE_BG: if(!has_xpvar()) { journal.type=0; journals.Lookup(action.bytes[0], journal); journal.string=""; journal.type|=HAS_SOLVED; journals[action.bytes[0]]=journal; } break; case AC_ADD_JOURNAL: if(has_xpvar() || (action.bytes[3]==JT_QUEST)) { if(journals.Lookup(action.bytes[0],journal)) { if(!journal.string.IsEmpty()) { if (journal.string.Find(itemname)<0) { journal.string+=", "+itemname; } } journal.type|=HAS_QUEST; journals[action.bytes[0]]=journal; } else { journal.string=itemname; journal.type=HAS_QUEST; journals[action.bytes[0]]=journal; } } else { if (action.bytes[3]==JT_DONE) { journal.type=0; journals.Lookup(action.bytes[0],journal); journal.string=""; journal.type|=HAS_SOLVED; journals[action.bytes[0]]=journal; } } } continue; } if(chkflg&NOCUT) continue; if(action.opcode==AC_STCUTMD) { if((num_or!=AC_CLRACT) && (num_or!=AC_CLRALLACT)) { log("Invalid action: StartCutSceneMode() without ClearActions() in line #%d in %d. action block", j+1,i); gret=ACTIONBL|i; } else if(action.opcode==AC_STARTCUT) { if(num_or!=AC_STCUTMD) { log("StartCutScene() without StartCutSceneMode() in line #%d in %d. action block", j+1,i); gret=ACTIONBL|i; } } } if((action.opcode==AC_STCUTMD) || (action.opcode==AC_STARTCUT) || (action.opcode==AC_CLRACT) || (action.opcode==AC_CLRALLACT)) num_or=action.opcode; } if(lines) delete[] lines; } return gret; }