⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 电路仿真程序 Classic Ladder is coded 100% in C.It can be used for educational purposes or anything you wan
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Classic Ladder Project *//* Copyright (C) 2001 Marc Le Douarain *//* mavati@club-internet.fr *//* http://www.multimania.com/mavati/classicladder *//* May 2001 *//* Last update : 26 January 2002 *//* ------ *//* Editor *//* ------ *//* This part of the editor is the one who will not change even if if we use *//* another gui instead of gtk... who know? *//* ------------------------------------------------------------- *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <gtk/gtk.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "classicladder.h"#include "global.h"#include "drawing.h"#include "edit.h"#include "editproperties_gtk.h"#include "calc.h"#include "files.h"#include "arithm_eval.h"#include "classicladder_gtk.h"/* This array give for each special elements the size used */#define TYPEELERULE 0#define XSIZEELERULE 1#define YSIZEELERULE 2static short int RulesForSpecialElements[5][3] =            { {ELE_TIMER , 2, 2 } ,              {ELE_MONOSTABLE, 2, 2 },              {ELE_COMPAR, 3, 1 },              {ELE_OUTPUT_OPERATE, 3, 1 },              {-1, -1, -1}/*end*/ };#define MODE_MODIFY 0#define MODE_ADD 1#define MODE_INSERT 2int ConvBaseInMilliSecsToId(int NbrMilliSecs){    switch(NbrMilliSecs)    {        case TIME_BASE_MINS:            return BASE_MINS;        case TIME_BASE_SECS:            return BASE_SECS;        case TIME_BASE_100MS:            return BASE_100MS;        default:            printf("!!!Error in ConvBaseInMilliSecsToInt()\n");            return BASE_SECS;    }}int ConvBaseInTextToId(char * text){    int ScanBase = 0;    int BaseFound = BASE_SECS;    do    {        if (strcmp(text,CorresDatasForBase[ScanBase].ParamSelect)==0)            BaseFound = ScanBase;        ScanBase++;    }    while(ScanBase<NBR_TIMEBASES);    return BaseFound;}int ConvLabelToNumRung(char * LabelName){    int ScanRung = 0;    int RungFound = -1;    int Done = FALSE;    ScanRung = InfosGene->FirstRung;    do    {        if (strcmp(RungArray[ScanRung].Label,LabelName)==0)            RungFound = ScanRung;        if (ScanRung == InfosGene->LastRung)            Done = TRUE;        else            ScanRung = RungArray[ScanRung].NextRung;    }    while(!Done);    return RungFound;}void LoadElementProperties(StrElement * Element){    char TextToWrite[100];    int NumParam;    StrTimer * Timer;    StrMonostable * Monostable;    for(NumParam=0;NumParam<NBR_PARAMS_PER_OBJ;NumParam++)        SetProperty(NumParam,"---","");    if (Element)    {        switch(Element->Type)        {            case ELE_INPUT:            case ELE_INPUT_NOT:            case ELE_RISING_INPUT:            case ELE_FALLING_INPUT:            case ELE_OUTPUT:            case ELE_OUTPUT_NOT:            case ELE_OUTPUT_SET:            case ELE_OUTPUT_RESET:                strcpy(TextToWrite,DisplayInfo(Element->VarType,Element->VarNum));                SetProperty(0,"Variable",TextToWrite);                break;            case ELE_OUTPUT_JUMP:                SetProperty(0,"JumpToLabel",RungArray[Element->VarNum].Label);                break;            case ELE_TIMER:                Timer = &TimerArray[Element->VarNum];                sprintf(TextToWrite,"%d",Element->VarNum);                SetProperty(0,"Number",TextToWrite);                sprintf(TextToWrite,"%s",CorresDatasForBase[ ConvBaseInMilliSecsToId(Timer->Base) ].ParamSelect);                SetProperty(1,"Base",TextToWrite);                sprintf(TextToWrite,"%d",Timer->Preset/Timer->Base);                SetProperty(2,"Preset",TextToWrite);                break;            case ELE_MONOSTABLE:                Monostable = &MonostableArray[Element->VarNum];                sprintf(TextToWrite,"%d",Element->VarNum);                SetProperty(0,"Number",TextToWrite);                sprintf(TextToWrite,"%s",CorresDatasForBase[ ConvBaseInMilliSecsToId(Monostable->Base) ].ParamSelect);                SetProperty(1,"Base",TextToWrite);                sprintf(TextToWrite,"%d",Monostable->Preset/Monostable->Base);                SetProperty(2,"Preset",TextToWrite);                break;            case ELE_COMPAR:            case ELE_OUTPUT_OPERATE:                strcpy(TextToWrite,DisplayArithmExpr(EditArithmExpr[Element->VarNum],0));                SetProperty(0,"Expression",TextToWrite);                break;        }    }}/* Convert a string to a number if >=Min and <=Max *//* return TRUE if okay */int TextToNumber(char * text,int ValMin,int ValMaxi,int *ValFound){    int IsOk = TRUE;    int Value;    Value = atoi(text);    if ( (Value<ValMin) || (Value>ValMaxi) )        IsOk = FALSE;    if (IsOk)        *ValFound = Value;    return IsOk;}/* Convert a string to variable (type/offset) *//* return TRUE if okay */int TextParserForAVar(char * text,int * VarTypeFound,int * VarOffsetFound){    int TypeFound;    int OffsetFound;    int IsOk = TRUE;    switch(text[0])    {        case 'B':            TypeFound = VAR_MEM_BIT;            if (!TextToNumber(&text[1],0,NBR_BITS-1,&OffsetFound))                IsOk = FALSE;            break;        case 'T':            if (text[strlen(text)-2]!=',')            {                IsOk = FALSE;            }            else            {                switch(text[strlen(text)-1])                {                    case 'D':                        TypeFound = VAR_TIMER_DONE;                        break;                    case 'R':                        TypeFound = VAR_TIMER_RUNNING;                        break;                    default:                        IsOk = FALSE;                        break;                }                text[strlen(text)-2] = '\0';                if(!TextToNumber(&text[1],0,NBR_TIMERS-1,&OffsetFound))                    IsOk = FALSE;            }            break;        case 'M':            if (text[strlen(text)-2]!=',')            {                IsOk = FALSE;            }            else            {                switch(text[strlen(text)-1])                {                    case 'R':                        TypeFound = VAR_MONOSTABLE_RUNNING;                        break;                    default:                        IsOk = FALSE;                        break;                }                text[strlen(text)-2] = '\0';                if(!TextToNumber(&text[1],0,NBR_MONOSTABLES-1,&OffsetFound))                    IsOk = FALSE;            }            break;        case 'I':            TypeFound = VAR_PHYS_INPUT;            if (!TextToNumber(&text[1],0,NBR_PHYS_INPUTS-1,&OffsetFound))                IsOk = FALSE;            break;        case 'Q':            TypeFound = VAR_PHYS_OUTPUT;            if (!TextToNumber(&text[1],0,NBR_PHYS_OUTPUTS-1,&OffsetFound))                IsOk = FALSE;            break;        case 'W':            TypeFound = VAR_MEM_WORD;            if (!TextToNumber(&text[1],0,NBR_WORDS-1,&OffsetFound))                IsOk = FALSE;            break;        default:            IsOk = FALSE;    }    if (IsOk)    {        *VarTypeFound = TypeFound;        *VarOffsetFound = OffsetFound;    }    return IsOk;}/* Convert a string of arithmetic expression for the arithm_eval : *//* Variables becomes @type/offset@ *//* Then verify all the expression using arithm_eval *//* return pointer on the new string converted and verified if okay, else NULL */char * TextParserForArithmExpr(char * text, int TypeElement){    static char NewExpr[100];    char Buffer[20];    int ItIsOk = TRUE;    int VarType;    int VarOffset;    char * ErrorMessage = NULL;    char * ptr = text;    strcpy(NewExpr,"");    /* Convert expression for variables authorized */    do    {        switch(*ptr)        {            case 'W':                if (TextParserForAVar(ptr,&VarType,&VarOffset))                {                    sprintf(Buffer,"@%d/%d@",VarType,VarOffset);                    strcat(NewExpr,Buffer);                    do                    {                        ptr++;                    }                    while( (*ptr>='0') && (*ptr<='9') );                }                else                {                    ItIsOk = FALSE;                }                break;            case 'B':            case 'T':            case 'M':            case 'I':            case 'Q':                ItIsOk = FALSE;                ErrorMessage = "Incompatible type of variable";                break;            case '\0':                ItIsOk = FALSE;                ErrorMessage = "Null expression not valid";                break;            default:                sprintf(Buffer,"%c",*ptr);                strcat(NewExpr, Buffer);                ptr++;                break;        }    }    while( (*ptr) && ItIsOk );    /* Verify length of the expression */    if (ItIsOk)    {        if (strlen(NewExpr)>=ARITHM_EXPR_SIZE)        {            ItIsOk = FALSE;            ErrorMessage = "Expression too long";        }    }//printf("Parser Arithm ; ItIsOk=%d ; OriExpr=%s ; NewExpr=%s\n",ItIsOk, text, NewExpr);    /* Verify expression converted */    if (ItIsOk)    {        if (TypeElement==ELE_OUTPUT_OPERATE)            ErrorMessage = VerifySyntaxForMakeCalc(NewExpr);        else            ErrorMessage = VerifySyntaxForEvalCompare(NewExpr);        if (ErrorMessage)            ItIsOk = FALSE;    }    /* Error Message */    if (ErrorMessage)    {        ShowMessageBox("Error",ErrorMessage,"Ok");    }    /* Give result */    if (ItIsOk)        return NewExpr;    else        return NULL;}void SaveElementProperties(){    int IdBase;    int Preset;    int NumRungToJump;    StrTimer * Timer;    StrMonostable * Monostable;    char * NewArithmExpr;    if (EditDatas.ElementUnderEdit)    {        switch(EditDatas.ElementUnderEdit->Type)        {            case ELE_INPUT:            case ELE_INPUT_NOT:            case ELE_RISING_INPUT:            case ELE_FALLING_INPUT:            case ELE_OUTPUT:            case ELE_OUTPUT_NOT:            case ELE_OUTPUT_SET:            case ELE_OUTPUT_RESET:                TextParserForAVar(GetProperty(0),&EditDatas.ElementUnderEdit->VarType,&EditDatas.ElementUnderEdit->VarNum);                break;            case ELE_TIMER:                TextToNumber(GetProperty(0),0,NBR_TIMERS-1,&EditDatas.ElementUnderEdit->VarNum);                Timer = &TimerArray[EditDatas.ElementUnderEdit->VarNum];                IdBase = ConvBaseInTextToId(GetProperty(1));                Timer->Base = CorresDatasForBase[IdBase].ValueInMS;                strcpy(Timer->DisplayFormat,CorresDatasForBase[IdBase].DisplayFormat);                if (TextToNumber(GetProperty(2),0,999,&Preset))                    Timer->Preset = Preset * Timer->Base;                break;            case ELE_MONOSTABLE:                TextToNumber(GetProperty(0),0,NBR_MONOSTABLES-1,&EditDatas.ElementUnderEdit->VarNum);                Monostable = &MonostableArray[EditDatas.ElementUnderEdit->VarNum];                IdBase = ConvBaseInTextToId(GetProperty(1));                Monostable->Base = CorresDatasForBase[IdBase].ValueInMS;                strcpy(Monostable->DisplayFormat,CorresDatasForBase[IdBase].DisplayFormat);                if (TextToNumber(GetProperty(2),0,999,&Preset))                    Monostable->Preset = Preset * Monostable->Base;                break;            case ELE_OUTPUT_JUMP:                NumRungToJump = ConvLabelToNumRung(GetProperty(0));                if (NumRungToJump>=0)                    EditDatas.ElementUnderEdit->VarNum = NumRungToJump;                break;            case ELE_COMPAR:                NewArithmExpr = TextParserForArithmExpr(GetProperty(0), ELE_COMPAR);                if (NewArithmExpr)                    strcpy(EditArithmExpr[EditDatas.ElementUnderEdit->VarNum],NewArithmExpr);                break;            case ELE_OUTPUT_OPERATE:                NewArithmExpr = TextParserForArithmExpr(GetProperty(0), ELE_OUTPUT_OPERATE);                if (NewArithmExpr)                    strcpy(EditArithmExpr[EditDatas.ElementUnderEdit->VarNum],NewArithmExpr);                break;        }        /* display back to show what we have really understand... */        LoadElementProperties(EditDatas.ElementUnderEdit);    }}/* For editing, we do not touch directly the current arithm   expressions. We work on the edit ones. It is only when the   edited rung is applyed that we copy the expressions edited */void CopyCurrentArithmExpr(){    int NumExpr;    for (NumExpr=0; NumExpr<NBR_ARITHM_EXPR; NumExpr++)        strcpy(EditArithmExpr[NumExpr],ArithmExpr[NumExpr].Expr);}void ApplyNewArithmExpr(){    int NumExpr;    for (NumExpr=0; NumExpr<NBR_ARITHM_EXPR; NumExpr++)        strcpy(ArithmExpr[NumExpr].Expr,EditArithmExpr[NumExpr]);}void CheckForFreeingArithmExpr(int PosiX,int PosiY){    int TypeElement = EditDatas.Rung.Element[PosiX][PosiY].Type;    if ( (TypeElement==ELE_COMPAR) || (TypeElement==ELE_OUTPUT_OPERATE) )    {        /* Freeing Expr */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -