Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / tools / leveldesign / georges_dll / action.cpp
blob520e2b2cf1aa3242b0a3a974367e3c929776b9fc
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdafx.h"
21 #include "georges_edit.h"
22 #include "georges_edit_doc.h"
23 #include "georges_edit_view.h"
24 #include "left_view.h"
26 #include "nel/georges/type.h"
27 #include "nel/georges/form_dfn.h"
28 #include "nel/georges/form_elm.h"
30 #include "action.h"
32 using namespace std;
33 using namespace NLMISC;
34 using namespace NLGEORGES;
36 #define _OldValue (_Value[0])
37 #define _NewValue (_Value[1])
39 // ***************************************************************************
41 IAction::IAction (TTypeAction type, uint selId, uint slot)
43 _Type = type;
44 _SelId = selId;
45 _Slot = slot;
48 // ***************************************************************************
50 void IAction::setLabel (const char *logLabel, CGeorgesEditDoc &doc)
52 _LogLabel = logLabel;
54 // New log present
55 _LogPresent[1] = true;
57 // Find log..
58 std::map<std::string, std::string>::iterator ite = doc._LastLogs.find (logLabel);
59 if (ite != doc._LastLogs.end ())
61 _LogPresent[0] = true;
62 _Log[0] = logLabel;
64 else
66 _LogPresent[0] = false;
70 // ***************************************************************************
72 bool IAction::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime)
74 uint index = (uint)redo;
75 doc.logValueChange (_LogLabel.c_str (), _Log[index].c_str (), _LogPresent[index]);
76 return true;
79 // ***************************************************************************
81 void IAction::update (bool updateLeftView, TUpdateRightView rightViewFlag, CGeorgesEditDoc &doc, const char *_FormName)
83 // Right and left view
84 CGeorgesEditView *rightView = doc.getRightView ();
85 nlassert (rightView);
86 CLeftView *leftView = doc.getLeftView ();
87 nlassert (leftView);
89 // Update left view ?
90 if (updateLeftView)
91 doc.updateDocumentStructure ();
93 // Set the current view..
94 uint subSelection = leftView->getCurrentSelectionId ();
95 if (subSelection != _SelId)
97 doc.changeSubSelection (_SelId, NULL);
98 return;
101 if (leftView->getCurrentSelectionId () == 1)
103 rightView->HeaderDialog.getFromDocument (*doc.getHeaderPtr ());
105 else if (doc.isType ())
107 rightView->TypeDialog.getFromDocument (*(doc.getTypePtr()));
109 else if (doc.isDfn ())
111 rightView->DfnDialog.getFromDocument (*(doc.getDfnPtr()));
113 else if (doc.isForm ())
115 if (rightViewFlag == DoNothing)
118 else if (rightViewFlag == UpdateLabels)
120 rightView->FormDialog.updateLabels ();
122 else if (rightViewFlag == UpdateValues)
124 rightView->FormDialog.updateValues ();
126 else if (rightViewFlag == Redraw)
128 rightView->FormDialog.getFromDocument ();
133 // ***************************************************************************
135 CActionString::CActionString (IAction::TTypeAction type, const char *newValue, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot) : IAction (type, selId, slot)
137 // Set the new value
138 _NewValue = newValue;
139 _FormName = formName;
140 _Log[1] = newValue;
141 _UserData = userData;
143 // Backup old value
144 switch (_Type)
146 case TypeType:
148 CType *type = doc.getTypePtr ();
149 _OldValue = toString ((int)(type->Type));
150 setLabel ("Type Type", doc);
151 uint ttype;
152 fromString(newValue, ttype);
153 _Log[1] = type->getTypeName ((UType::TType)ttype);
155 break;
156 case TypeUI:
158 CType *type = doc.getTypePtr ();
159 _OldValue = toString ((int)(type->UIType));
160 setLabel ("Type UI", doc);
161 uint ttype;
162 fromString(newValue, ttype);
163 _Log[1] = type->getUIName ((CType::TUI)ttype);
165 break;
166 case TypeDefault:
168 CType *type = doc.getTypePtr ();
169 _OldValue = type->Default;
170 setLabel ("Type Default", doc);
172 break;
173 case TypeMin:
175 CType *type = doc.getTypePtr ();
176 _OldValue = type->Min;
177 setLabel ("Type Min", doc);
179 break;
180 case TypeMax:
182 CType *type = doc.getTypePtr ();
183 _OldValue = type->Max;
184 setLabel ("Type Max", doc);
186 break;
187 case TypeIncrement:
189 CType *type = doc.getTypePtr ();
190 _OldValue = type->Increment;
191 setLabel ("Type Increment", doc);
193 break;
194 case FormTypeValue:
195 case FormValue:
197 // Form
198 const NLGEORGES::CForm &form = *(doc.getFormPtr ());
199 nlverify (doc.getRootNode (_Slot)->getValueByName (_OldValue, formName, UFormElm::NoEval, NULL));
200 setLabel (formName, doc);
202 break;
203 case HeaderVersion:
205 CFileHeader *header = doc.getHeaderPtr ();
206 char versionText[512];
207 smprintf (versionText, 512, "Version %d.%d", header->MajorVersion, header->MinorVersion);
208 _OldValue = versionText;
209 setLabel ("Header Version", doc);
211 break;
212 case HeaderState:
214 CFileHeader *header = doc.getHeaderPtr ();
215 _OldValue = toString ((int)(header->State)).c_str ();
216 setLabel ("Header State", doc);
218 break;
219 case HeaderComments:
221 _OldValue = doc.getHeaderPtr ()->Comments;
222 setLabel ("Header Comments", doc);
224 break;
225 case FormArrayRename:
227 setLabel ((formName+string (" Renamed")).c_str (), doc);
228 int idInParent = atoi (_UserData.c_str ());
230 // Get the parent node
231 const CFormDfn *parentDfn;
232 uint indexDfn;
233 const CFormDfn *nodeDfn;
234 const CType *nodeType;
235 CFormElm *node;
236 UFormDfn::TEntryType type;
237 bool array;
238 bool vdfnArray;
239 CForm *form=doc.getFormPtr ();
240 CFormElm *elm = doc.getRootNode (slot);
241 nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
242 &nodeDfn, &nodeType, &node, type, array, vdfnArray, true, NLGEORGES_FIRST_ROUND) );
243 if (node)
245 CFormElmArray* array = safe_cast<CFormElmArray*> (node->getParent ());
246 _OldValue = array->Elements[idInParent].Name;
249 break;
250 case FormArrayInsert:
252 // do nothing
253 setLabel ("Array Insert", doc);
255 break;
256 default:
257 nlstop;
261 // ***************************************************************************
263 bool CActionString::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime)
265 IAction::doAction (doc, redo, modified, firstTime);
267 modified = false;
268 bool ok = true;
269 uint index = (uint)redo;
270 switch (_Type)
272 case TypeType:
274 CType *type = doc.getTypePtr ();
275 type->Type = (CType::TType)(atoi (_Value[index].c_str ()));
276 modified = true;
277 update (false, Redraw, doc, _FormName.c_str ());
279 break;
280 case TypeUI:
282 CType *type = doc.getTypePtr ();
283 type->UIType = (CType::TUI)(atoi (_Value[index].c_str ()));
284 modified = true;
285 update (false, Redraw, doc, _FormName.c_str ());
287 break;
288 case TypeDefault:
290 CType *type = doc.getTypePtr ();
291 type->Default = _Value[index];
292 modified = true;
293 if (!firstTime)
294 update (false, Redraw, doc, _FormName.c_str ());
296 break;
297 case TypeMin:
299 CType *type = doc.getTypePtr ();
300 type->Min = _Value[index];
301 modified = true;
302 if (!firstTime)
303 update (false, Redraw, doc, _FormName.c_str ());
305 break;
306 case TypeMax:
308 CType *type = doc.getTypePtr ();
309 type->Max = _Value[index];
310 modified = true;
311 if (!firstTime)
312 update (false, Redraw, doc, _FormName.c_str ());
314 break;
315 case TypeIncrement:
317 CType *type = doc.getTypePtr ();
318 type->Increment = _Value[index];
319 modified = true;
320 if (!firstTime)
321 update (false, Redraw, doc, _FormName.c_str ());
323 break;
324 case FormTypeValue:
325 case FormValue:
327 // Empty ?
328 if (!_Value[index].empty ())
330 // Get / create the node
331 const CFormDfn *parentDfn;
332 uint indexDfn;
333 const CFormDfn *nodeDfn;
334 const CType *nodeType;
335 CFormElm *node;
336 UFormDfn::TEntryType type;
337 bool array;
338 bool created;
339 CForm *form=doc.getFormPtr ();
340 CFormElm *elm = doc.getRootNode (_Slot);
341 nlverify ( elm->createNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
342 &nodeDfn, &nodeType, &node, type, array, created) );
343 nlassert (node);
345 // Set the atom value
346 CFormElmAtom *atom = safe_cast<CFormElmAtom*> (node);
347 atom->setValue (_Value[index].c_str ());
348 modified = true;
350 if (firstTime)
351 update (created, UpdateLabels, doc, _FormName.c_str ());
352 else
353 update (created, UpdateValues, doc, _FormName.c_str ());
355 else
357 if (FormTypeValue == _Type)
359 // Get the node
360 const CFormDfn *parentDfn;
361 uint indexDfn;
362 const CFormDfn *nodeDfn;
363 const CType *nodeType;
364 CFormElm *node;
365 UFormDfn::TEntryType type;
366 bool array;
367 bool parentVDnfArray;
368 CForm *form=doc.getFormPtr ();
369 CFormElm *elm = doc.getRootNode (_Slot);
370 nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
371 &nodeDfn, &nodeType, &node, type, array, parentVDnfArray, true, NLGEORGES_FIRST_ROUND) );
372 nlassert (node);
373 CFormElmAtom *atom = safe_cast<CFormElmAtom*> (node);
374 atom->setValue ("");
376 else
378 // Remove the node
379 const CFormDfn *parentDfn;
380 uint indexDfn;
381 const CFormDfn *nodeDfn;
382 const CType *nodeType;
383 CFormElm *node;
384 UFormDfn::TEntryType type;
385 bool array;
386 CForm *form=doc.getFormPtr ();
387 CFormElm *elm = doc.getRootNode (_Slot);
388 nlverify ( elm->deleteNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
389 &nodeDfn, &nodeType, &node, type, array) );
390 nlassert ((FormTypeValue == _Type)||(node == NULL));
393 modified = true;
395 update (true, UpdateValues, doc, _FormName.c_str ());
398 break;
399 case HeaderVersion:
401 uint v0, v1;
402 if (sscanf (_Value[index].c_str (), "Version %d.%d", &v0, &v1)==2)
404 CFileHeader *header = doc.getHeaderPtr ();
405 header->MajorVersion = v0;
406 header->MinorVersion = v1;
407 modified = true;
408 update (false, Redraw, doc, _FormName.c_str ());
411 break;
412 case HeaderState:
414 CFileHeader *header = doc.getHeaderPtr ();
415 header->State = (CFileHeader::TState)atoi (_Value[index].c_str ());
416 modified = true;
417 update (false, Redraw, doc, _FormName.c_str ());
419 break;
420 case HeaderComments:
422 doc.getHeaderPtr ()->Comments = _Value[index];
423 modified = true;
424 if (!firstTime)
425 update (false, Redraw, doc, _FormName.c_str ());
427 break;
428 case FormArrayRename:
430 int idInParent = atoi (_UserData.c_str ());
432 // Get the parent node
433 const CFormDfn *parentDfn;
434 uint indexDfn;
435 const CFormDfn *nodeDfn;
436 const CType *nodeType;
437 CFormElm *node;
438 UFormDfn::TEntryType type;
439 bool array;
440 bool vdfnArray;
441 CForm *form=doc.getFormPtr ();
442 CFormElm *elm = doc.getRootNode (_Slot);
443 nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
444 &nodeDfn, &nodeType, &node, type, array, vdfnArray, true, NLGEORGES_FIRST_ROUND) );
445 if (node)
447 CFormElmArray* array = safe_cast<CFormElmArray*> (node->getParent ());
448 array->Elements[idInParent].Name = _Value[index];
449 modified = true;
450 update (true, DoNothing, doc, _FormName.c_str ());
453 break;
454 case FormArrayInsert:
456 int idInParent = atoi (_NewValue.c_str ());
458 // Insert ?
459 if (redo)
461 // Get the parent node
462 const CFormDfn *parentDfn;
463 uint indexDfn;
464 const CFormDfn *nodeDfn;
465 const CType *nodeType;
466 CFormElm *parentNode;
467 UFormDfn::TEntryType type;
468 bool array;
469 CForm *form=doc.getFormPtr ();
470 CFormElm *elm = doc.getRootNode (_Slot);
471 nlverify ( elm->arrayInsertNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
472 &nodeDfn, &nodeType, &parentNode, type, array, true, idInParent) );
473 modified = true;
475 else
477 // Get the parent node
478 const CFormDfn *parentDfn;
479 uint indexDfn;
480 const CFormDfn *nodeDfn;
481 const CType *nodeType;
482 CFormElm *parentNode;
483 UFormDfn::TEntryType type;
484 bool array;
485 CForm *form=doc.getFormPtr ();
486 CFormElm *elm = doc.getRootNode (_Slot);
487 nlverify ( elm->arrayDeleteNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
488 &nodeDfn, &nodeType, &parentNode, type, array, true, idInParent) );
489 modified = true;
492 update (true, Redraw, doc, _FormName.c_str ());
494 break;
495 default:
496 nlstop;
499 return ok;
502 // ***************************************************************************
504 CActionStringVector::CActionStringVector (IAction::TTypeAction type, const std::vector<std::string> &stringVector, CGeorgesEditDoc &doc, const char *formName, uint selId, uint slot) : IAction (type, selId, slot)
506 // Set the new value
507 _FormName = formName;
508 _NewValue = stringVector;
510 // Backup old value
511 switch (_Type)
513 case DfnParents:
515 // Dfn
516 const NLGEORGES::CFormDfn &dfn = *(doc.getDfnPtr ());
518 // Add the parents
519 _OldValue.resize (dfn.getNumParent ());
520 uint parent;
521 for (parent=0; parent<dfn.getNumParent (); parent++)
523 // Add the label and value
524 _OldValue[parent] = dfn.getParentFilename (parent);
526 setLabel ("Dfn Parents", doc);
528 break;
529 case FormParents:
531 // Get the form
532 const NLGEORGES::CForm &form = *(doc.getFormPtr ());
534 // Resize old string array
535 _OldValue.resize (form.getParentCount ());
537 // For each parent
538 uint parent;
539 for (parent=0; parent<form.getParentCount (); parent++)
541 // Get the parent filename
542 _OldValue[parent] = form.getParentFilename (parent);
544 setLabel ("Form Parents", doc);
546 break;
547 /* case FormArrayReplace:
548 case FormArrayAppend:
550 // Get the form
551 const NLGEORGES::CForm &form = *(doc.getFormPtr ());
553 // Get the node
554 const CFormDfn *parentDfn;
555 uint indexDfn;
556 const CFormDfn *nodeDfn;
557 const CType *nodeType;
558 CFormElm *node;
559 UFormDfn::TEntryType type;
560 bool array;
561 bool parentVDfnArray;
562 CFormElm *elm = doc.getRootNode (slot);
563 nlverify ( elm->getNodeByName (formName, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true) );
565 // Get the atom
566 _OldValue.clear ();
567 if (node)
569 // Get the atom
570 CFormElmArray *arrayPtr = safe_cast<CFormElmArray*>(node);
572 uint size;
573 nlverify (arrayPtr->getArraySize (size));
574 _OldValue.resize (size);
575 uint elm;
576 for (elm=0; elm<_OldValue.size (); elm++)
578 if (arrayPtr->Elements[elm])
580 CFormElmAtom *atom = safe_cast<CFormElmAtom*>(arrayPtr->Elements[elm]);
581 atom->getValue (_OldValue[elm], false);
585 if (_Type == FormArrayReplace)
586 setLabel ("Form Array Replace", doc);
587 else
588 setLabel ("Form Array Append", doc);
590 break;*/
591 default:
592 nlstop;
596 // ***************************************************************************
598 bool CActionStringVector::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime)
600 IAction::doAction (doc, redo, modified, firstTime);
602 modified = false;
603 bool ok = true;
604 uint index = (uint)redo;
605 switch (_Type)
607 case DfnParents:
609 // Get document pointer
610 CFormDfn *dfn = doc.getDfnPtr ();
611 nlassert (dfn);
613 // Add the parents
614 dfn->setNumParent (_Value[index].size ());
616 uint parent;
617 for (parent=0; parent<_Value[index].size (); parent++)
621 // Set the parent
622 dfn->setParent (parent, doc.FormLoader, _Value[index][parent].c_str ());
624 modified = true;
626 catch (const Exception &e)
628 ok = false;
629 char message[512];
630 smprintf (message, 512, "Error while loading Dfn file (%s): %s", _Value[index][parent].c_str (), e.what());
631 theApp.outputError (message);
633 // Next parent
634 parent--;
637 modified = true;
638 if (!firstTime)
639 update (false, Redraw, doc, "");
641 break;
642 case FormParents:
644 // Get the form
645 NLGEORGES::CForm &form = *(doc.getFormPtr ());
647 // Remove parent
648 form.clearParents ();
650 // Get the result value
651 uint count = _Value[index].size ();
652 uint value;
653 for (value = 0; value<count; value++)
655 // Load the parent
656 if (!_Value[index].empty ())
658 // Try to load the form
659 NLMISC::CSmartPtr<CForm> parentForm = (CForm*)doc.FormLoader.loadForm (_Value[index][value].c_str ());
660 if (parentForm)
662 if ((&form) != parentForm)
664 // Check it is the same dfn
665 if (parentForm->Elements.FormDfn == form.Elements.FormDfn)
667 // This is the parent form selector
668 if (form.insertParent (value, _Value[index][value].c_str(), parentForm))
671 else
673 ok = false;
674 char msg[512];
675 smprintf (msg, 512, "Internal error while assign the form (%s) as parent.", _Value[index][value].c_str());
676 theApp.outputError (msg);
679 else
681 ok = false;
682 char msg[512];
683 smprintf (msg, 512, "The parent form (%s) doesn't use the same DFN than the current form.", _Value[index][value].c_str());
684 theApp.outputError (msg);
687 else
689 ok = false;
690 char msg[512];
691 smprintf (msg, 512, "Can't assign a form it self as parent.");
692 theApp.outputError (msg);
695 else
697 ok = false;
698 char msg[512];
699 smprintf (msg, 512, "Can't read the form %s.", _Value[index][value].c_str());
700 theApp.outputError (msg);
704 modified = true;
705 update (true, Redraw, doc, _FormName.c_str ());
707 break;
708 /*case FormArrayReplace:
709 case FormArrayAppend:
711 // Get the node
712 const CFormDfn *parentDfn;
713 uint indexDfn;
714 const CFormDfn *nodeDfn;
715 const CType *nodeType;
716 CFormElm *node;
717 UFormDfn::TEntryType type;
718 bool array;
719 bool parentVDfnArray;
720 CForm *form=doc.getFormPtr ();
721 CFormElm *elm = doc.getRootNode (slot);
722 nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true) );
724 // Is a type entry ?
725 if ((type == UFormDfn::EntryType) && array)
727 // Create the array
728 bool created;
729 nlverify ( elm->createNodeByName (_FormName.c_str (), &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, created) );
730 nlassert (node);
732 // Get the atom
733 CFormElmArray *arrayPtr = safe_cast<CFormElmArray*>(node);
735 // Replace ?
736 if (_Type == FormArrayReplace)
738 arrayPtr->clean ();
741 // For each element
742 uint arraySize = arrayPtr->Elements.size();
743 for (uint i=0; i<_Value[index].size (); i++)
745 // Name
746 char name[512];
747 smprintf (name, 512, "[%d]", i+arraySize);
749 // Create the atom node
750 nlverify ( arrayPtr->createNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, created) );
751 nlassert (node);
753 // Get the atom
754 CFormElmAtom *atom = safe_cast<CFormElmAtom*>(node);
756 // Set the value
757 atom->setValue (_Value[index][i].c_str());
760 modified = true;
761 update (true, Redraw, doc, _FormName.c_str ());
764 break;*/
767 return ok;
770 // ***************************************************************************
772 CActionStringVectorVector::CActionStringVectorVector (IAction::TTypeAction type, const std::vector<std::vector<std::string> > &stringVector,
773 CGeorgesEditDoc &doc, uint selId, uint slot) : IAction (type, selId, slot)
775 // Set the new value
776 _NewValue = stringVector;
778 // Backup old value
779 switch (_Type)
781 case DfnStructure:
783 // Dfn
784 const NLGEORGES::CFormDfn &dfn = *(doc.getDfnPtr ());
786 // Add the struct element
787 _OldValue.resize (dfn.getNumEntry ());
788 uint elm;
789 for (elm=0; elm<_OldValue.size (); elm++)
791 // Resize the entry
792 _OldValue[elm].resize (5);
794 // Add the label and value
795 _OldValue[elm][0] = dfn.getEntry (elm).getName ();
796 switch (elm, dfn.getEntry (elm).getType ())
798 case UFormDfn::EntryType:
799 _OldValue[elm][1] = dfn.getEntry (elm).getArrayFlag () ? "Type array" : "Type";
800 _OldValue[elm][4] = dfn.getEntry (elm).getFilenameExt ();
801 break;
802 case UFormDfn::EntryDfn:
803 _OldValue[elm][1] = dfn.getEntry (elm).getArrayFlag () ? "Dfn array" : "Dfn";
804 break;
805 case UFormDfn::EntryVirtualDfn:
806 _OldValue[elm][1] = "Virtual Dfn";
807 break;
809 _OldValue[elm][2] = dfn.getEntry (elm).getFilename ();
810 _OldValue[elm][3] = dfn.getEntry (elm).getDefault ();
812 setLabel ("Dfn Structure", doc);
814 break;
815 case TypePredef:
817 // Type
818 const NLGEORGES::CType &type = *(doc.getTypePtr ());
820 uint predef;
821 _OldValue.resize (type.Definitions.size());
822 for (predef=0; predef<_OldValue.size(); predef++)
824 // Add the label and value
825 _OldValue[predef].resize (2);
826 _OldValue[predef][0] = type.Definitions[predef].Label;
827 _OldValue[predef][1] = type.Definitions[predef].Value;
829 setLabel ("Type Predef", doc);
831 break;
835 // ***************************************************************************
837 bool CActionStringVectorVector::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime)
839 IAction::doAction (doc, redo, modified, firstTime);
841 modified = false;
842 bool ok = true;
843 uint index = (uint)redo;
845 // Backup old value
846 switch (_Type)
848 case DfnStructure:
850 // Dfn
851 NLGEORGES::CFormDfn &dfn = *(doc.getDfnPtr ());
853 // Add the entries
854 dfn.setNumEntry (_Value[index].size ());
855 uint elm;
856 for (elm=0; elm<_Value[index].size (); elm++)
858 // Ref on the entry
859 CFormDfn::CEntry &entry = dfn.getEntry (elm);
861 // Get the name
862 entry.setName (_Value[index][elm][0].c_str ());
864 // Get the filename
865 string &filename = _Value[index][elm][2];
867 // Get the type
868 string &type= _Value[index][elm][1];
869 if ((type == "Type") || (type == "Type array"))
871 // Set the type
872 entry.setType (doc.FormLoader, filename.c_str ());
874 // Set the default value
875 string &def = _Value[index][elm][3];
876 entry.setDefault (def.c_str ());
878 // Set the default extension
879 string &ext = _Value[index][elm][4];
880 entry.setFilenameExt (ext.c_str ());
882 else if ((type == "Dfn") || (type == "Dfn array"))
884 // Set the type
885 entry.setDfn (doc.FormLoader, filename.c_str ());
887 else if (type == "Virtual Dfn")
889 // Set the type
890 entry.setDfnPointer ();
892 entry.setArrayFlag ((type == "Type array") || (type == "Dfn array"));
894 modified = true;
895 if (!firstTime)
896 update (false, Redraw, doc, "");
898 break;
899 case TypePredef:
901 // Type
902 CType &type = *(doc.getTypePtr ());
904 // Add the predef
905 type.Definitions.resize (_Value[index].size ());
906 uint predef;
907 for (predef=0; predef<type.Definitions.size(); predef++)
909 // Add the label and value
910 type.Definitions[predef].Label = _Value[index][predef][0];
911 type.Definitions[predef].Value = _Value[index][predef][1];
913 modified = true;
914 if (!firstTime)
915 update (false, Redraw, doc, "");
917 break;
918 default:
919 nlstop;
922 return ok;
925 // ***************************************************************************
927 CActionBuffer::CActionBuffer (IAction::TTypeAction type, const uint8 *buffer, uint bufferSize, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot) : IAction (type, selId, slot)
929 // New value
930 _FormName = formName;
931 _UserData = userData;
933 // Backup old value
934 switch (_Type)
936 case FormPaste:
938 // Backup buffer
939 _NewValue.resize (bufferSize);
940 memcpy (&_NewValue[0], buffer, bufferSize);
942 // Serial formname in the memBuffer
943 nlverify (theApp.SerialIntoMemStream (formName, &doc, _Slot, false));
944 _OldValue.resize (theApp.MemStream.length());
945 memcpy (&_OldValue[0], theApp.MemStream.buffer (), theApp.MemStream.length());
946 setLabel (("formName"+string (" Pasted")).c_str (), doc);
948 break;
949 case FormArrayDelete:
951 // Serial formname in the memBuffer
952 nlverify (theApp.SerialIntoMemStream (formName, &doc, _Slot, false));
953 _OldValue.resize (theApp.MemStream.length());
954 memcpy (&_OldValue[0], theApp.MemStream.buffer (), theApp.MemStream.length());
955 setLabel (("formName"+string (" Deleted")).c_str (), doc);
957 break;
958 case FormArraySize:
960 // Serial formname in the memBuffer
961 nlverify (theApp.SerialIntoMemStream (formName, &doc, _Slot, false));
962 _OldValue.resize (theApp.MemStream.length());
963 memcpy (&_OldValue[0], theApp.MemStream.buffer (), theApp.MemStream.length());
964 setLabel (("formName"+string (" Resized")).c_str (), doc);
965 _Log[1] = _UserData;
967 break;
968 case FormVirtualDfnName:
970 // Serial formname in the memBuffer
971 nlverify (theApp.SerialIntoMemStream (formName, &doc, _Slot, false));
972 _OldValue.resize (theApp.MemStream.length());
973 memcpy (&_OldValue[0], theApp.MemStream.buffer (), theApp.MemStream.length());
974 setLabel (formName, doc);
975 _Log[1] = _UserData;
977 break;
978 default:
979 nlstop;
983 // ***************************************************************************
985 bool CActionBuffer::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime)
987 IAction::doAction (doc, redo, modified, firstTime);
989 modified = false;
990 bool ok = true;
991 uint index = (uint)redo;
993 // Backup old value
994 switch (_Type)
996 case FormPaste:
998 // Fill memstream with the new buffer
999 theApp.FillMemStreamWithBuffer (&_Value[index][0], _Value[index].size ());
1001 // Reserial the document
1002 nlverify (theApp.SerialFromMemStream (_FormName.c_str (), &doc, _Slot));
1003 modified = true;
1004 update (true, Redraw, doc, _FormName.c_str ());
1006 break;
1007 case FormArrayDelete:
1009 if (redo)
1011 // Get the parent node
1012 const CFormDfn *parentDfn;
1013 uint indexDfn;
1014 const CFormDfn *nodeDfn;
1015 const CType *nodeType;
1016 CFormElm *parentNode;
1017 UFormDfn::TEntryType type;
1018 bool array;
1019 CForm *form=doc.getFormPtr ();
1020 CFormElm *elm = doc.getRootNode (_Slot);
1021 nlverify ( elm->arrayDeleteNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1022 &nodeDfn, &nodeType, &parentNode, type, array, true, atoi (_UserData.c_str ())) );
1023 modified = true;
1025 else
1027 // Insert a node
1028 const CFormDfn *parentDfn;
1029 uint indexDfn;
1030 const CFormDfn *nodeDfn;
1031 const CType *nodeType;
1032 CFormElm *parentNode;
1033 UFormDfn::TEntryType type;
1034 bool array;
1035 CForm *form=doc.getFormPtr ();
1036 CFormElm *elm = doc.getRootNode (_Slot);
1037 nlverify ( elm->arrayInsertNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1038 &nodeDfn, &nodeType, &parentNode, type, array, true, atoi (_UserData.c_str ())) );
1040 // Paste the node
1042 // Fill memstream with the new buffer
1043 theApp.FillMemStreamWithBuffer (&_OldValue[0], _OldValue.size ());
1045 // Reserial the document
1046 nlverify (theApp.SerialFromMemStream (_FormName.c_str (), &doc, _Slot));
1047 modified = true;
1050 update (true, Redraw, doc, _FormName.c_str ());
1052 break;
1053 case FormArraySize:
1055 if (redo)
1057 // Get the size
1058 int size = 0;
1059 if ( _UserData.empty() || (sscanf (_UserData.c_str(), "%d", &size) == 1) )
1061 if (size < 0)
1062 size = 0;
1064 // Array exist ?
1065 if (size > 0)
1067 // Get / create the node
1068 const CFormDfn *parentDfn;
1069 uint indexDfn;
1070 const CFormDfn *nodeDfn;
1071 const CType *nodeType;
1072 CFormElm *node;
1073 UFormDfn::TEntryType type;
1074 bool array;
1075 bool created;
1076 CForm *form=doc.getFormPtr ();
1077 CFormElm *elm = doc.getRootNode (_Slot);
1078 nlverify ( elm->createNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1079 &nodeDfn, &nodeType, &node, type, array, created) );
1080 nlassert (node);
1082 // Get the array node
1083 CFormElmArray *arrayPtr = safe_cast<CFormElmArray*> (node);
1085 // Backup old size
1086 uint oldSize = arrayPtr->Elements.size ();
1088 // Erase old element
1089 uint i;
1090 for (i=size; i<oldSize; i++)
1092 // Delete the element
1093 if (arrayPtr->Elements[i].Element)
1094 delete arrayPtr->Elements[i].Element;
1097 // Resize the array
1098 arrayPtr->Elements.resize (size);
1100 // Insert element
1101 for (i=oldSize; i<(uint)size; i++)
1103 // Create empty sub node
1104 char index[512];
1105 smprintf (index, 512, "[%d]", i);
1106 nlverify ( arrayPtr->createNodeByName (index, &parentDfn, indexDfn,
1107 &nodeDfn, &nodeType, &node, type, array, created) );
1110 // Document modified
1111 modified = true;
1112 update (true, UpdateValues, doc, _FormName.c_str ());
1114 else
1116 // Remove the node
1117 const CFormDfn *parentDfn;
1118 uint indexDfn;
1119 const CFormDfn *nodeDfn;
1120 const CType *nodeType;
1121 CFormElm *node;
1122 UFormDfn::TEntryType type;
1123 bool array;
1124 CForm *form=doc.getFormPtr ();
1125 CFormElm *elm = doc.getRootNode (_Slot);
1126 nlverify ( elm->deleteNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1127 &nodeDfn, &nodeType, &node, type, array) );
1128 nlassert ( (node == NULL) || (node->getForm () != doc.getFormPtr ()) );
1130 // Document modified
1131 modified = true;
1132 update (true, UpdateValues, doc, _FormName.c_str ());
1136 else
1138 // Fill memstream with the new buffer
1139 theApp.FillMemStreamWithBuffer (&_OldValue[0], _OldValue.size ());
1141 // Reserial the document
1142 nlverify (theApp.SerialFromMemStream (_FormName.c_str (), &doc, _Slot));
1143 modified = true;
1144 update (true, UpdateValues, doc, _FormName.c_str ());
1147 break;
1148 case FormVirtualDfnName:
1150 if (redo)
1152 // Result ok ?
1153 if (!_UserData.empty())
1155 // Try to load the DFN
1156 CSmartPtr<CFormDfn> newDfn = doc.FormLoader.loadFormDfn (_UserData.c_str (), false);
1157 if (newDfn)
1159 // Get / create the node
1160 const CFormDfn *parentDfn;
1161 uint indexDfn;
1162 const CFormDfn *nodeDfn;
1163 const CType *nodeType;
1164 CFormElm *node;
1165 UFormDfn::TEntryType type;
1166 bool array;
1167 bool created;
1168 CForm *form=doc.getFormPtr ();
1169 CFormElm *elm = doc.getRootNode (_Slot);
1170 nlverify ( elm->createNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1171 &nodeDfn, &nodeType, &node, type, array, created) );
1172 nlassert (node);
1174 // Get the atom
1175 CFormElmVirtualStruct *vStruct = safe_cast<CFormElmVirtualStruct*> (node);
1177 // Assign it
1178 vStruct->DfnFilename = _UserData.c_str ();
1180 // Build the dfn
1181 vStruct->build (newDfn);
1182 modified = true;
1184 update (true, Redraw, doc, _FormName.c_str ());
1186 else
1188 ok = false;
1190 // Output error
1191 char msg[512];
1192 smprintf (msg, 512, "Can't read the dfn %s.", _UserData.c_str());
1193 theApp.outputError (msg);
1194 update (false, Redraw, doc, _FormName.c_str ());
1197 else
1199 // Delete the node
1200 const CFormDfn *parentDfn;
1201 uint indexDfn;
1202 const CFormDfn *nodeDfn;
1203 const CType *nodeType;
1204 CFormElm *node;
1205 UFormDfn::TEntryType type;
1206 bool array;
1207 CForm *form=doc.getFormPtr ();
1208 CFormElm *elm = doc.getRootNode (_Slot);
1209 nlverify ( elm->deleteNodeByName (_FormName.c_str (), &parentDfn, indexDfn,
1210 &nodeDfn, &nodeType, &node, type, array) );
1212 // Document is modified by this view
1213 modified = true;
1214 update (true, Redraw, doc, _FormName.c_str ());
1217 else
1219 // Fill memstream with the new buffer
1220 theApp.FillMemStreamWithBuffer (&_OldValue[0], _OldValue.size ());
1222 // Reserial the document
1223 nlverify (theApp.SerialFromMemStream (_FormName.c_str (), &doc, _Slot));
1224 modified = true;
1225 update (true, Redraw, doc, _FormName.c_str ());
1228 break;
1229 default:
1230 nlstop;
1233 return ok;
1236 // ***************************************************************************