123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300 |
- #include "JsonEditor.h"
- #include "Bild.h"
- #include "Globals.h"
- #include "MausEreignis.h"
- #include "Regex.h"
- #include "Schrift.h"
- #include "TastaturEreignis.h"
- #include "TextFeld.h"
- using namespace Framework;
- using namespace JSON;
- const char* errors[] = {"Unexpected start of object",
- "Unexpected start of array",
- "Unexpected value",
- "Unexpected ','",
- "Unexpected ':'",
- "Unexpected end of object",
- "Unexpected end of array",
- "Unexpected start of string",
- "Invalid json value",
- ""};
- class EditableJsonElementReference : public virtual AbstractElement,
- public virtual ReferenceCounter,
- public virtual AbstractBool,
- public virtual AbstractNumber,
- public virtual AbstractString,
- public virtual AbstractArray,
- public virtual AbstractObject
- {
- private:
- EditableJsonElement* root;
- RCArray<EditableJsonElementReference>* children;
- EditableJsonElementReference(EditableJsonElement* root,
- RCArray<EditableJsonElementReference>* children)
- : root(root),
- children(children)
- {}
- public:
- EditableJsonElementReference(EditableJsonElement* root)
- : root(root),
- children(new RCArray<EditableJsonElementReference>())
- {}
- ~EditableJsonElementReference()
- {
- children->release();
- }
- AbstractType getType() const override
- {
- if (root->hasError() || root->getValue().istGleich("null"))
- {
- return AbstractType::NULL_;
- }
- else if (root->getOpeningControllChar() == '{')
- {
- return AbstractType::OBJECT;
- }
- else if (root->getOpeningControllChar() == '[')
- {
- return AbstractType::ARRAY;
- }
- else if (root->getValue().istGleich("true")
- || root->getValue().istGleich("false"))
- {
- return AbstractType::BOOLEAN;
- }
- else if (root->getValue().hatAt(0, "\""))
- {
- return AbstractType::STRING;
- }
- else
- {
- return AbstractType::NUMBER;
- }
- }
- const AbstractBool* asAbstractBool() const override
- {
- return this;
- }
- const AbstractNumber* asAbstractNumber() const override
- {
- return this;
- }
- const AbstractString* asAbstractString() const override
- {
- return this;
- }
- const AbstractArray* asAbstractArray() const override
- {
- return this;
- }
- const AbstractObject* asAbstractObject() const override
- {
- return this;
- }
- Text toString() const override
- {
- return root->getRecursiveContent();
- }
- bool getBool() const override
- {
- return (bool)root->getValue();
- }
- double getNumber() const override
- {
- return (double)root->getValue();
- }
- Text getString() const override
- {
- Text txt = root->getValue().getText() + 1;
- txt.remove(txt.getLength() - 1, 1);
- return (double)root->getValue();
- }
- AbstractElement* zAbstractValue(int i) const override
- {
- EditableJsonElement* e = root->zFirstChildren();
- while (e && i > 0)
- {
- e = e->zMextSibling();
- i--;
- }
- if (e)
- {
- EditableJsonElementReference* result
- = new EditableJsonElementReference(e, children);
- children->add(result);
- return result;
- }
- return 0;
- }
- int getLength() const override
- {
- EditableJsonElement* e = root->zFirstChildren();
- int i = 0;
- while (e)
- {
- e = e->zMextSibling();
- i++;
- }
- return i;
- }
- AbstractElement* zAbstractValue(Text field) const override
- {
- EditableJsonElement* e = root->zFirstChildren();
- while (e)
- {
- if (e->getKey().istGleich(field))
- {
- EditableJsonElementReference* result
- = new EditableJsonElementReference(e, children);
- children->add(result);
- return result;
- }
- e = e->zMextSibling();
- }
- return 0;
- }
- int getFieldCount() const override
- {
- return getLength();
- }
- Text getFieldKey(int i) const override
- {
- EditableJsonElement* e = root->zFirstChildren();
- while (e && i > 0)
- {
- e = e->zMextSibling();
- i--;
- }
- if (e)
- {
- return e->getKey();
- }
- return 0;
- }
- bool hasValue(Text field) const override
- {
- EditableJsonElement* e = root->zFirstChildren();
- while (e)
- {
- if (e->getKey().istGleich(field))
- {
- return 1;
- }
- e = e->zMextSibling();
- }
- return 0;
- }
- };
- SyntaxError::SyntaxError(int start, int end, SyntaxErrorType errorType)
- : start(start),
- end(end),
- errorType(errorType)
- {}
- SyntaxError::SyntaxError()
- : start(-1),
- end(-1),
- errorType(SyntaxErrorType::OTHER)
- {}
- int SyntaxError::getStart() const
- {
- return start;
- }
- int SyntaxError::getEnd() const
- {
- return end;
- }
- SyntaxErrorType SyntaxError::getErrorType() const
- {
- return errorType;
- }
- Framework::JSON::ParserState::ParserState(
- JsonStructure parent, bool valueExpected)
- : index(0),
- keyStart(-1),
- keyEnd(0),
- valueStart(-1),
- valueEnd(0),
- errorStart(0),
- parent(parent),
- inString(0),
- escaped(0),
- colon(parent != JsonStructure::OBJECT),
- key(parent != JsonStructure::OBJECT),
- value(0),
- inValue(0),
- valueValidationNeeded(0),
- openingControllChar(0),
- closingControllChar(0),
- valueExpected(valueExpected)
- {}
- bool Framework::JSON::ParserState::next(
- const char* current, const char* next, SyntaxError& error)
- {
- if (current[0] == 0) return next == 0;
- bool stop = 0;
- if (current[0] == '{' && !inString)
- {
- stop = 1;
- if (!colon || value)
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_OBJECT_START;
- }
- value = 1;
- openingControllChar = current[0];
- }
- else if (current[0] == '[' && !inString)
- {
- stop = 1;
- if (!colon || value)
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_ARRAY_START;
- }
- value = 1;
- openingControllChar = current[0];
- }
- else if (current[0] == '}' && !inString)
- {
- stop = current[1] == ']' || current[1] == '}';
- if (!stop)
- {
- const char* n = current + 1;
- while (*n && (*n == ' ' || *n == '\t' || *n == '\r' || *n == '\n'))
- {
- n++;
- }
- stop = *n == ']' || *n == '}';
- if (!stop && next)
- {
- n = next;
- while (
- *n && (*n == ' ' || *n == '\t' || *n == '\r' || *n == '\n'))
- {
- n++;
- }
- stop = *n == ']' || *n == '}';
- }
- }
- if (parent != JsonStructure::OBJECT || (!value && valueExpected))
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_END_OF_OBJECT;
- }
- value = 1;
- closingControllChar = current[0];
- }
- else if (current[0] == ']' && !inString)
- {
- stop = current[1] == ']' || current[1] == '}';
- if (!stop)
- {
- const char* n = current + 1;
- while (*n && (*n == ' ' || *n == '\t' || *n == '\r' || *n == '\n'))
- {
- n++;
- }
- stop = *n == ']' || *n == '}';
- if (!stop && next)
- {
- n = next;
- while (
- *n && (*n == ' ' || *n == '\t' || *n == '\r' || *n == '\n'))
- {
- n++;
- }
- stop = *n == ']' || *n == '}';
- }
- }
- if (parent != JsonStructure::ARRAY || (!value && valueExpected))
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_END_OF_ARRAY;
- }
- value = 1;
- closingControllChar = current[0];
- }
- else if (current[0] == '"' && !escaped)
- {
- inString = !inString;
- if (inString)
- {
- if (!key)
- {
- keyStart = index + 1;
- }
- else if (colon && !value)
- {
- valueStart = index;
- }
- else
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_START_OF_STRING;
- }
- }
- else
- {
- if (!key)
- {
- keyEnd = index;
- key = 1;
- }
- else if (colon && !value)
- {
- valueEnd = index + 1;
- value = 1;
- }
- }
- }
- else if (current[0] == '\\' && inString)
- {
- escaped = !escaped;
- }
- else if (current[0] == ':' && !inString)
- {
- if (key && !colon)
- {
- colon = 1;
- }
- else
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_COLON;
- }
- }
- else if (current[0] == ',' && !inString)
- {
- stop = 1;
- if (!value)
- {
- error.start = index;
- error.end = index + 1;
- error.errorType = SyntaxErrorType::UNEXPECTED_COMMA;
- }
- }
- else
- {
- escaped = 0;
- if (!inString && current[0] != ' ' && current[0] != '\t'
- && current[0] != '\n' && current[0] != '\r')
- {
- if (colon && !value)
- {
- if (!inValue)
- {
- valueStart = index;
- inValue = 1;
- }
- }
- else
- {
- if (!inValue)
- {
- errorStart = index;
- inValue = 1;
- }
- }
- if (inValue
- && (current[1] == ':' || current[1] == '"' || current[1] == '{'
- || current[1] == '[' || current[1] == ']'
- || current[1] == '}' || current[1] == ','))
- {
- inValue = 0;
- if (colon && !value)
- {
- value = 1;
- valueEnd = index + 1;
- valueValidationNeeded = 1;
- }
- else
- {
- error.start = errorStart;
- error.end = index;
- error.errorType = SyntaxErrorType::UNEXPECTED_VALUE;
- }
- }
- }
- else if (inValue)
- {
- inValue = 0;
- if (colon && !value)
- {
- valueEnd = index;
- value = 1;
- valueValidationNeeded = 1;
- }
- else
- {
- error.start = errorStart;
- error.end = index;
- error.errorType = SyntaxErrorType::UNEXPECTED_VALUE;
- }
- }
- }
- index++;
- return stop;
- }
- EditableJsonElement::EditableJsonElement(Regex::Automata<char>* valueValidator)
- : ReferenceCounter(),
- content(),
- valueValidator(valueValidator),
- valueStart(-1),
- keyStart(-1),
- newLineCount(0)
- {
- children = 0;
- siblings = 0;
- lastChild = 0;
- parent = 0;
- hidden = false;
- parentStructure = JsonStructure::VALUE;
- }
- Framework::JSON::EditableJsonElement::EditableJsonElement(
- Regex::Automata<char>* valueValidator, const char* content)
- : EditableJsonElement(valueValidator)
- {
- setContent(content);
- valueValidator->release();
- }
- EditableJsonElement::~EditableJsonElement()
- {
- if (children)
- {
- children->release();
- }
- if (siblings)
- {
- siblings->release();
- }
- }
- void Framework::JSON::EditableJsonElement::setContentOnly(const char** content,
- int& startPos,
- Array<EditableJsonElement*>& afterList,
- Array<EditableJsonElement*>& deleteList)
- {
- errors.leeren();
- int start = startPos;
- EditableJsonElement* before = zBefore(0, false, 0);
- ParserState p(parentStructure,
- before
- ? before->getContent()[before->getContent().getLength() - 1] == ','
- : 0);
- SyntaxError error;
- key = "";
- value = "";
- this->content = "";
- while (true)
- {
- const char* current = (*content) + startPos++;
- const char* next = 0;
- if (afterList.getEintragAnzahl())
- {
- next = afterList.get(0)->getContent();
- }
- if (p.next(current, next, error))
- {
- break;
- }
- if (error.getErrorType() != SyntaxErrorType::OTHER)
- {
- errors.add(error);
- error = SyntaxError();
- }
- if (!*current)
- {
- startPos--;
- }
- if (!(*content)[startPos])
- {
- if (!afterList.getEintragAnzahl())
- {
- break;
- }
- else
- {
- if (p.keyStart >= 0
- && (p.keyEnd < p.keyStart || p.keyEnd + start >= 0)
- && parentStructure == JsonStructure::OBJECT)
- {
- int s = p.keyStart + start < 0 ? 0 : p.keyStart + start;
- int e = p.keyEnd < p.keyStart ? p.index : p.keyEnd + start;
- key += Text(*content, s, e - s);
- }
- if (p.valueStart >= 0
- && (p.valueEnd < p.valueStart || p.valueEnd + start >= 0)
- && parentStructure == JsonStructure::OBJECT)
- {
- int s = p.valueStart + start < 0 ? 0 : p.valueStart + start;
- int e = p.valueEnd < p.valueStart ? p.index + start
- : p.valueEnd + start;
- value += Text(*content, s, e - s);
- }
- this->content += Text(*content,
- start < 0 ? 0 : start,
- start < 0 ? startPos : startPos - start);
- EditableJsonElement* next = afterList.get(0);
- int i = 0;
- afterList.remove(i);
- if (next->children)
- {
- afterList.add(next->children, i);
- i++;
- }
- if (next->siblings)
- {
- afterList.add(next->siblings, i);
- }
- next->disconnect();
- deleteList.add(next);
- *content = next->getContent();
- startPos = 0;
- start = -p.index;
- }
- }
- }
- if (error.getErrorType() != SyntaxErrorType::OTHER)
- {
- errors.add(error);
- error = SyntaxError();
- }
- if (p.keyStart >= 0 && (p.keyEnd < p.keyStart || p.keyEnd + start >= 0)
- && parentStructure == JsonStructure::OBJECT)
- {
- int s = p.keyStart + start < 0 ? 0 : p.keyStart + start;
- int e = p.keyEnd < p.keyStart ? p.index : p.keyEnd + start;
- key += Text(*content, s, e - s);
- }
- if (p.valueStart >= 0
- && (p.valueEnd < p.valueStart || p.valueEnd + start >= 0))
- {
- int s = p.valueStart + start < 0 ? 0 : p.valueStart + start;
- int e
- = p.valueEnd < p.valueStart ? p.index + start : p.valueEnd + start;
- value += Text(*content, s, e - s);
- }
- if (p.valueValidationNeeded)
- {
- if (!isValueValid(value, 0, value.getLength()))
- {
- errors.add(SyntaxError(
- p.valueStart, p.valueEnd, SyntaxErrorType::INVALID_VALUE));
- }
- }
- this->content += Text(*content,
- start < 0 ? 0 : start,
- start < 0 ? startPos : startPos - start);
- newLineCount = this->content.anzahlVon('\n');
- openingControllChar = p.openingControllChar;
- closingControllChar = p.closingControllChar;
- valueStart = p.valueStart;
- keyStart = p.keyStart;
- if ((*content)[startPos]
- && ((*content)[startPos - 1] == '[' || (*content)[startPos - 1] == '{'))
- {
- EditableJsonElement* next = new EditableJsonElement(valueValidator);
- addChildren(next);
- next->setContentRecursive(content, startPos, afterList, deleteList);
- }
- // TODO: set parent structure of children
- // TODO: update tree
- }
- void Framework::JSON::EditableJsonElement::setContentRecursive(
- const char** content,
- int& startPos,
- Array<EditableJsonElement*>& afterList,
- Array<EditableJsonElement*>& deleteList)
- {
- setContentOnly(content, startPos, afterList, deleteList);
- char lastControl = closingControllChar;
- while ((*content)[startPos]
- && !((lastControl == ']' && parentStructure == JsonStructure::ARRAY)
- || (lastControl == '}'
- && parentStructure == JsonStructure::OBJECT)))
- {
- if (closingControllChar == ']'
- && parentStructure == JsonStructure::ARRAY)
- {
- break;
- }
- EditableJsonElement* next = new EditableJsonElement(valueValidator);
- addSibling(next);
- next->setContentOnly(content, startPos, afterList, deleteList);
- lastControl = next->getClosingControllChar();
- }
- }
- void Framework::JSON::EditableJsonElement::format(
- int indent, bool insertNewLine)
- {
- Text content = this->content;
- content.removeWhitespaceAfter(0);
- int index = 0;
- if (insertNewLine)
- {
- content.insert(0, "\n");
- for (int i = 0; i < indent; i++)
- {
- content.insert(1, " ");
- }
- index = indent * 4 + 1;
- }
- bool keyStart = false;
- bool keyEnd = false;
- bool colonFound = false;
- bool valueStart = false;
- bool valueEnd = false;
- bool escaped = false;
- for (int i = index; i < content.getLength(); i++)
- {
- if ((content[i] == '{' || content[i] == '[' || content[i] == ',')
- && !(keyStart && !keyEnd) && !(valueStart && !valueEnd))
- {
- if (content[i] == ',')
- {
- i -= content.removeWhitespaceBefore(i);
- }
- content.removeWhitespaceAfter(i + 1);
- }
- else if ((content[i] == '}' || content[i] == ']')
- && !(keyStart && !keyEnd) && !(valueStart && !valueEnd))
- {
- content.removeWhitespaceAfter(i + 1);
- if (!parent || parent->children != this)
- {
- i -= content.removeWhitespaceBefore(i);
- content.insert(i, '\n');
- for (int j = 0; j < indent - 1; j++)
- {
- content.insert(i + 1, " ");
- }
- i += 1 + (indent > 0 ? (indent - 1) * 4 : 0);
- }
- else
- {
- i -= content.removeWhitespaceBefore(i);
- }
- }
- else if (content[i] == '"' && !escaped)
- { // format whitespaces arround values and keys
- if (!keyStart)
- {
- keyStart = true;
- }
- else
- {
- if (!keyEnd)
- {
- keyEnd = true;
- content.removeWhitespaceAfter(i + 1);
- }
- else
- {
- if (colonFound)
- {
- if (!valueStart)
- {
- valueStart = true;
- }
- else if (!valueEnd)
- {
- valueEnd = true;
- content.removeWhitespaceAfter(i + 1);
- }
- }
- }
- }
- }
- else if (content[i] == ':' && !(keyStart && !keyEnd)
- && !(valueStart && !valueEnd))
- {
- if (!colonFound && keyEnd)
- {
- colonFound = true;
- content.removeWhitespaceAfter(i + 1);
- content.insert(i + 1, " ");
- }
- }
- else if (content[i] == '\t' && !(keyStart && !keyEnd)
- && !(valueStart && !valueEnd))
- {
- content.remove(i, 1);
- i--;
- }
- else if (content[i] == '\\')
- {
- if ((keyStart && !keyEnd) || (valueStart && !valueEnd))
- {
- escaped = !escaped;
- }
- }
- else
- {
- escaped = false;
- }
- }
- int count = 0;
- Array<EditableJsonElement*> empty;
- const char* tmp = content.getText();
- setContentOnly(&tmp, count, empty, empty);
- if (count < content.getLength())
- {
- throw "Illegal State Exception: tree changed after formatting";
- }
- if (children)
- {
- children->formatRecursive(indent + 1, true);
- }
- }
- void Framework::JSON::EditableJsonElement::formatRecursive(
- int indent, bool insertNewLine)
- {
- format(indent, insertNewLine);
- EditableJsonElement* tmp = siblings;
- while (tmp)
- {
- tmp->format(indent, true);
- tmp = tmp->siblings;
- }
- }
- bool Framework::JSON::EditableJsonElement::isValueValid(
- const char* content, int start, int end)
- {
- Text value(content, start, end - start);
- if (value.istGleich("null") || value.istGleich("true")
- || value.istGleich("false"))
- {
- return true;
- }
- RCArray<Regex::Result>* results
- = valueValidator->match(value, value.getLength());
- bool ok = results->getEintragAnzahl() == 1;
- results->release();
- return ok;
- }
- void Framework::JSON::EditableJsonElement::setContent(
- const char* content, int& startPos, Array<EditableJsonElement*>& afterList)
- {
- if (children)
- {
- afterList.add(children);
- }
- if (siblings)
- {
- afterList.add(siblings);
- }
- EditableJsonElement* p = parent;
- EditableJsonElement* last = this;
- while (p)
- {
- if (p->siblings)
- {
- afterList.add(p->siblings);
- p->siblings = 0;
- }
- p->lastChild = last;
- last = p;
- p = p->parent;
- }
- lastChild = 0;
- children = 0;
- siblings = 0;
- if (parent)
- {
- parent->lastChild = this;
- }
- Array<EditableJsonElement*> deleteList;
- setContentRecursive(&content, startPos, afterList, deleteList);
- if (content[startPos])
- {
- EditableJsonElement* next = new EditableJsonElement(valueValidator);
- if (parent)
- {
- parent->addSibling(next);
- }
- else
- {
- addSibling(next);
- }
- next->setContent(content, startPos, afterList);
- }
- else if (afterList.getEintragAnzahl())
- {
- if (openingControllChar)
- {
- while (afterList.getEintragAnzahl()
- && (!lastChild
- || !((openingControllChar == '['
- && lastChild->closingControllChar == ']')
- || (openingControllChar == '{'
- && lastChild->closingControllChar == '}'))))
- {
- EditableJsonElement* next = afterList.get(0);
- afterList.remove(0);
- EditableJsonElement* end = next;
- while (end)
- {
- if ((end->closingControllChar == ']'
- && this->openingControllChar == '[')
- || (end->closingControllChar == '}'
- && this->openingControllChar == '{'))
- {
- if (end->siblings)
- {
- afterList.add(end->siblings, 0);
- end->siblings = 0;
- }
- break;
- }
- end = end->siblings;
- }
- addChildren(next);
- next->checkSyntax();
- while (next->siblings)
- {
- next = next->siblings;
- next->checkSyntax();
- }
- }
- }
- EditableJsonElement* p = parent;
- EditableJsonElement* c = this;
- while (afterList.getEintragAnzahl())
- {
- if (p)
- {
- if (p->siblings)
- {
- afterList.add(p->siblings);
- p->siblings = 0;
- if (p->parent)
- {
- p->parent->lastChild = p;
- }
- }
- while (
- afterList.getEintragAnzahl()
- && (!p->lastChild
- || !((p->openingControllChar == '['
- && p->lastChild->closingControllChar == ']')
- || (p->openingControllChar == '{'
- && p->lastChild->closingControllChar == '}'))))
- {
- EditableJsonElement* next = afterList.get(0);
- afterList.remove(0);
- EditableJsonElement* end = next;
- while (end)
- {
- if ((end->closingControllChar == ']'
- && p->openingControllChar == '[')
- || (end->closingControllChar == '}'
- && p->openingControllChar == '{'))
- {
- if (end->siblings)
- {
- afterList.add(end->siblings, 0);
- end->siblings = 0;
- }
- break;
- }
- end = end->siblings;
- }
- p->addChildren(next);
- next->checkSyntax();
- while (next->siblings)
- {
- next = next->siblings;
- next->checkSyntax();
- }
- }
- c = p;
- p = p->parent;
- }
- else
- {
- while (afterList.getEintragAnzahl())
- {
- EditableJsonElement* next = afterList.get(0);
- afterList.remove(0);
- c->addSibling(next);
- next->checkSyntax();
- while (next->siblings)
- {
- next = next->siblings;
- next->checkSyntax();
- }
- }
- }
- }
- }
- for (EditableJsonElement* e : deleteList)
- {
- e->release();
- }
- }
- void Framework::JSON::EditableJsonElement::checkSyntax()
- {
- errors.leeren();
- EditableJsonElement* before = zBefore(0, false, 0);
- ParserState p(parentStructure,
- before
- ? before->getContent()[before->getContent().getLength() - 1] == ','
- : 0);
- SyntaxError error;
- key = "";
- value = "";
- int pos = 0;
- while (pos < content.getLength())
- {
- const char* current = content.getText() + pos++;
- p.next(current, 0, error);
- if (error.getErrorType() != SyntaxErrorType::OTHER)
- {
- errors.add(error);
- error = SyntaxError();
- }
- }
- if (error.getErrorType() != SyntaxErrorType::OTHER)
- {
- errors.add(error);
- error = SyntaxError();
- }
- if (p.keyStart >= 0 && p.keyEnd >= p.keyStart
- && parentStructure == JsonStructure::OBJECT)
- {
- key += Text(content, p.keyStart, p.keyEnd - p.keyStart);
- }
- if (p.valueStart >= 0 && p.valueEnd >= p.valueStart)
- {
- value += Text(content, p.valueStart, p.valueEnd - p.valueStart);
- }
- if (p.valueValidationNeeded)
- {
- if (!isValueValid(value, 0, value.getLength()))
- {
- errors.add(SyntaxError(
- p.valueStart, p.valueEnd, SyntaxErrorType::INVALID_VALUE));
- }
- }
- openingControllChar = p.openingControllChar;
- closingControllChar = p.closingControllChar;
- valueStart = p.valueStart;
- keyStart = p.keyStart;
- }
- void EditableJsonElement::setContent(const char* content)
- {
- Array<EditableJsonElement*> afterList;
- int p = 0;
- setContent(content, p, afterList);
- }
- void EditableJsonElement::addChildren(EditableJsonElement* content)
- {
- JsonStructure currentStructure
- = openingControllChar == '['
- ? JsonStructure::ARRAY
- : (openingControllChar == '{' ? JsonStructure::OBJECT
- : JsonStructure::VALUE);
- if (this->children)
- {
- this->lastChild->siblings = content;
- }
- else
- {
- this->children = content;
- this->lastChild = content;
- }
- if (content->parent != this)
- {
- content->parent = this;
- content->parentStructure = currentStructure;
- for (; lastChild->siblings; lastChild = lastChild->siblings)
- {
- lastChild->siblings->parent = this;
- lastChild->siblings->parentStructure = currentStructure;
- }
- }
- while (lastChild->siblings)
- {
- lastChild = lastChild->siblings;
- }
- }
- void Framework::JSON::EditableJsonElement::setNextSibling(
- EditableJsonElement* content)
- {
- this->siblings = content;
- EditableJsonElement* current = this;
- if (content->parent != parent)
- {
- for (; current->siblings; current = current->siblings)
- {
- current->siblings->parent = parent;
- current->siblings->parentStructure = parentStructure;
- }
- }
- if (parent)
- {
- parent->lastChild = current;
- while (parent->lastChild->siblings)
- {
- parent->lastChild = parent->lastChild->siblings;
- }
- }
- }
- void EditableJsonElement::addSibling(EditableJsonElement* content)
- {
- EditableJsonElement* current = parent ? parent->lastChild : this;
- while (current->siblings)
- {
- current = current->siblings;
- }
- current->siblings = content;
- if (content->parent != parent)
- {
- for (; current->siblings; current = current->siblings)
- {
- current->siblings->parent = parent;
- current->siblings->parentStructure = parentStructure;
- }
- }
- if (parent)
- {
- parent->lastChild = current;
- while (parent->lastChild->siblings)
- {
- parent->lastChild = parent->lastChild->siblings;
- }
- }
- }
- void Framework::JSON::EditableJsonElement::format()
- {
- int indent = getIndent();
- formatRecursive(indent, false);
- }
- const Text& Framework::JSON::EditableJsonElement::getContent()
- {
- return content;
- }
- Text Framework::JSON::EditableJsonElement::getRecursiveContent()
- {
- Text result
- = content + (children ? children->getRecursiveContent() : Text(""));
- EditableJsonElement* s = siblings;
- while (s)
- {
- result += s->content
- + (s->children ? s->children->getRecursiveContent() : Text(""));
- s = s->siblings;
- }
- return result;
- }
- int Framework::JSON::EditableJsonElement::lineCount()
- {
- return newLineCount;
- }
- bool Framework::JSON::EditableJsonElement::lineCount(bool includeChildren,
- bool includeSiblings,
- EditableJsonElement* stop,
- int& count)
- {
- count += newLineCount;
- if (this == stop)
- {
- return false;
- }
- if (includeChildren && children)
- {
- if (!children->lineCount(true, true, stop, count))
- {
- return false;
- }
- }
- if (includeSiblings && siblings)
- {
- return siblings->lineCount(true, true, stop, count);
- };
- return true;
- }
- bool Framework::JSON::EditableJsonElement::isHidden()
- {
- return hidden;
- }
- void Framework::JSON::EditableJsonElement::setHidden(bool hidden)
- {
- this->hidden = hidden;
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zParent()
- {
- return parent;
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zMextSibling()
- {
- return siblings;
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zFirstChildren()
- {
- return children;
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zLastChildren()
- {
- return lastChild;
- }
- char Framework::JSON::EditableJsonElement::getOpeningControllChar()
- {
- return openingControllChar;
- }
- char Framework::JSON::EditableJsonElement::getClosingControllChar()
- {
- return closingControllChar;
- }
- Text& Framework::JSON::EditableJsonElement::getKey()
- {
- return key;
- }
- Text& Framework::JSON::EditableJsonElement::getValue()
- {
- return value;
- }
- void Framework::JSON::EditableJsonElement::disconnect()
- {
- children = 0;
- lastChild = 0;
- siblings = 0;
- parent = 0;
- }
- void Framework::JSON::EditableJsonElement::removeChild(
- EditableJsonElement* zElement)
- {
- // TODO: needed?
- if (children == zElement)
- {
- children = 0;
- lastChild = 0;
- }
- else
- {
- EditableJsonElement* current = children;
- while (current)
- {
- if (current->siblings == zElement)
- {
- current->siblings = 0;
- if (current->parent)
- {
- current->parent->lastChild = current;
- }
- break;
- }
- current = current->siblings;
- }
- }
- }
- void Framework::JSON::EditableJsonElement::getWordBounds(
- int pos, int* left, int* right)
- {
- bool escaped = false;
- int lastStartStr = -1;
- int lastBlank = 0;
- bool found = false;
- int len = content.getLength();
- for (int i = 0; i < len; i++)
- {
- if ((content[i] == ' ' || content[i] == ',' || content[i] == '\n')
- && lastStartStr == -1)
- {
- if (i >= pos)
- {
- if (left)
- {
- *left = lastBlank;
- }
- if (right)
- {
- *right = i;
- }
- found = true;
- break;
- }
- lastBlank = i + 1;
- }
- else if (content[i] == '"')
- {
- if (lastStartStr == -1)
- {
- lastStartStr = i + 1;
- if (i >= pos)
- {
- if (left)
- {
- *left = i;
- }
- if (right)
- {
- *right = i + 1;
- }
- found = true;
- break;
- }
- }
- else if (!escaped)
- {
- if (i >= pos)
- {
- if (left)
- {
- *left = lastStartStr;
- }
- if (right)
- {
- *right = i;
- }
- found = true;
- break;
- }
- lastStartStr = -1;
- }
- }
- else if (content[i] == '\\' && lastStartStr >= 0)
- {
- escaped = !escaped;
- }
- else
- {
- escaped = false;
- }
- }
- if (!found && lastBlank >= 0)
- {
- if (left)
- {
- *left = lastBlank;
- }
- if (right)
- {
- *right = len;
- }
- }
- }
- bool Framework::JSON::EditableJsonElement::hasError(int column) const
- {
- for (const SyntaxError& error : errors)
- {
- if (error.getStart() <= column && error.getEnd() >= column)
- {
- return true;
- }
- }
- return false;
- }
- SyntaxError Framework::JSON::EditableJsonElement::getError(int column) const
- {
- for (const SyntaxError& error : errors)
- {
- if (error.getStart() <= column && error.getEnd() >= column)
- {
- return error;
- }
- }
- return SyntaxError();
- }
- bool Framework::JSON::EditableJsonElement::hasError() const
- {
- return errors.getEintragAnzahl() > 0;
- }
- void Framework::JSON::EditableJsonElement::makeVisible()
- {
- EditableJsonElement* current = parent;
- while (current)
- {
- current->setHidden(false);
- current = current->zParent();
- }
- }
- bool Framework::JSON::EditableJsonElement::isVisible() const
- {
- EditableJsonElement* current = parent;
- while (current)
- {
- if (current->isHidden())
- {
- return false;
- }
- current = current->zParent();
- }
- return true;
- }
- int Framework::JSON::EditableJsonElement::getIndent() const
- {
- int indent = 0;
- EditableJsonElement* tmp = parent;
- while (tmp)
- {
- indent++;
- tmp = tmp->parent;
- }
- return indent;
- }
- int Framework::JSON::EditableJsonElement::getColor(int index)
- {
- int color = 0xFFA0A0A0;
- if (hasError(index))
- {
- color = 0xFFFF3030;
- }
- else if (keyStart >= 0 && index >= keyStart - 1
- && index < keyStart + key.getLength() + 1)
- {
- color = 0xFF7070C0;
- }
- else if (valueStart >= 0 && index >= valueStart
- && index < valueStart + value.getLength())
- {
- if (value[0] == '"')
- {
- color = 0xFF70C070;
- }
- else if (value.istGleich("null"))
- {
- color = 0xFFC0A070;
- }
- else if (value.istGleich("true") || value.istGleich("false"))
- {
- color = 0xFFC070C0;
- }
- else
- {
- color = 0xFF70C0C0;
- }
- }
- return color;
- }
- void Framework::JSON::EditableJsonElement::removeUntil(
- int startIndex, EditableJsonElement* end, int endIndex)
- {
- Text* result = content.getTeilText(0, startIndex);
- if (end == this)
- {
- result->append(content.getTeilText(endIndex));
- setContent(*result);
- result->release();
- return;
- }
- else
- {
- Array<EditableJsonElement*> toDelete;
- Stack<EditableJsonElement*> stack;
- if (siblings)
- {
- stack.push(siblings);
- }
- if (children)
- {
- stack.push(children);
- }
- if (!stack.getSize())
- {
- EditableJsonElement* p = parent;
- while (p)
- {
- if (p->siblings)
- {
- stack.push(p->siblings);
- break;
- }
- p = p->parent;
- }
- }
- if (stack.getSize())
- {
- EditableJsonElement* next = stack.pop();
- while (true)
- {
- if (next->siblings)
- {
- stack.push(siblings);
- }
- if (next->children)
- {
- stack.push(children);
- }
- if (!stack.getSize() && next != end)
- {
- EditableJsonElement* p = next->parent;
- while (p)
- {
- if (p->siblings)
- {
- stack.push(p->siblings);
- break;
- }
- p = p->parent;
- }
- }
- if (next->parent)
- {
- next->parent->removeChild(next);
- }
- else
- {
- EditableJsonElement* p = this;
- while (p->parent)
- {
- p = p->parent;
- }
- while (p->siblings != next)
- {
- p = p->siblings;
- }
- p->siblings = 0;
- }
- toDelete.add(next);
- if (!stack.getSize())
- {
- next = 0;
- break;
- }
- if (next == end)
- {
- break;
- }
- next = stack.pop();
- }
- if (next == end)
- {
- result->append(next->content.getTeilText(endIndex));
- }
- for (EditableJsonElement* del : toDelete)
- {
- del->disconnect();
- del->release();
- }
- Array<EditableJsonElement*> afterList;
- while (stack.getSize())
- {
- afterList.add(stack.pop());
- }
- int p = 0;
- setContent(*result, p, afterList);
- }
- else
- {
- setContent(*result);
- result->release();
- return;
- }
- }
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zBefore(
- EditableJsonElement* zRoot, bool onlyVisible, int* lineCount)
- {
- if (this == zRoot)
- {
- return 0;
- }
- EditableJsonElement* parent = this->parent;
- EditableJsonElement* current = parent ? parent->children : zRoot;
- EditableJsonElement* last = parent;
- while (current)
- {
- if (current == this)
- {
- break;
- }
- last = current;
- current = current->siblings;
- }
- if (last && last->children != this && (!last->hidden || !onlyVisible))
- {
- current = last->lastChild;
- while (current)
- {
- last = current;
- if (current->children)
- {
- if ((!current->hidden || !onlyVisible))
- {
- current = current->lastChild;
- }
- else if (*lineCount)
- {
- EditableJsonElement* e = current->children;
- while (e)
- {
- int lc = 0;
- e->lineCount(true, false, 0, lc);
- *lineCount -= lc;
- e = e->siblings;
- }
- break;
- }
- }
- else
- {
- break;
- }
- }
- }
- else if (last && last->hidden && onlyVisible && lineCount)
- {
- EditableJsonElement* e = last->children;
- while (e)
- {
- int lc = 0;
- e->lineCount(true, false, 0, lc);
- *lineCount -= lc;
- e = e->siblings;
- }
- }
- return last;
- }
- EditableJsonElement* Framework::JSON::EditableJsonElement::zAfter(
- bool onlyVisible, int* lineCount)
- {
- EditableJsonElement* zElement = this;
- if (zElement->children)
- {
- if (!zElement->hidden || !onlyVisible)
- {
- return zElement->children;
- }
- else if (lineCount)
- {
- EditableJsonElement* e = zElement->children;
- while (e)
- {
- int lc = 0;
- e->lineCount(true, false, 0, lc);
- *lineCount += lc;
- e = e->siblings;
- }
- }
- }
- if (zElement->siblings)
- {
- return zElement->siblings;
- }
- while (zElement->parent)
- {
- zElement = zElement->parent;
- if (zElement->siblings)
- {
- return zElement->siblings;
- }
- }
- return 0;
- }
- JsonEditor::JsonEditor(UIInit uiInit)
- : ZeichnungHintergrund(),
- uiInit(uiInit)
- {
- valueValidator = Regex::parse("^-?[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$");
- validator = 0;
- content = 0;
- renderStart = {0, 0};
- renderStartLine = 0;
- lineCount = 0;
- cursorPos.x = -1;
- cursorPos.y = -1;
- textCursor = {0, 0};
- selectionStart = {0, 0};
- renderStartOffset = 0;
- selectionEnd = {0, 0};
- textRenderer = new TextRenderer();
- textRenderer->setSchriftSize(12);
- textRenderer->setZeilenAbstand(2);
- textRenderer->setZeichenAbstand(1);
- pressed = 0;
- time = 0;
- drag = 0;
- drawCursor = 0;
- dragSart = {-1, -1};
- pressedPos = {-1, -1};
- dragStartPos = {0, -1};
- timeSicePress = 0.0;
- lastClickCursorPos = {0, 0};
- tps = 0;
- renderings = 0;
- renderedLines = 0;
- renderStopLine = 0;
- errorDescription = uiInit.createTextFeld(uiInit.initParam);
- errorDescription->setStyle(TextFeld::Style::Text | TextFeld::Style::Center
- | TextFeld::Style::Rahmen
- | TextFeld::Style::Hintergrund
- | TextFeld::Style::HAlpha);
- errorDescription->removeStyle(TextFeld::Style::Sichtbar);
- errorDescription->setSchriftFarbe(0xFFFFFFFF);
- errorDescription->setRahmenFarbe(0xFFA0A0A0);
- errorDescription->setHintergrundFarbe(0xA0000000);
- hasSyntaxError = false;
- }
- JsonEditor::~JsonEditor()
- {
- if (content) content->release();
- if (validator) validator->release();
- textRenderer->release();
- errorDescription->release();
- }
- void Framework::JSON::JsonEditor::doMausEreignis(MausEreignis& me, bool userRet)
- {
- LOCK(&cs);
- rend |= cursorPos.x != me.mx || cursorPos.y != me.my;
- cursorPos.x = me.mx;
- cursorPos.y = me.my;
- if (me.id == ME_RLinks)
- {
- pressedPos = cursorPos;
- if (timeSicePress < 0.5)
- {
- if (lastClickCursorPos.line == textCursor.line
- && lastClickCursorPos.column == textCursor.column
- && lastClickCursorPos.line && lastClickCursorPos.column > 0)
- {
- EditableJsonElement* current = textCursor.line;
- int start = 0;
- int end = 0;
- current->getWordBounds(textCursor.column, &start, &end);
- selectionStart = {current, start};
- selectionEnd = {current, end};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- }
- }
- lastClickCursorPos = textCursor;
- pressed = true;
- drag = false;
- rend = 1;
- time = 0;
- timeSicePress = 0.0;
- }
- if (me.id == ME_PLinks || (me.id == ME_Betritt && getMausStand(M_Links)))
- {
- if (me.mx >= getInnenBreite() - 15)
- {
- int line = (int)(me.my / ((double)getInnenHeight() / lineCount));
- if (line >= lineCount)
- {
- line = lineCount - 1;
- }
- scrollToLine(line + 1, Center);
- }
- if (!drag)
- {
- drag = true;
- textCursor = getScreenPosition(cursorPos.x, cursorPos.y);
- selectionStart = textCursor;
- selectionEnd = textCursor;
- dragSart = cursorPos;
- dragStartPos = textCursor;
- rend = 1;
- time = 0;
- }
- }
- if (me.id == ME_Bewegung)
- {
- if (drag)
- {
- if (dragSart.x >= getInnenBreite() - 15)
- {
- int line
- = (int)(me.my / ((double)getInnenHeight() / lineCount));
- if (line >= lineCount)
- {
- line = lineCount - 1;
- }
- scrollToLine(line + 1, Center);
- }
- else
- {
- EditorPosition pos
- = getScreenPosition(cursorPos.x, cursorPos.y);
- if (pos.line == dragStartPos.line)
- {
- if (pos.column < dragStartPos.column)
- {
- selectionStart = pos;
- selectionEnd = dragStartPos;
- }
- else if (pos.column > dragStartPos.column)
- {
- selectionStart = dragStartPos;
- selectionEnd = pos;
- }
- }
- else
- {
- if (cursorPos.y < dragSart.y)
- {
- selectionStart = pos;
- selectionEnd = dragStartPos;
- }
- else if (cursorPos.y > dragSart.y)
- {
- selectionStart = dragStartPos;
- selectionEnd = pos;
- }
- }
- textCursor = pos;
- }
- }
- }
- if (me.id == ME_UScroll)
- {
- if (renderStart.column > 0)
- {
- const char* content = renderStart.line->getContent();
- int index = renderStart.column - 2;
- while (index > 0 && content[index] != '\n')
- {
- index--;
- }
- if (content[index] == '\n')
- {
- renderStart.column = index + 1;
- rend = 1;
- renderStartLine--;
- unifyPosition(renderStart);
- return;
- }
- }
- while (true)
- {
- EditableJsonElement* next
- = renderStart.line->zBefore(content, true, &renderStartLine);
- if (next)
- {
- renderStart.line = next;
- const char* content = next->getContent();
- int index = next->getContent().getLength() - 1;
- while (index > 0 && content[index] != '\n')
- {
- index--;
- }
- if (content[index] == '\n')
- {
- renderStart.column = index + 1;
- rend = 1;
- renderStartLine--;
- unifyPosition(renderStart);
- return;
- }
- }
- else
- {
- renderStart.column = 0;
- rend = 1;
- renderStartLine = 1;
- return;
- }
- }
- }
- if (me.id == ME_DScroll)
- {
- const char* content = renderStart.line->getContent();
- int length = renderStart.line->getContent().getLength();
- int index = renderStart.column;
- while (index < length && content[index] != '\n')
- {
- index++;
- }
- if (content[index] == '\n')
- {
- renderStart.column = index + 1;
- rend = 1;
- renderStartLine++;
- unifyPosition(renderStart);
- return;
- }
- while (true)
- {
- EditableJsonElement* next
- = renderStart.line->zAfter(true, &renderStartLine);
- if (next)
- {
- renderStart.line = next;
- const char* content = next->getContent();
- int length = next->getContent().getLength();
- int index = 0;
- while (index < length && content[index] != '\n')
- {
- index++;
- }
- if (content[index] == '\n')
- {
- renderStart.column = index + 1;
- rend = 1;
- renderStartLine++;
- unifyPosition(renderStart);
- return;
- }
- }
- else
- {
- return;
- }
- }
- }
- }
- EditorPosition Framework::JSON::JsonEditor::getScreenPosition(
- int localX, int localY)
- {
- if (!renderStart.line) return {0, 0};
- int y = 0;
- int lineNumberWidth = 0;
- for (int i = lineCount; i > 0; i /= 10)
- {
- lineNumberWidth++;
- }
- lineNumberWidth = lineNumberWidth * textRenderer->getMaxCharWidth()
- + textRenderer->getZeichenAbstand() * (lineNumberWidth - 1);
- int x = lineNumberWidth + 26;
- EditableJsonElement* current = renderStart.line;
- int index = renderStart.column;
- EditableJsonElement* last = current;
- while (y < gr.y && current)
- {
- int length = current->getContent().getLength();
- const char* content = current->getContent();
- for (int i = index; i < length; i++)
- {
- if (y >= localY - textRenderer->getZeilenHeight()
- - textRenderer->getZeilenAbstand()
- && x >= localX - textRenderer->getCharWidth(content[i]) / 2
- - textRenderer->getZeichenAbstand())
- {
- EditorPosition result = {current, i};
- unifyPosition(result);
- return result;
- }
- if (content[i] == '\n')
- {
- if (y >= localY - textRenderer->getZeilenHeight()
- - textRenderer->getZeilenAbstand())
- {
- EditorPosition result = {current, i};
- unifyPosition(result);
- return result;
- }
- y += textRenderer->getZeilenHeight()
- + textRenderer->getZeilenAbstand();
- x = lineNumberWidth + 26;
- }
- else
- {
- x += textRenderer->getCharWidth(content[i])
- + textRenderer->getZeichenAbstand();
- }
- }
- last = current;
- current = current->zAfter(true, 0);
- index = 0;
- }
- return {last, last->getContent().getLength()};
- }
- void Framework::JSON::JsonEditor::deleteSelection()
- {
- if (selectionStart.line && selectionEnd.line)
- {
- selectionStart.line->removeUntil(
- selectionStart.column, selectionEnd.line, selectionEnd.column);
- selectionEnd = selectionStart;
- textCursor = selectionStart;
- fixTree(selectionStart.line);
- if (dragStartPos.line)
- {
- dragStartPos = selectionStart;
- }
- if (lastClickCursorPos.line)
- {
- lastClickCursorPos = selectionStart;
- }
- }
- }
- void Framework::JSON::JsonEditor::unifyPosition(EditorPosition& pos)
- {
- while (pos.line && pos.column >= pos.line->getContent().getLength())
- {
- if (pos.line->zFirstChildren() && pos.line->isVisible())
- {
- pos = {pos.line->zFirstChildren(),
- pos.column - pos.line->getContent().getLength()};
- }
- else if (pos.line->zMextSibling())
- {
- pos = {pos.line->zMextSibling(),
- pos.column - pos.line->getContent().getLength()};
- }
- else
- {
- EditableJsonElement* p = pos.line->zParent();
- while (p)
- {
- if (p->zMextSibling())
- {
- pos = {p->zMextSibling(), 0};
- break;
- }
- p = p->zParent();
- }
- if (!p)
- {
- pos.column = pos.line->getContent().getLength();
- break;
- }
- }
- }
- }
- void Framework::JSON::JsonEditor::fixTree(EditableJsonElement* zElement)
- {
- EditableJsonElement* before = zElement->zBefore(content, false, 0);
- int beforeLength = before ? before->getContent().getLength() : 0;
- if (zElement->hasError() && before)
- {
- Text content = before->getContent();
- before->setContent(content);
- if (before->getContent().getLength() != beforeLength)
- {
- before->makeVisible();
- }
- }
- if (textCursor.line == zElement)
- {
- textCursor.column += beforeLength;
- textCursor.line = before ? before : zElement;
- unifyPosition(textCursor);
- }
- if (renderStart.line == zElement)
- {
- renderStart.column += beforeLength;
- renderStart.line = before ? before : zElement;
- unifyPosition(renderStart);
- }
- }
- void Framework::JSON::JsonEditor::setFont(Schrift* schrift)
- {
- textRenderer->setSchriftZ(schrift);
- }
- void Framework::JSON::JsonEditor::setFontSize(int size)
- {
- textRenderer->setSchriftSize(size);
- textRenderer->setZeilenAbstand(size / 6);
- textRenderer->setZeichenAbstand(size / 8);
- }
- void JsonEditor::setContent(Text content)
- {
- if (this->content)
- {
- this->content->release();
- this->content = 0;
- this->renderStart = {0, 0};
- }
- this->content = new EditableJsonElement(
- dynamic_cast<Regex::Automata<char>*>(valueValidator->getThis()));
- content.ersetzen("\r", "");
- content.ersetzen("\t", " ");
- this->content->setContent(content);
- textCursor = {this->content, 0};
- selectionStart = {this->content, 0};
- selectionEnd = {this->content, 0};
- format();
- }
- void Framework::JSON::JsonEditor::setContent(JSONValue* content)
- {
- setContent(content->toString());
- content->release();
- }
- void Framework::JSON::JsonEditor::format()
- {
- if (content)
- {
- content->format();
- lineCount = 0;
- content->lineCount(true, true, 0, lineCount);
- }
- }
- void Framework::JSON::JsonEditor::setValidator(
- Validator::DataValidator* validator)
- {
- if (this->validator) this->validator->release();
- this->validator = validator;
- // if (content) validate(); TODO: validate attributes
- }
- void Framework::JSON::JsonEditor::doTastaturEreignis(TastaturEreignis& te)
- {
- LOCK(&cs);
- if (!textCursor.line)
- {
- return;
- }
- bool shift = getTastenStand(T_Shift);
- bool strg = getTastenStand(T_Strg);
- if (te.id == TE_Press)
- {
- switch (te.virtualKey)
- {
- case T_Tab:
- {
- Text illegalStarts = "[]{},\": ";
- if (shift)
- {
- bool lastStr
- = textCursor.line->getContent().getLength()
- > textCursor.column
- ? textCursor.line->getContent()[textCursor.column]
- == '"'
- : false;
- int nextColumn = textCursor.column - 1;
- EditableJsonElement* nextLine = textCursor.line;
- while (nextLine)
- {
- if (nextColumn < 0)
- {
- nextLine = nextLine->zBefore(content, true, 0);
- if (!nextLine)
- {
- return;
- }
- nextColumn = nextLine->getContent().getLength();
- }
- int start = 0;
- int end = 0;
- nextLine->getWordBounds(nextColumn, &start, &end);
- if ((start != end
- && !illegalStarts.hat(
- nextLine->getContent()[start]))
- || (lastStr
- && nextLine->getContent()[nextColumn] == '"'))
- {
- if (lastStr
- && nextLine->getContent()[nextColumn] == '"')
- {
- start = end;
- }
- if (selectionStart.column != start
- || selectionStart.line != nextLine
- || selectionEnd.column != end
- || selectionEnd.line != nextLine)
- {
- selectionStart = {nextLine, start};
- selectionEnd = {nextLine, end};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- scrollToLine(textCursor, Top);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- }
- lastStr = nextLine->getContent()[nextColumn] == '"';
- nextColumn--;
- }
- }
- else
- {
- bool lastStr
- = textCursor.line->getContent().getLength()
- > textCursor.column
- ? textCursor.line->getContent()[textCursor.column]
- == '"'
- : false;
- int nextColumn = textCursor.column + 1;
- EditableJsonElement* nextLine = textCursor.line;
- while (nextLine)
- {
- if (nextColumn > nextLine->getContent().getLength())
- {
- nextLine = nextLine->zAfter(true, 0);
- if (!nextLine)
- {
- return;
- }
- nextColumn = 0;
- }
- int start = 0;
- int end = 0;
- nextLine->getWordBounds(nextColumn, &start, &end);
- if (((start != end
- && !illegalStarts.hat(
- nextLine->getContent()[start]))
- || (lastStr
- && nextLine->getContent()[nextColumn]
- == '"'))
- && (selectionStart.column != start
- || selectionStart.line != nextLine
- || selectionEnd.column != end
- || selectionEnd.line != nextLine))
- {
- selectionStart = {nextLine, start};
- selectionEnd = {nextLine, end};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- scrollToLine(textCursor, Bottom);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- lastStr = nextLine->getContent()[nextColumn] == '"';
- nextColumn++;
- }
- }
- }
- return;
- case T_Entf:
- if (selectionStart.line == selectionEnd.line
- && selectionStart.column == selectionEnd.column)
- {
- if (textCursor.column
- < textCursor.line->getContent().getLength())
- {
- Text content = textCursor.line->getContent();
- content.remove(textCursor.column, textCursor.column + 1);
- textCursor.line->setContent(content);
- fixTree(textCursor.line);
- }
- }
- else
- {
- deleteSelection();
- }
- break;
- case T_BackSpace:
- if (selectionStart.line == selectionEnd.line
- && selectionStart.column == selectionEnd.column)
- {
- if (textCursor.column > 0)
- {
- Text content = textCursor.line->getContent();
- content.remove(textCursor.column - 1, textCursor.column);
- textCursor.line->setContent(content);
- textCursor.column--;
- fixTree(textCursor.line);
- }
- else
- {
- EditableJsonElement* before
- = textCursor.line->zBefore(content, false, 0);
- if (before)
- {
- before->makeVisible();
- Text content = before->getContent();
- content.remove(
- content.getLength() - 1, content.getLength());
- before->setContent(content);
- textCursor = {before, content.getLength()};
- fixTree(before);
- scrollToLine(textCursor, Top);
- }
- }
- }
- else
- {
- deleteSelection();
- }
- break;
- case T_Enter:
- {
- deleteSelection();
- Text content = textCursor.line->getContent();
- content.insert(textCursor.column, "\n");
- textCursor.column += 1;
- textCursor.line->setContent(content);
- fixTree(textCursor.line);
- scrollToLine(textCursor, Bottom);
- }
- break;
- case T_Links:
- {
- int nextColumn = textCursor.column - 1;
- EditableJsonElement* nextLine = textCursor.line;
- while (nextColumn < 0)
- {
- nextLine = textCursor.line->zBefore(content, true, 0);
- if (!nextLine)
- {
- return;
- }
- nextColumn = nextLine->getContent().getLength() - 1;
- }
- if (strg)
- {
- int start = 0;
- nextLine->getWordBounds(nextColumn, &start, 0);
- nextColumn = start;
- }
- if (shift)
- {
- if (textCursor.line == selectionStart.line
- && textCursor.column == selectionStart.column)
- {
- selectionStart = {nextLine, nextColumn};
- unifyPosition(selectionStart);
- textCursor = selectionStart;
- }
- else
- {
- selectionEnd = {nextLine, nextColumn};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- }
- }
- else
- {
- textCursor = {nextLine, nextColumn};
- unifyPosition(textCursor);
- selectionStart = textCursor;
- selectionEnd = textCursor;
- }
- scrollToLine(textCursor, Top);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- case T_Oben:
- {
- EditableJsonElement* current = textCursor.line;
- int count = 0;
- bool found = 0;
- int index = textCursor.column - 1;
- const char* content = current->getContent();
- while (current)
- {
- while (index < 0)
- {
- current = current->zBefore(this->content, true, 0);
- if (!current)
- {
- break;
- }
- content = current->getContent();
- index = current->getContent().getLength() - 1;
- }
- if (!current)
- {
- break;
- }
- if (content[index] == '\n')
- {
- if (found)
- {
- break;
- }
- found = 1;
- }
- if (!found)
- {
- count++;
- }
- index--;
- }
- if (!current)
- {
- break;
- }
- index++;
- while (current && count > 0)
- {
- while (index >= current->getContent().getLength())
- {
- current = current->zAfter(true, 0);
- if (!current)
- {
- break;
- }
- content = current->getContent();
- index = 0;
- }
- if (!current)
- {
- break;
- }
- if (content[index] == '\n')
- {
- break;
- }
- count--;
- index++;
- }
- if (!current)
- {
- break;
- }
- if (shift)
- {
- if (textCursor.line == selectionStart.line
- && textCursor.column == selectionStart.column)
- {
- selectionStart = {current, index};
- unifyPosition(selectionStart);
- textCursor = selectionStart;
- }
- else
- {
- selectionEnd = {current, index};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- }
- }
- else
- {
- textCursor = {current, index};
- unifyPosition(textCursor);
- selectionStart = textCursor;
- selectionEnd = textCursor;
- }
- scrollToLine(textCursor, Top);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- case T_Rechts:
- {
- int nextColumn = textCursor.column + 1;
- EditableJsonElement* nextLine = textCursor.line;
- if (nextColumn > nextLine->getContent().getLength())
- {
- nextLine = textCursor.line->zAfter(true, 0);
- if (!nextLine)
- {
- return;
- }
- nextColumn = 0;
- }
- if (strg)
- {
- int end = 0;
- nextLine->getWordBounds(nextColumn, 0, &end);
- nextColumn = end;
- }
- if (shift)
- {
- if (textCursor.line == selectionEnd.line
- && textCursor.column == selectionEnd.column)
- {
- selectionEnd = {nextLine, nextColumn};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- }
- else
- {
- selectionStart = {nextLine, nextColumn};
- unifyPosition(selectionStart);
- textCursor = selectionStart;
- }
- }
- else
- {
- textCursor = {nextLine, nextColumn};
- unifyPosition(textCursor);
- selectionStart = textCursor;
- selectionEnd = textCursor;
- }
- scrollToLine(textCursor, Bottom);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- case T_Unten:
- {
- EditableJsonElement* current = textCursor.line;
- int count = 0;
- int index = textCursor.column - 1;
- const char* content = current->getContent();
- while (current)
- {
- while (index < 0)
- {
- current = current->zBefore(this->content, true, 0);
- if (!current)
- {
- break;
- }
- content = current->getContent();
- index = current->getContent().getLength() - 1;
- }
- if (!current)
- {
- break;
- }
- if (content[index] == '\n')
- {
- break;
- }
- count++;
- index--;
- }
- bool found = 0;
- current = textCursor.line;
- index = textCursor.column;
- content = current->getContent();
- while (current && (count > 0 || !found))
- {
- while (index >= current->getContent().getLength())
- {
- current = current->zAfter(true, 0);
- if (!current)
- {
- break;
- }
- content = current->getContent();
- index = 0;
- }
- if (found)
- {
- count--;
- }
- if (content[index] == '\n')
- {
- if (found)
- {
- break;
- }
- found = 1;
- }
- index++;
- }
- if (shift)
- {
- if (textCursor.line == selectionEnd.line
- && textCursor.column == selectionEnd.column)
- {
- selectionEnd = {current, index};
- unifyPosition(selectionEnd);
- textCursor = selectionEnd;
- }
- else
- {
- selectionStart = {current, index};
- unifyPosition(selectionStart);
- textCursor = selectionStart;
- }
- }
- else
- {
- textCursor = {current, index};
- unifyPosition(textCursor);
- selectionStart = textCursor;
- selectionEnd = textCursor;
- }
- scrollToLine(textCursor, Bottom);
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- return;
- }
- default:
- if (strg)
- {
- if (te.virtualKey == 'c' || te.virtualKey == 'C')
- {
- Text content = getSelectedContent();
- TextKopieren(content);
- return;
- }
- else if (te.virtualKey == 'x' || te.virtualKey == 'X')
- {
- Text content = getSelectedContent();
- TextKopieren(content);
- deleteSelection();
- scrollToLine(textCursor, Top);
- return;
- }
- else if (te.virtualKey == 'v' || te.virtualKey == 'V')
- {
- deleteSelection();
- EditableJsonElement* changed = textCursor.line;
- Text content = changed->getContent();
- const char* inserted = TextInsert();
- content.insert(textCursor.column, inserted);
- textCursor.column += textLength(inserted);
- unifyPosition(textCursor);
- scrollToLine(textCursor, Bottom);
- break;
- }
- else if (te.virtualKey == 'a' || te.virtualKey == 'A')
- {
- selectionStart = {content, 0};
- EditableJsonElement* element = content;
- bool first = true;
- while (element->zMextSibling())
- {
- element = element->zMextSibling();
- }
- while (element->zLastChildren())
- {
- element = element->zLastChildren();
- }
- selectionEnd = {element, element->getContent().getLength()};
- textCursor = selectionEnd;
- te.verarbeitet = true;
- time = 0;
- rend = 1;
- scrollToLine(textCursor, Bottom);
- return;
- }
- else if (te.virtualKey == 'f' || te.virtualKey == 'F')
- {
- format();
- return;
- }
- }
- if (istSchreibbar(te.taste[0]))
- {
- deleteSelection();
- Text content = textCursor.line->getContent();
- content.insert(textCursor.column, te.taste);
- textCursor.column += textLength(te.taste);
- textCursor.line->setContent(content);
- fixTree(textCursor.line);
- }
- else
- {
- return;
- }
- }
- selectionStart = textCursor;
- selectionEnd = textCursor;
- te.verarbeitet = true;
- lineCount = 0;
- content->lineCount(true, true, 0, lineCount);
- }
- time = 0;
- rend = 1;
- }
- bool Framework::JSON::JsonEditor::tick(double tickVal)
- {
- LOCK(&cs);
- time += tickVal;
- timeSicePress += tickVal;
- if (time > 1.0)
- {
- tps = renderings / time;
- time = 0.0;
- renderings = 0;
- }
- rend |= drawCursor != (time < 0.5);
- drawCursor = time < 0.5;
- errorDescription->tick(tickVal);
- return ZeichnungHintergrund::tick(tickVal);
- }
- void Framework::JSON::JsonEditor::render(Bild& rObj)
- {
- LOCK(&cs);
- renderings++;
- renderedLines = 0;
- errorDescription->removeStyle(TextFeld::Style::Sichtbar);
- ZeichnungHintergrund::render(rObj);
- if (textRenderer->zSchrift() && content
- && rObj.setDrawOptions(
- pos + Punkt(getRahmenBreite(), getRahmenBreite()),
- Punkt(getInnenBreite(), getInnenHeight())))
- {
- if (!renderStart.line)
- {
- renderStart = {content, 0};
- renderStartLine = 1;
- }
- int y = 0;
- int lineNumberWidth = 0;
- for (int i = lineCount; i > 0; i /= 10)
- {
- lineNumberWidth++;
- }
- lineNumberWidth
- = lineNumberWidth * textRenderer->getMaxCharWidth()
- + textRenderer->getZeichenAbstand() * (lineNumberWidth - 1);
- bool selected = false;
- EditableJsonElement* element = content;
- while (element)
- {
- if (element == selectionStart.line)
- {
- if (element != renderStart.line)
- {
- selected = true;
- }
- else
- {
- if (selectionStart.column < renderStart.column)
- {
- selected = true;
- }
- }
- }
- if (element == selectionEnd.line)
- {
- if (element != renderStart.line)
- {
- selected = false;
- break;
- }
- else
- {
- if (selectionEnd.column < renderStart.column)
- {
- selected = false;
- }
- }
- }
- if (element == renderStart.line)
- {
- break;
- }
- element = element->zAfter(false, 0);
- }
- int line = renderStartLine;
- int x = lineNumberWidth + 26;
- EditableJsonElement* current = renderStart.line;
- EditableJsonElement* highlightStop = 0;
- int index = renderStart.column;
- bool treeBranchRendered = false;
- bool highlighted = false;
- int numberWidth = textRenderer->getTextBreite(Text(line));
- textRenderer->renderText(
- 5 + lineNumberWidth - numberWidth, y, Text(line), rObj, 0xFF707070);
- bool whiteSpaceOnly = true;
- while (y < gr.y && current)
- {
- const Text& content = current->getContent();
- int column = index;
- for (int i = index; i < content.getLength() && y < gr.y;
- i++, column++)
- {
- if (selectionStart.line == current
- && selectionStart.column == i)
- {
- selected = true;
- }
- if (selectionEnd.line == current && selectionEnd.column == i)
- {
- selected = false;
- }
- int color = current->getColor(i);
- int cursorX = x - 1;
- if (textCursor.line == current && textCursor.column == i
- && drawCursor)
- {
- rObj.drawLinieV(
- cursorX, y, textRenderer->getSchriftSize(), 0xFFC0C0C0);
- }
- if (content[i] == '\n')
- {
- column = -1;
- highlighted = false;
- if (!treeBranchRendered)
- {
- // | in tree view
- rObj.drawLinieV(lineNumberWidth + 13,
- y
- - (line > 1 ? textRenderer->getSchriftSize() / 6
- : 0),
- textRenderer->getSchriftSize()
- + (line > 1 ? textRenderer->getSchriftSize() / 6
- : 0),
- 0xFF808080);
- if (highlightStop)
- {
- // hover effect in tree view
- rObj.fillRegion(lineNumberWidth + 10,
- y - textRenderer->getSchriftSize() / 6,
- 7,
- textRenderer->getSchriftSize()
- + textRenderer->getSchriftSize() / 6,
- 0xFF505050);
- }
- }
- if (selected)
- {
- rObj.fillRegion(x,
- y,
- textRenderer->getTextBreite(" "),
- textRenderer->getZeilenHeight()
- + textRenderer->getZeilenAbstand(),
- 0xFF502020);
- }
- x = lineNumberWidth + 26;
- y += textRenderer->getZeilenHeight()
- + textRenderer->getZeilenAbstand();
- whiteSpaceOnly = true;
- line++;
- renderedLines++;
- treeBranchRendered = false;
- int numberWidth = textRenderer->getTextBreite(Text(line));
- textRenderer->renderText(5 + lineNumberWidth - numberWidth,
- y,
- Text(line),
- rObj,
- 0xFF707070);
- }
- else
- {
- textRenderer->renderChar(x,
- y,
- content[i],
- rObj,
- color,
- false,
- selected,
- 0xFF502020);
- }
- if (cursorPos.x > cursorX && cursorPos.x <= x
- && cursorPos.y >= y
- && cursorPos.y <= y + textRenderer->getZeilenHeight())
- {
- if (current->hasError(i))
- {
- const SyntaxError& error = current->getError(i);
- errorDescription->setText(errors[error.getErrorType()]);
- errorDescription->setSize(
- errorDescription->getNeededWidth() + 6,
- errorDescription->getNeededHeight() + 6);
- errorDescription->setPosition(
- cursorPos.x, cursorPos.y + 20);
- if (errorDescription->getX()
- + errorDescription->getBreite()
- > getInnenBreite())
- {
- errorDescription->setX(
- getInnenBreite() - errorDescription->getBreite()
- - 5);
- }
- if (errorDescription->getY()
- + errorDescription->getHeight()
- > getInnenHeight())
- {
- errorDescription->setY(
- getInnenHeight() - errorDescription->getHeight()
- - 5);
- }
- errorDescription->addStyle(TextFeld::Style::Sichtbar);
- }
- }
- if (column % 4 == 0 && content[i] == ' ' && whiteSpaceOnly)
- {
- rObj.drawLinieV(
- cursorX + 1 + textRenderer->getTextBreite(" ") / 2,
- y + 2,
- textRenderer->getSchriftSize() - 4,
- 0xFF353535);
- }
- whiteSpaceOnly &= content[i] == ' ' || content[i] == '\n';
- }
- if (selectionStart.line == current
- && selectionStart.column == content.getLength())
- {
- selected = true;
- }
- if (selectionEnd.line == current
- && selectionEnd.column == content.getLength())
- {
- selected = false;
- }
- if (textCursor.line == current
- && textCursor.column == content.getLength() && drawCursor)
- {
- rObj.drawLinieV(
- x - 1, y, textRenderer->getSchriftSize(), 0xFFC0C0C0);
- }
- if (current->zFirstChildren())
- {
- if (pressed && pressedPos.x >= lineNumberWidth + 10
- && pressedPos.x <= lineNumberWidth + 16
- && pressedPos.y
- >= y + textRenderer->getSchriftSize() / 2 - 4
- && pressedPos.y
- <= y + textRenderer->getSchriftSize() / 2 + 2)
- {
- pressed = false;
- current->setHidden(!current->isHidden());
- }
- if (cursorPos.x >= lineNumberWidth + 10
- && cursorPos.x <= lineNumberWidth + 16
- && cursorPos.y >= y + textRenderer->getSchriftSize() / 2 - 4
- && cursorPos.y <= y + textRenderer->getSchriftSize() / 2 + 2
- && !current->isHidden())
- {
- highlightStop = current->zLastChildren();
- }
- if (current->isHidden())
- {
- if (!treeBranchRendered)
- {
- rObj.fillRegion(lineNumberWidth + 10,
- y + textRenderer->getSchriftSize() / 2 - 4,
- 6,
- 6,
- 0xFF000000);
- rObj.drawLinie(
- Punkt(lineNumberWidth + 10,
- y + textRenderer->getSchriftSize() / 2 - 4),
- Punkt(lineNumberWidth + 16,
- y + textRenderer->getSchriftSize() / 2 - 1),
- 0xFF808080);
- rObj.drawLinie(
- Punkt(lineNumberWidth + 10,
- y + textRenderer->getSchriftSize() / 2 + 2),
- Punkt(lineNumberWidth + 16,
- y + textRenderer->getSchriftSize() / 2 - 1),
- 0xFF808080);
- }
- for (char c : " ... ")
- {
- textRenderer->renderChar(x,
- y,
- c,
- rObj,
- 0xFF505050,
- false,
- selected,
- 0xFF502020);
- }
- if (current->getOpeningControllChar() == '{')
- {
- textRenderer->renderChar(x,
- y,
- '}',
- rObj,
- 0xFF505050,
- false,
- selected,
- 0xFF502020);
- }
- else if (current->getOpeningControllChar() == '[')
- {
- textRenderer->renderChar(x,
- y,
- ']',
- rObj,
- 0xFF505050,
- false,
- selected,
- 0xFF502020);
- }
- }
- else
- {
- if (!treeBranchRendered)
- {
- rObj.fillRegion(lineNumberWidth + 10,
- y + textRenderer->getSchriftSize() / 2 - 4,
- 6,
- 6,
- 0xFF000000);
- rObj.drawLinie(
- Punkt(lineNumberWidth + 10,
- y + textRenderer->getSchriftSize() / 2 - 4),
- Punkt(lineNumberWidth + 13,
- y + textRenderer->getSchriftSize() / 2 + 2),
- 0xFF808080);
- rObj.drawLinie(
- Punkt(lineNumberWidth + 16,
- y + textRenderer->getSchriftSize() / 2 - 4),
- Punkt(lineNumberWidth + 13,
- y + textRenderer->getSchriftSize() / 2 + 2),
- 0xFF808080);
- }
- }
- treeBranchRendered = true;
- }
- if (!current->zMextSibling() && current->zParent())
- {
- // |_ in tree view
- rObj.drawLinieH(lineNumberWidth + 14,
- y + textRenderer->getSchriftSize() - 1,
- 3,
- 0xFF808080);
- }
- rObj.drawLinieV(x,
- y,
- textRenderer->getSchriftSize(),
- 0xFF30C030); // TODO: debug tree seperator
- if (current == highlightStop)
- {
- highlightStop = 0;
- if (!treeBranchRendered)
- {
- // hover effect in tree view
- rObj.fillRegion(lineNumberWidth + 10,
- y - textRenderer->getSchriftSize() / 6,
- 7,
- textRenderer->getSchriftSize()
- + textRenderer->getSchriftSize() / 6,
- 0xFF505050);
- highlighted = true;
- }
- }
- current = current->zAfter(true, &line);
- index = 0;
- }
- if (!treeBranchRendered && !highlighted)
- {
- // | in tree view
- rObj.drawLinieV(lineNumberWidth + 13,
- y - (line > 1 ? textRenderer->getSchriftSize() / 6 : 0),
- textRenderer->getSchriftSize()
- + (line > 1 ? textRenderer->getSchriftSize() / 6 : 0),
- 0xFF808080);
- }
- EditableJsonElement* resnderStopElement = current;
- renderStopLine = line;
- textRenderer->renderText(5,
- y + textRenderer->getZeilenHeight()
- + textRenderer->getZeilenAbstand(),
- Text("FPS: ") + Text(tps),
- rObj,
- 0xFFFFFFFF);
- bool visible = false;
- double sy = 0.0;
- double yOffset = (double)getInnenHeight() / lineCount;
- current = content;
- EditableJsonElement* hiddenStop = 0;
- while (current)
- {
- if (hiddenStop == current)
- {
- hiddenStop = 0;
- }
- if (current == renderStart.line)
- {
- visible = true;
- }
- if (current == resnderStopElement)
- {
- visible = false;
- }
- int f = 0xFF303030;
- if (visible)
- {
- f = 0xFFA0A0A0;
- }
- if (hiddenStop)
- {
- f = 0xFF505050;
- }
- if (current->hasError())
- {
- f = 0xFFFF0000;
- }
- double size = current->lineCount() * yOffset;
- if ((int)(sy + size) > (int)sy || current->hasError())
- {
- rObj.fillRegion(getInnenBreite() - 15,
- (int)sy,
- 15,
- (int)(sy + MAX(yOffset, 1)),
- f);
- }
- if (current->isHidden())
- {
- if (!hiddenStop)
- {
- hiddenStop = current->zAfter(true, 0);
- }
- }
- current = current->zAfter(false, 0);
- sy += size;
- }
- errorDescription->render(rObj);
- rObj.releaseDrawOptions();
- }
- }
- Text Framework::JSON::JsonEditor::getContent()
- {
- return content ? content->getRecursiveContent() : Text("");
- }
- Text Framework::JSON::JsonEditor::getSelectedContent()
- {
- Text result = "";
- if (selectionStart.line && selectionEnd.line)
- {
- if (selectionStart.line == selectionEnd.line)
- {
- result.append(selectionStart.line->getContent().getTeilText(
- selectionStart.column, selectionEnd.column));
- }
- else
- {
- result.append(selectionStart.line->getContent().getTeilText(
- selectionStart.column,
- selectionStart.line->getContent().getLength()));
- Stack<EditableJsonElement*> stack(0);
- stack.push(selectionStart.line);
- while (stack.getSize())
- {
- EditableJsonElement* current = stack.pop();
- if (current->zMextSibling())
- {
- stack.push(current->zMextSibling());
- }
- else if (stack.getSize() == 0 && current->zParent())
- {
- EditableJsonElement* parent = current->zParent();
- while (parent)
- {
- if (parent->zMextSibling())
- {
- stack.push(current->zParent()->zMextSibling());
- break;
- }
- parent = parent->zParent();
- }
- }
- if (current->zFirstChildren())
- {
- stack.push(current->zFirstChildren());
- }
- if (current == selectionEnd.line)
- {
- break;
- }
- if (current != selectionStart.line)
- {
- result += current->getContent();
- }
- }
- result.append(selectionEnd.line->getContent().getTeilText(
- 0, selectionEnd.column));
- }
- }
- return result;
- }
- JSONValue* Framework::JSON::JsonEditor::getValidContent()
- {
- return nullptr; // TODO
- }
- void Framework::JSON::JsonEditor::scrollToLine(int line, ScrollTargetPos pos)
- {
- if (pos == Top || pos == Bottom)
- {
- if (line >= renderStartLine && line < renderStopLine)
- {
- return; // line is already visible
- }
- }
- EditableJsonElement* element = content;
- if (line == 1)
- {
- scrollToLine(line, {content, 0}, pos);
- return;
- }
- int l = 1;
- int column = 0;
- while (element)
- {
- int lineCount = element->lineCount();
- if (lineCount + l >= line)
- {
- column = element->getContent().positionVon('\n', line - l - 1) + 1;
- break;
- }
- l += lineCount;
- EditableJsonElement* tmp = element->zAfter(true, &l);
- if (l >= line)
- {
- column = element->getContent().positionVon('\n', lineCount - 1) + 1;
- break;
- }
- element = tmp;
- }
- EditorPosition target = {element, column};
- unifyPosition(target);
- scrollToLine(line, target, pos);
- }
- void Framework::JSON::JsonEditor::scrollToLine(
- EditorPosition target, ScrollTargetPos pos)
- {
- if (!target.line || !target.line->isVisible())
- {
- return;
- }
- int lineNumber = 0;
- if (!content->lineCount(true, true, target.line, lineNumber))
- {
- Text* part = target.line->getContent().getTeilText(0, target.column);
- lineNumber += part->anzahlVon('\n');
- part->release();
- if (pos == Top || pos == Bottom)
- {
- if (lineNumber >= renderStartLine && lineNumber < renderStopLine)
- {
- return; // line is already visible
- }
- }
- scrollToLine(lineNumber, target, pos);
- }
- }
- void Framework::JSON::JsonEditor::scrollToLine(
- int lineNum, EditorPosition target, ScrollTargetPos pos)
- {
- if (!target.line || !target.line->isVisible())
- {
- return;
- }
- if (pos == Top || pos == Bottom)
- {
- if (lineNum >= renderStartLine && lineNum < renderStopLine)
- {
- return; // line is already visible
- }
- }
- if (pos == Top)
- {
- renderStart = target;
- const char* content = renderStart.line->getContent();
- while (
- renderStart.column > 0 && content[renderStart.column - 1] != '\n')
- {
- renderStart.column--;
- }
- renderStartLine = lineNum;
- }
- else
- {
- int linesUntilStart
- = pos == Bottom ? renderedLines - 1 : renderedLines / 2 - 1;
- if (linesUntilStart >= lineNum)
- {
- renderStart = {content, 0};
- renderStartLine = 1;
- return;
- }
- EditableJsonElement* element = target.line;
- EditableJsonElement* before = element;
- while (linesUntilStart >= 0)
- {
- if (!before)
- {
- break;
- }
- element = before;
- int newLines = 0;
- if (element == target.line)
- {
- Text* part
- = element->getContent().getTeilText(0, target.column);
- newLines = part->anzahlVon('\n');
- part->release();
- }
- else
- {
- newLines = element->lineCount();
- }
- if (newLines > linesUntilStart)
- {
- renderStart = {element,
- element->getContent().positionVon(
- '\n', newLines - linesUntilStart - 1)
- + 1};
- unifyPosition(renderStart);
- renderStartLine = lineNum - linesUntilStart;
- return;
- }
- lineNum -= newLines;
- linesUntilStart -= newLines;
- before = element->zBefore(this->content, true, &lineNum);
- }
- renderStart = {element, 0};
- renderStartLine = lineNum;
- }
- }
|