예제 #1
0
/*
 * 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;
}
예제 #2
0
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;
          }
        }
      }
    }
  }
}
예제 #3
0
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;
}