Changeset 388 for cafu/trunk
- Timestamp:
- 09/20/11 21:18:12 (8 months ago)
- Location:
- cafu/trunk/CaWE
- Files:
-
- 12 modified
-
DialogInsp-EntityProps.cpp (modified) (1 diff)
-
GuiEditor/Commands/ModifyWindow.cpp (modified) (1 diff)
-
GuiEditor/Commands/Paste.cpp (modified) (1 diff)
-
GuiEditor/GuiDocument.cpp (modified) (4 diffs)
-
GuiEditor/GuiDocument.hpp (modified) (1 diff)
-
GuiEditor/WindowTree.cpp (modified) (1 diff)
-
GuiEditor/Windows/EditorWindow.cpp (modified) (2 diffs)
-
GuiEditor/Windows/EditorWindow.hpp (modified) (2 diffs)
-
LuaAux.cpp (modified) (1 diff)
-
LuaAux.hpp (modified) (1 diff)
-
MapEntity.cpp (modified) (1 diff)
-
ModelEditor/ObserverPattern.hpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
cafu/trunk/CaWE/DialogInsp-EntityProps.cpp
r285 r388 949 949 950 950 // Check Lua compatibility for entity names. 951 if (Key=="name" && !CheckLuaVarCompat(NewValue)) 952 { 953 wxMessageBox("Entity names must be valid Lua identifiers: They can be any combination of letters, digits and underscores that does not begin with a digit and is not a reserved Lua keyword.", "Error: Entity name is not a Lua identifier.", wxOK | wxICON_ERROR); 951 if (Key=="name" && !IsLuaIdentifier(NewValue)) 952 { 953 wxMessageBox("An entity name must be a string of letters, digits, and underscores that is\n" 954 "not beginning with a digit and is not a reserved Lua keyword or global variable.", 955 "Entity name is not a valid script identifier.", wxOK | wxICON_ERROR); 956 954 957 NotifySubjectChanged_Modified(MapDoc, MapElements, MEMD_ENTITY_PROPERTY_MODIFIED, ""); // Intentionally update also this dialog to restore previous property value. 955 958 return; -
cafu/trunk/CaWE/GuiEditor/Commands/ModifyWindow.cpp
r374 r388 115 115 { 116 116 m_OldString=m_Window->Name; 117 118 if (!GuiDocumentT::GetSibling(m_Window)->SetName(m_NewString)) 119 { 120 m_GuiDocument->UpdateAllObservers_Modified(m_Window, WMD_PROPERTY_CHANGED, m_PropertyName); // This is needed to reset the property grid correctly. 121 return false; 122 } 117 m_Window->Name=m_GuiDocument->CheckWindowName(m_NewString, GuiDocumentT::GetSibling(m_Window)); 123 118 } 124 119 else if (m_PropertyName=="BackMatName") -
cafu/trunk/CaWE/GuiEditor/Commands/Paste.cpp
r367 r388 86 86 m_Windows[WinNr]->Parent=m_NewParent; 87 87 m_NewParent->Children.PushBack(m_Windows[WinNr]); 88 89 // If the name of the window is not unique among its siblings, find a new unique name.90 GuiDocumentT::GetSibling(m_Windows[WinNr])->RepairNameUniqueness();91 88 } 92 89 -
cafu/trunk/CaWE/GuiEditor/GuiDocument.cpp
r386 r388 24 24 #include "../GameConfig.hpp" 25 25 #include "../EditorMaterialEngine.hpp" 26 #include "../LuaAux.hpp" 26 27 27 28 #include "GuiSys/GuiImpl.hpp" … … 76 77 else 77 78 { 78 m_Gui=new cf::GuiSys::GuiImplT("Win=gui:new('WindowT'); gui:SetRootWindow(Win); gui:showMouse(false); gui:setFocus(Win); Win:SetName(' Window'); Win:set(\"rect\", 0, 0, 640, 480);", true);79 m_Gui=new cf::GuiSys::GuiImplT("Win=gui:new('WindowT'); gui:SetRootWindow(Win); gui:showMouse(false); gui:setFocus(Win); Win:SetName('Root'); Win:set(\"rect\", 0, 0, 640, 480);", true); 79 80 80 81 m_GuiProperties=GuiPropertiesT(*m_Gui); … … 139 140 140 141 141 const ArrayT<cf::GuiSys::WindowT*>& GuiDocumentT::GetSelection() 142 { 143 return m_Selection; 144 } 145 146 147 // Recursively makes sure that the children of each window have unique names. 148 // Normally the other GUI editor code should make sure that that is always true, but right now it 149 // is possible to create violations of this constraint via drag-and-drop in the window hierarchy tree 150 // (can drop a window as a child of another window that already has a child with the same name). 151 static void CheckWindowNames(cf::GuiSys::WindowT* Window) 152 { 153 const std::string OldName=Window->Name; 154 155 GuiDocumentT::GetSibling(Window)->RepairNameUniqueness(); 156 157 if (Window->Name!=OldName) 158 GuiDocumentT::GetSibling(Window)->GetGuiDoc()->UpdateAllObservers_Modified(Window, WMD_PROPERTY_CHANGED, "Name"); 159 160 for (unsigned long ChildNr=0; ChildNr<Window->Children.Size(); ChildNr++) 161 CheckWindowNames(Window->Children[ChildNr]); 142 wxString GuiDocumentT::CheckWindowName(const wxString& TestName, EditorWindowT* Win) const 143 { 144 const wxString Name_ =CheckLuaIdentifier(TestName); 145 const cf::GuiSys::WindowT* Win_ =Win ? Win->GetDual() : NULL; 146 wxString NewName=Name_; 147 ArrayT<cf::GuiSys::WindowT*> AllChildren; 148 149 AllChildren.PushBack(m_RootWindow); 150 m_RootWindow->GetChildren(AllChildren, true); 151 152 while (true) 153 { 154 bool IsUnique=true; 155 156 for (unsigned long ChildNr=0; ChildNr<AllChildren.Size(); ChildNr++) 157 { 158 if (AllChildren[ChildNr]->Name==NewName && AllChildren[ChildNr]!=Win_) 159 { 160 IsUnique=false; 161 break; 162 } 163 } 164 165 if (IsUnique) break; 166 167 static unsigned int Count=1; 168 NewName=Name_+wxString::Format("_%u", Count); 169 Count++; 170 } 171 172 return NewName; 162 173 } 163 174 … … 243 254 bool GuiDocumentT::SaveInit_cgui(std::ostream& OutFile) 244 255 { 245 CheckWindowNames(m_RootWindow);246 247 256 OutFile << "-- This is a Cafu engine GUI script file, written by CaWE, the Cafu World Editor.\n"; 248 257 OutFile << "-- You CAN edit this file manually, but note that CaWE may overwrite your changes.\n"; -
cafu/trunk/CaWE/GuiEditor/GuiDocument.hpp
r386 r388 63 63 64 64 void SetSelection(const ArrayT<cf::GuiSys::WindowT*>& NewSelection); 65 const ArrayT<cf::GuiSys::WindowT*>& GetSelection() ;65 const ArrayT<cf::GuiSys::WindowT*>& GetSelection() const { return m_Selection; } 66 66 67 67 const ArrayT<EditorMaterialI*>& GetEditorMaterials() const { return m_EditorMaterials; } 68 68 GameConfigT* GetGameConfig() { return m_GameConfig; } 69 70 /// Checks if the given string is a valid name for the given window. 71 /// A name is valid if it is a valid Lua identifier and unique among all windows in this GUI. 72 /// @returns 73 /// If the given string \c TestName is valid, it is returned unchanged. 74 /// Otherwise, a new string is created from \c TestName that is valid. 75 wxString CheckWindowName(const wxString& TestName, EditorWindowT* Win) const; 69 76 70 77 bool SaveInit_cgui(std::ostream& OutFile); -
cafu/trunk/CaWE/GuiEditor/WindowTree.cpp
r374 r388 417 417 } 418 418 419 // The command may well have set a name different from TE.GetLabel(). 420 TE.Veto(); 421 SetItemText(TE.GetItem(), Window->Name); 422 419 423 m_IsRecursiveSelfNotify=false; 420 424 } -
cafu/trunk/CaWE/GuiEditor/Windows/EditorWindow.cpp
r387 r388 25 25 #include "../Commands/ModifyWindow.hpp" 26 26 #include "../../EditorMaterial.hpp" 27 #include "../../LuaAux.hpp"28 27 #include "../../MaterialBrowser/DocAccess.hpp" 29 28 #include "../../MaterialBrowser/MaterialBrowserDialog.hpp" … … 46 45 : m_Win(Win), 47 46 m_GuiDoc(GuiDoc), 48 m_IsSelected(false), 49 m_Counter(1) 50 { 51 // If window has no name, create default name. 52 if (m_Win->Name=="") m_Win->Name="Window"; 53 54 // Check window name uniqueness and repair it. 55 RepairNameUniqueness(); 56 57 // Note: Since the name of a window comes from an already functional script or is checked when set 58 // by the method below, we assert that the name is already Lua compatible here. 59 wxASSERT(CheckLuaVarCompat(m_Win->Name)); 60 } 61 62 63 bool EditorWindowT::SetName(const wxString& NewName) 64 { 65 if (!CheckLuaVarCompat(NewName)) 66 { 67 wxMessageBox("A window name must be a string of letters, digits, and underscores that is\n" 68 "not beginning with a digit and is not a reserved Lua keyword or global variable.", 69 "Window name is not a valid Lua identifier.", wxOK | wxICON_ERROR); 70 return false; 71 } 72 73 if (!CheckNameUniqueness(NewName)) 74 { 75 wxMessageBox("The window name must be unique in this window hierarchy level. The window can't have a name that is already taken by one of its siblings.", "Error: The given window name is not unique.", wxOK | wxICON_ERROR); 76 return false; 77 } 78 79 m_Win->Name=NewName.c_str(); 80 81 return true; 82 } 83 84 85 bool EditorWindowT::CheckNameUniqueness(const wxString& Name) const 86 { 87 if (m_Win->GetRoot()==m_Win) return true; // Root window can have any name. 88 89 // Get the siblings of this windows and check name uniqueness against them. 90 cf::GuiSys::WindowT* Parent=m_Win->GetParent(); 91 ArrayT<cf::GuiSys::WindowT*> Siblings; 92 Parent->GetChildren(Siblings); 93 94 for (unsigned long SibNr=0; SibNr<Siblings.Size(); SibNr++) 95 { 96 if (Siblings[SibNr]==m_Win) continue; // Don't check against ourselves. 97 98 if (Siblings[SibNr]->Name==Name) return false; 99 } 100 101 return true; 102 } 103 104 105 static wxString StripSuffix(const wxString& Str) 106 { 107 const size_t Pos=Str.rfind("_"); 108 109 if (Pos==std::string::npos) return Str; 110 111 for (size_t i=Pos+1; i<Str.length(); i++) 112 if (!wxIsdigit(Str[i])) return Str; 113 114 if (Pos==0) return "Window"; 115 116 return Str.Left(Pos); 117 } 118 119 120 void EditorWindowT::RepairNameUniqueness() 121 { 122 const wxString BaseName=StripSuffix(m_Win->Name); 123 wxString NewName =m_Win->Name; 124 125 while (!CheckNameUniqueness(NewName)) 126 { 127 NewName=BaseName+"_"+wxString::Format("%u", m_Counter); 128 m_Counter++; 129 } 130 131 m_Win->Name=NewName; 47 m_IsSelected(false) 48 { 49 if (m_Win->Name=="") 50 { 51 m_Win->Name=m_Win->GetType()->ClassName; 52 53 const size_t len=m_Win->Name.length(); 54 55 if (len>1 && m_Win->Name[len-1]=='T') 56 { 57 // Remove the trailing "T" from our class name. 58 m_Win->Name=std::string(m_Win->Name, 0, len-1); 59 } 60 } 61 62 m_Win->Name=m_GuiDoc->CheckWindowName(m_Win->Name, this); 132 63 } 133 64 -
cafu/trunk/CaWE/GuiEditor/Windows/EditorWindow.hpp
r387 r388 59 59 bool IsSelected() const { return m_IsSelected; } 60 60 61 /// Sets the name for this window.62 /// This method checks if the name is valid in the sense of Lua compatibility63 /// (window name is used as a Lua variable name for this window) and uniqueness.64 /// This function should always be called instead of setting the name member65 /// of the window directly.66 /// @param NewName The name to be set.67 /// @return Whether the name has been successfully set.68 bool SetName(const wxString& NewName);69 70 /// Checks the name uniqueness of a new name string within the windows siblings.71 /// @param Name Name to check for uniqueness.72 /// @return Whether this name is unique.73 bool CheckNameUniqueness(const wxString& Name) const;74 75 /// Helper method to check and auto-repair the uniqueness of the name of this window.76 void RepairNameUniqueness();77 78 61 /// Fills a property grid manager with one property for each class member. 79 62 /// @param PropMan The property manager grid to fill. … … 105 88 cf::GuiSys::WindowT* m_Win; ///< The GuiSys's "dual" or "sibling" of this window. 106 89 GuiDocumentT* m_GuiDoc; ///< The GUI document that this window lives in. 107 bool m_IsSelected; 108 unsigned int m_Counter; 90 bool m_IsSelected; ///< Is this window selected for editing? 109 91 }; 110 92 } -
cafu/trunk/CaWE/LuaAux.cpp
r387 r388 26 26 27 27 28 static const std::string Keywords_Lua[]={"and", "break", "do", "else", "elseif", 29 "end", "false", "for", "function", "if", 30 "in", "local", "nil", "not", "or", "repeat", 31 "return", "then", "true", "until", "while"}; 28 namespace 29 { 30 const wxString Keywords[]= 31 { 32 "and", "break", "do", "else", "elseif", 33 "end", "false", "for", "function", "if", 34 "in", "local", "nil", "not", "or", "repeat", 35 "return", "then", "true", "until", "while" 36 }; 32 37 33 static const int NrOfKeywords=sizeof(Keywords_Lua)/sizeof(*Keywords_Lua); 34 35 36 bool CheckLuaVarCompat(const wxString& Varname) 37 { 38 wxRegEx LuaVarName("^[A-Za-z_][\\w]+$", wxRE_ADVANCED); 39 wxASSERT(LuaVarName.IsValid()); 40 41 if (LuaVarName.Matches(Varname)) 42 { 43 // Check if variable name is a reserved Lua keyword. 44 for (int KeywordNr=0; KeywordNr<NrOfKeywords; KeywordNr++) 45 if (Varname.c_str()==Keywords_Lua[KeywordNr]) return false; 46 47 // Check if variable name matches a Lua global variable. 48 wxRegEx LuaGlobals("^[_][A-Z]+$", wxRE_ADVANCED); 49 wxASSERT(LuaGlobals.IsValid()); 50 51 if (LuaGlobals.Matches(Varname)) return false; 52 53 return true; 54 } 55 56 return false; 38 const unsigned int NrOfKeywords=sizeof(Keywords)/sizeof(*Keywords); 57 39 } 58 40 59 41 60 wxString MakeLuaVarName(const wxString& Varname)42 bool IsLuaIdentifier(const wxString& id) 61 43 { 62 // Return the original name if it is already valid. 63 if (CheckLuaVarCompat(Varname)) return Varname; 44 // Does id fail to meet the Lua identifier rules? 45 const wxRegEx LuaIdRegEx("^[A-Za-z_][\\w]+$", wxRE_ADVANCED); 46 wxASSERT(LuaIdRegEx.IsValid()); 64 47 65 // Return a default string if passed varname is empty so this functions never fails. 66 if (Varname=="") return "Variable"; 48 if (!LuaIdRegEx.Matches(id)) return false; 67 49 68 wxRegEx LuaVarName("\\W", wxRE_ADVANCED); 69 wxASSERT(LuaVarName.IsValid()); 50 // Is id a global reserved Lua identifier? 51 const wxRegEx LuaGlobalRegEx("^[_][A-Z]+$", wxRE_ADVANCED); 52 wxASSERT(LuaGlobalRegEx.IsValid()); 70 53 71 wxString LuaVar=Varname;54 if (LuaGlobalRegEx.Matches(id)) return false; 72 55 73 LuaVarName.Replace(&LuaVar, "_"); // Replace all non compatible chars with underscore. 56 // Is id a reserved Lua keyword? 57 for (unsigned int kwNr=0; kwNr<NrOfKeywords; kwNr++) 58 if (id==Keywords[kwNr]) return false; 74 59 75 // If variable is now compatible, return it. 76 if (CheckLuaVarCompat(LuaVar)) return LuaVar; 60 // All tests passed: id is a valid Lua identifier! 61 return true; 62 } 77 63 78 // Add a leading underscore which will make the variable compatible in any case.79 LuaVar="_"+LuaVar;80 64 81 wxASSERT(CheckLuaVarCompat(LuaVar)); 65 wxString CheckLuaIdentifier(const wxString& id) 66 { 67 // If id is valid, return it unchanged. 68 if (IsLuaIdentifier(id)) return id; 82 69 83 return LuaVar; 70 // If id is empty, just come up with some valid identifier. 71 if (id=="") return "id"; 72 73 // Replace all non-alphanumeric characters with an underscore. 74 wxString NewId=id; 75 76 const wxRegEx NotAlphaNumRegEx("\\W", wxRE_ADVANCED); 77 wxASSERT(NotAlphaNumRegEx.IsValid()); 78 79 NotAlphaNumRegEx.Replace(&NewId, "_"); 80 81 if (IsLuaIdentifier(NewId)) return NewId; 82 83 // Still not good? Add a prefix. 84 NewId="id_"+NewId; 85 86 wxASSERT(IsLuaIdentifier(NewId)); 87 return NewId; 84 88 } -
cafu/trunk/CaWE/LuaAux.hpp
r387 r388 39 39 40 40 41 /// Checks if a string is a valid Lua variable name. 42 /// @param Varname The variable name to be checked. 43 /// @return Whether the string is valid or not. 44 bool CheckLuaVarCompat(const wxString& Varname); 41 /// Determines if the given string is a valid Lua identifier. 42 /// 43 /// @param id The identifier name to check. 44 /// @return Whether \c id is a valid Lua identifier. 45 bool IsLuaIdentifier(const wxString& id); 45 46 46 /// Converts a string into a valid Lua variable name by replacing 47 /// all special invalid characters with underscores and/or adding 48 /// underscores to the begining of the name to make it valid. 49 /// @param Varname The variable name to convert. 50 /// @return The converted valid Lua variable name. 51 wxString MakeLuaVarName(const wxString& Varname); 47 48 /// Determines if the given string is a valid Lua identifier. 49 /// If valid, \c id is returned unchanged. 50 /// Otherwise, for the return value a variant of \c id is created that is valid. 51 /// 52 /// @param id The identifier name to check. 53 /// @return A valid Lua identifier derived from \c id. 54 wxString CheckLuaIdentifier(const wxString& id); 52 55 53 56 #endif -
cafu/trunk/CaWE/MapEntity.cpp
r285 r388 409 409 for (unsigned long Count=1; true; Count++) 410 410 { 411 const wxString UniqueValue= MakeLuaVarName(m_Class->GetName())+wxString::Format("_%03lu", Count);411 const wxString UniqueValue=CheckLuaIdentifier(m_Class->GetName())+wxString::Format("_%03lu", Count); 412 412 unsigned long EntNr; 413 413 -
cafu/trunk/CaWE/ModelEditor/ObserverPattern.hpp
r383 r388 81 81 /// Notifies the observer that a skin has changed. 82 82 /// @param Subject The model document with the model in which the skin has changed. 83 /// @param AnimNr The number of the skin that has changed.83 /// @param SkinNr The number of the skin that has changed. 84 84 virtual void Notify_SkinChanged(SubjectT* Subject, unsigned int SkinNr) { } 85 85
