Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AddPrimitiveKeyCommand.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Linq;
5 
6 using SiliconStudio.ActionStack;
7 using SiliconStudio.Core.Reflection;
8 using SiliconStudio.Quantum.Attributes;
9 
10 namespace SiliconStudio.Quantum.Commands
11 {
13  {
14  /// <inheritdoc/>
15  public string Name { get { return "AddPrimitiveKey"; } }
16 
17  /// <inheritdoc/>
18  public CombineMode CombineMode { get { return CombineMode.CombineOnlyForAll; } }
19 
20  /// <inheritdoc/>
21  public bool CanAttach(ITypeDescriptor typeDescriptor, MemberDescriptorBase memberDescriptor)
22  {
23  if (memberDescriptor != null)
24  {
25  var attrib = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute<SealedCollectionAttribute>(memberDescriptor.MemberInfo);
26  if (attrib != null && attrib.CollectionSealed)
27  return false;
28  }
29 
30  var dictionaryDescriptor = typeDescriptor as DictionaryDescriptor;
31  if (dictionaryDescriptor == null)
32  return false;
33  return !dictionaryDescriptor.KeyType.IsClass || dictionaryDescriptor.KeyType == typeof(string) || dictionaryDescriptor.KeyType.GetConstructor(new Type[0]) != null;
34  }
35 
36  /// <inheritdoc/>
37  public object Invoke(object currentValue, ITypeDescriptor descriptor, object parameter, out UndoToken undoToken)
38  {
39  var dictionaryDescriptor = (DictionaryDescriptor)descriptor;
40  var newKey = dictionaryDescriptor.KeyType != typeof(string) ? Activator.CreateInstance(dictionaryDescriptor.KeyType) : GenerateStringKey(currentValue, descriptor, parameter);
41  var newItem = !dictionaryDescriptor.ValueType.IsAbstract ? Activator.CreateInstance(dictionaryDescriptor.ValueType) : null;
42  dictionaryDescriptor.SetValue(currentValue, newKey, newItem);
43  undoToken = new UndoToken(true, newKey);
44  return currentValue;
45  }
46 
47  /// <inheritdoc/>
48  public object Undo(object currentValue, ITypeDescriptor descriptor, UndoToken undoToken)
49  {
50  var dictionaryDescriptor = (DictionaryDescriptor)descriptor;
51  var key = undoToken.TokenValue;
52  dictionaryDescriptor.Remove(currentValue, key);
53  return currentValue;
54  }
55 
56  private static object GenerateStringKey(object value, ITypeDescriptor descriptor, object baseValue)
57  {
58  // TODO: use a dialog service and popup a message when the given key is invalid
59  string baseName = GenerateBaseName(baseValue);
60  int i = 1;
61 
62  var dictionary = (DictionaryDescriptor)descriptor;
63  while (dictionary.ContainsKey(value, baseName))
64  {
65  baseName = (baseValue != null ? baseValue.ToString() : "Key") + " " + ++i;
66  }
67 
68  return baseName;
69  }
70 
71  private static string GenerateBaseName(object baseValue)
72  {
73  const string DefaultKey = "Key";
74 
75  if (baseValue == null)
76  return DefaultKey;
77 
78  var baseName = baseValue.ToString();
79  if (string.IsNullOrWhiteSpace(baseName))
80  return DefaultKey;
81 
82  if (baseName.Any(x => !Char.IsLetterOrDigit(x) && x == ' ' && x == '_'))
83  return DefaultKey;
84 
85  return baseName;
86  }
87  }
88 }
object Invoke(object currentValue, ITypeDescriptor descriptor, object parameter, out UndoToken undoToken)
Invokes the node command. The current value of the associated object or member.The type descriptor of...
object Undo(object currentValue, ITypeDescriptor descriptor, UndoToken undoToken)
Undoes an invoke of the node command. The current value of the associated object or member...
Provides a descriptor for a System.Collections.IDictionary.
bool CanAttach(ITypeDescriptor typeDescriptor, MemberDescriptorBase memberDescriptor)
Indicates whether this command can be attached to an object or a member with the given descriptors...
CombineMode
An enum that describes what to do with a node or a command when combining view models.
Definition: CombineMode.cs:8
Base interface for node commands.
Definition: INodeCommand.cs:11
Provides access members of a type.
Base class for IMemberDescriptor for a MemberInfo
Represents a token that stores an unique identifier and an object. This token should be generated by ...
Definition: UndoToken.cs:12