00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 using System;
00013 using System.Collections;
00014 using System.Collections.Generic;
00015 using System.Diagnostics;
00016 using System.Text;
00017 using System.Text.RegularExpressions;
00018 using Microsoft.Office.Project.Server.Library;
00019
00020 namespace Mcs.Epm.MicrosoftProject.mpFx
00021 {
00022
00023
00024
00025 public class GraphicalIndicator
00026 {
00027 #region Constants
00028
00029 public static readonly int MAX_NUMBER_OF_CRITERIA = 3;
00030 public static readonly int MAX_IMAGE_INDEX = 65;
00031
00032 #endregion
00033
00034 #region Instance Data
00035
00036 private static readonly Dictionary<string, string> _Tests = new Dictionary<string, string>();
00037 private readonly Dictionary<int, Criteria> _ProjectSummaryCriteria = new Dictionary<int, Criteria>();
00038 private readonly Dictionary<int, Criteria> _SummaryCriteria = new Dictionary<int, Criteria>();
00039 private readonly Dictionary<int, Criteria> _NonSummaryCriteria = new Dictionary<int, Criteria>();
00040
00041 #endregion
00042
00043 #region Enums
00044
00045 public enum CriteriaFor
00046 {
00047 None,
00048 NonSummaryRows,
00049 ProjectSummary,
00050 Summary
00051 }
00052
00053 #endregion
00054
00055 #region Constructor
00056
00057
00058
00059
00060
00061
00062
00063 public GraphicalIndicator(Guid entityGuid,
00064 CustomFieldDefinition customField,
00065 CustomField.Type customFieldType)
00066 {
00067 if (customField == null)
00068 {
00069 throw new ArgumentNullException("customField");
00070 }
00071
00072 if (entityGuid == Guid.Empty || !IsValidEntityForGraphicalIndicator(entityGuid))
00073 {
00074 throw new ArgumentException("Invalid entity Guid");
00075 }
00076
00077 if (customFieldType == CustomField.Type.FINISHDATE)
00078 {
00079 throw new ArgumentException("Invalid custom field type");
00080 }
00081
00082 EntityGuid = entityGuid;
00083 CustomFieldDefinition = customField;
00084 CustomFieldType = customFieldType;
00085
00086 LoadTests();
00087
00088 UnpackCustomField();
00089 }
00090
00091 #endregion
00092
00093 #region Public Methods
00094
00095
00096
00097
00098
00099
00100 public void AddCriteria(CriteriaFor criteriaFor,
00101 Criteria criteria)
00102 {
00103 if (criteria.ImageIndex == 0)
00104 {
00105 throw new ArgumentException("criteria");
00106 }
00107
00108 if (string.IsNullOrEmpty(criteria.Test))
00109 {
00110 throw new ArgumentException("criteria");
00111 }
00112
00113 if (string.IsNullOrEmpty(criteria.Value))
00114 {
00115 throw new ArgumentException("criteria");
00116 }
00117
00118 Dictionary<int, Criteria> thisCollection;
00119
00120 switch (criteriaFor)
00121 {
00122 case CriteriaFor.None:
00123 throw new ArgumentException("criteria");
00124
00125 case CriteriaFor.NonSummaryRows:
00126 thisCollection = _NonSummaryCriteria;
00127 break;
00128
00129 case CriteriaFor.ProjectSummary:
00130 thisCollection = _ProjectSummaryCriteria;
00131 break;
00132
00133 case CriteriaFor.Summary:
00134 thisCollection = _SummaryCriteria;
00135 break;
00136
00137 default:
00138 throw new ArgumentOutOfRangeException("criteriaFor");
00139 }
00140
00141 Debug.Assert(thisCollection != null);
00142
00143 if (thisCollection.Count + 1 > MAX_NUMBER_OF_CRITERIA)
00144 {
00145 throw new IndexOutOfRangeException();
00146 }
00147
00148 thisCollection.Add(criteria.Index, criteria);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 public Criteria GetCriteria(CriteriaFor criteriaFor,
00158 int index)
00159 {
00160 switch (criteriaFor)
00161 {
00162 case CriteriaFor.NonSummaryRows:
00163 return _NonSummaryCriteria[index];
00164 case CriteriaFor.ProjectSummary:
00165 return _ProjectSummaryCriteria[index];
00166 case CriteriaFor.Summary:
00167 return _SummaryCriteria[index];
00168 default:
00169 throw new ArgumentOutOfRangeException("criteriaFor");
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178 public string GetCriteriaString(CriteriaFor criteriaFor)
00179 {
00180 Dictionary<int, Criteria> thisCollection;
00181
00182 switch (criteriaFor)
00183 {
00184 case CriteriaFor.NonSummaryRows:
00185 thisCollection = _NonSummaryCriteria;
00186 break;
00187 case CriteriaFor.ProjectSummary:
00188 thisCollection = _ProjectSummaryCriteria;
00189 break;
00190 case CriteriaFor.Summary:
00191 thisCollection = _SummaryCriteria;
00192 break;
00193 default:
00194 throw new ArgumentOutOfRangeException("criteriaFor");
00195 }
00196
00197 StringBuilder criteriaString = new StringBuilder();
00198
00199 foreach (KeyValuePair<int, Criteria> pair in thisCollection)
00200 {
00201 criteriaString.AppendFormat("[[{0}\t{1}\t\t][{2}]]",
00202 _Tests[pair.Value.Test],
00203 pair.Value.Value,
00204 pair.Value.ImageIndex);
00205 }
00206
00207 return criteriaString.ToString();
00208 }
00209
00210
00211
00212
00213
00214
00215 public int GetCount(CriteriaFor criteriaFor)
00216 {
00217 switch (criteriaFor)
00218 {
00219 case CriteriaFor.NonSummaryRows:
00220 return _NonSummaryCriteria.Count;
00221 case CriteriaFor.ProjectSummary:
00222 return _ProjectSummaryCriteria.Count;
00223 case CriteriaFor.Summary:
00224 return _SummaryCriteria.Count;
00225 default:
00226 throw new ArgumentOutOfRangeException("criteriaFor");
00227 }
00228 }
00229
00230
00231
00232
00233
00234 public void ClearCriteria(CriteriaFor criteriaFor)
00235 {
00236 switch (criteriaFor)
00237 {
00238 case CriteriaFor.None:
00239 break;
00240 case CriteriaFor.NonSummaryRows:
00241 _NonSummaryCriteria.Clear();
00242 break;
00243 case CriteriaFor.ProjectSummary:
00244 _ProjectSummaryCriteria.Clear();
00245 break;
00246 case CriteriaFor.Summary:
00247 _SummaryCriteria.Clear();
00248 break;
00249 default:
00250 throw new ArgumentOutOfRangeException("criteriaFor");
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259 public Stack ParseCriteriaString(string criteriaString)
00260 {
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 Regex tokenizer = new Regex(@"\[(?<Tokens>([^\]])*)\]");
00288 MatchCollection tokens = tokenizer.Matches(criteriaString);
00289 Stack criteria = new Stack();
00290
00291 for (int matchCount = 0; matchCount < tokens.Count; matchCount++)
00292 {
00293 string token = tokens[matchCount].Value;
00294
00295 token = token.Replace("[", "");
00296 token = token.Replace("]", "");
00297
00298 token = token.Trim();
00299
00300 string[] components = token.Split('\t');
00301
00302 for (int i = 0; i < components.Length; i++)
00303 {
00304 criteria.Push(components[i]);
00305 }
00306 }
00307
00308 return criteria;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 public static string GetDisplayName(string testString)
00318 {
00319 foreach (KeyValuePair<string, string> test in _Tests)
00320 {
00321 if (test.Value.Equals(testString,
00322 StringComparison.CurrentCultureIgnoreCase)) {
00323 return test.Key;
00324 }
00325 }
00326
00327 return null;
00328 }
00329
00330 #endregion
00331
00332 #region Public Properties
00333
00334
00335
00336
00337 public string[] TestsDisplayNames
00338 {
00339 get
00340 {
00341 string[] testDisplayNames = new string[_Tests.Keys.Count];
00342
00343 _Tests.Keys.CopyTo(testDisplayNames, 0);
00344
00345 return testDisplayNames;
00346 }
00347 }
00348
00349
00350
00351
00352 public Guid EntityGuid { get; private set; }
00353
00354
00355
00356
00357 public CustomField.Type CustomFieldType { get; private set; }
00358
00359
00360
00361
00362 public int ProjectSummaryCriteriaCount
00363 {
00364 get { return _ProjectSummaryCriteria.Count; }
00365 }
00366
00367
00368
00369
00370 public int SummaryCriteriaCount
00371 {
00372 get { return _SummaryCriteria.Count; }
00373 }
00374
00375
00376
00377
00378 public int NonSummaryCriteriaCount
00379 {
00380 get { return _NonSummaryCriteria.Count; }
00381 }
00382
00383 #endregion
00384
00385 #region Private Methods
00386
00387
00388
00389
00390
00391 private void UnpackCustomField()
00392 {
00393 if (!string.IsNullOrEmpty(CustomFieldDefinition.NonSummaryCriteriaString))
00394 {
00395 Stack components = ParseCriteriaString(CustomFieldDefinition.NonSummaryCriteriaString);
00396
00397 AddCriteria(CriteriaFor.NonSummaryRows, components);
00398 }
00399
00400 if (!string.IsNullOrEmpty(CustomFieldDefinition.ProjectSummaryCriteriaString))
00401 {
00402 Stack components = ParseCriteriaString(CustomFieldDefinition.ProjectSummaryCriteriaString);
00403
00404 AddCriteria(CriteriaFor.ProjectSummary, components);
00405 }
00406
00407 if (!string.IsNullOrEmpty(CustomFieldDefinition.SummaryTaskCriteriaString))
00408 {
00409 Stack components = ParseCriteriaString(CustomFieldDefinition.SummaryTaskCriteriaString);
00410
00411 AddCriteria(CriteriaFor.Summary, components);
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420 private void AddCriteria(CriteriaFor criteriaFor,
00421 Stack criteriaComponents)
00422 {
00423 int operationsCount = criteriaComponents.Count;
00424
00425
00426 for (int counter = 0; counter < operationsCount/3; counter++)
00427 {
00428 Criteria criteria = new Criteria(Convert.ToInt32(criteriaComponents.Pop()),
00429 criteriaComponents.Pop().ToString(),
00430 GetDisplayName(criteriaComponents.Pop().ToString()), counter);
00431
00432 AddCriteria(criteriaFor, criteria);
00433 }
00434 }
00435
00436
00437 private static void LoadTests()
00438 {
00439 if (_Tests.Count == 0)
00440 {
00441 _Tests.Add("equals", "==");
00442 _Tests.Add("does not equal", "!=");
00443 _Tests.Add("is greater than", ">");
00444 _Tests.Add("is greater than or equal to", ">=");
00445 _Tests.Add("is less than", "<");
00446 _Tests.Add("is less than or equal to", "<=");
00447 _Tests.Add("is within", "Between");
00448 _Tests.Add("is not within", "NotBetween");
00449 _Tests.Add("contains", "Contains");
00450 _Tests.Add("doesn't contain", "DoesntContain");
00451 _Tests.Add("contains exactly", "ContainsExactly");
00452 _Tests.Add("any value", "ANY");
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 private static bool IsValidEntityForGraphicalIndicator(Guid entity)
00463 {
00464 string entityString = entity.ToString().ToLower();
00465
00466 return (entityString == Utilities.GetEntityGuidStringFromName("Project").ToLower() ||
00467 entityString == Utilities.GetEntityGuidStringFromName("Task").ToLower() ||
00468 entityString == Utilities.GetEntityGuidStringFromName("Resource").ToLower());
00469 }
00470
00471 #endregion
00472
00473 #region Private Properties
00474
00475
00476
00477
00478 private CustomFieldDefinition CustomFieldDefinition { get; set; }
00479
00480 #endregion
00481
00482 #region Classes
00483
00484
00485
00486
00487 public class Criteria
00488 {
00489
00490
00491
00492
00493
00494
00495
00496 public Criteria(int imageIndex,
00497 string value,
00498 string test,
00499 int index)
00500 {
00501 Index = index;
00502 ImageIndex = imageIndex;
00503 Test = test;
00504 Value = value;
00505 }
00506
00507
00508
00509
00510 public int Index { get; private set; }
00511
00512 public int ImageIndex { get; private set; }
00513 public string Value { get; private set; }
00514 public string Test { get; private set; }
00515 }
00516
00517 #endregion
00518 }
00519 }