public void ChangesCanBeIteratedOverSinceAChange() { var h = new DocumentHistory(); h.Add(FakeChange("foo")); h.Add(FakeChange("bar")); h.Add(FakeChange("baz")); Assert.AreEqual( new string[] { "bar", "baz" }, h.IterateChangesAfter("foo").Select(c => c.Id).ToArray() ); Assert.AreEqual( new string[] { "baz" }, h.IterateChangesAfter("bar").Select(c => c.Id).ToArray() ); Assert.AreEqual( new string[] {}, h.IterateChangesAfter("baz").Select(c => c.Id).ToArray() ); Assert.AreEqual( new string[] {}, h.IterateChangesAfter("xxx").Select(c => c.Id).ToArray() ); Assert.AreEqual( new string[] {}, new DocumentHistory().IterateChangesAfter("xxx").Select(c => c.Id).ToArray() ); }
public DocumentInfo CreateDocument(CreateDocumentInput input, Stream stream) { var documentInfo = Mapper.Map <DocumentInfo>(input); StoreDocumentFile(documentInfo, stream); HandleTifFile(documentInfo.FileType, documentInfo.Path); documentInfo.Key = Guid.NewGuid().ToString(); documentInfo.CreateTime = DateTime.Now; documentInfo.ModifyTime = documentInfo.CreateTime; documentInfo.ModifyUserId = documentInfo.CreateUserID; documentInfo.ModifyUserName = documentInfo.CreateUserName; documentInfo.CurrentVersion = 1; _context.DocumentInfos.Add(documentInfo); _context.SaveChanges(); var historyPath = StoreHistoryFile(stream, documentInfo.FileType); DocumentHistory fileHistory = new DocumentHistory { DocumentInfoId = documentInfo.Id, Version = 1, PreviousVersion = -1, Key = documentInfo.Key, Path = historyPath, UserId = input.CreateUserID, UserName = input.CreateUserName, CreateTime = DateTime.Now }; _context.DocumentHistories.Add(fileHistory); _context.SaveChanges(); return(documentInfo); }
private void CreateDocument(DocumentHistory history) { _logger.LogDebug("create document: {0}", history.Path); if (_documentsByPath.TryGetValue(history.Path, out var _)) { _logger.LogWarning($"invalid created log found: {history.Id}"); UpdateDocument(history); } var document = new MaintainanceDocument() { DocumentId = _documentId++, Path = history.Path, StorageKey = history.StorageKey, ContentType = history.ContentType, FileSize = history.FileSize, Hash = history.Hash, Created = history.Created, LastModified = history.LastModified, Histories = new List <DocumentHistory>() { history } }; _documentStore.Add(document.DocumentId, document); _documentsByPath.Add(document.Path, document); }
private void UpdateDocument(DocumentHistory history) { _logger.LogDebug("update document: {0}", history.Path); if (!_documentsByPath.TryGetValue(history.Path, out var document)) { _logger.LogWarning($"invalid update history found: {history.Id}"); CreateDocument(history); } else { if (history.FileSize != document.FileSize || history.Hash != document.Hash || history.LastModified != document.LastModified || history.Created != document.Created) { document.Histories.Add(history); document.Path = history.Path; document.StorageKey = history.StorageKey; document.ContentType = history.ContentType; document.FileSize = history.FileSize; document.Hash = history.Hash; document.Created = history.Created; document.LastModified = history.LastModified; document.Histories.Add(history); } else { _deletableHistories.Add(history); } } }
public Row(DocumentHistory documentHistory) { Time = documentHistory.Time.ToLongTimeString(); string state; switch (documentHistory.State) { case DocumentPrintState.BeginPrinting: state = "Начало печати"; break; case DocumentPrintState.Printed: state = "Распечатано"; break; case DocumentPrintState.PrintingError: state = "Ошибка печати"; break; case DocumentPrintState.PrintingRepeat: state = "Ошибка. Повторная отправка задания печати"; break; default: state = documentHistory.State.ToString(); break; } State = state; }
public void Apply(DocumentHistory history) { if (!AssertHistory(history)) { _deletableHistories.Add(history); return; } switch (history.Discriminator) { case DocumentHistoryDiscriminator.DocumentCreated: CreateDocument(history); break; case DocumentHistoryDiscriminator.DocumentDeleted: DeleteDocument(history); break; case DocumentHistoryDiscriminator.DocumentUpdated: UpdateDocument(history); break; default: break; } }
private void Deleted(DocmsContext ctx, string path, int contentId) { ctx.DocumentHistories.Add(DocumentHistory.DocumentDeleted( DateTime.UtcNow, contentId, path)); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static void Serialize <T>(IEnumerable <T> bhomObjects, BH.oM.XML.GBXML gbx, string fileName, XMLSettings settings) where T : IObject { switch (settings.ExportDetail) { case ExportDetail.Full: SerializeCollectionFull(bhomObjects as dynamic, gbx, settings); break; case ExportDetail.BuildingShell: SerializeBuildingShell(bhomObjects as dynamic, gbx, settings); break; case ExportDetail.IndividualSpaces: SerializeSpaces(bhomObjects, fileName, settings); break; default: throw new NotImplementedException("That option has not been implemented"); } // Document History DocumentHistory DocumentHistory = new DocumentHistory(); DocumentHistory.CreatedBy.Date = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"); gbx.DocumentHistory = DocumentHistory; }
public async Task Handle(DomainEventNotification <DocumentDeletedEvent> notification, CancellationToken cancellationToken = default) { var ev = notification.Event; _db.DocumentHistories .Add(DocumentHistory.DocumentDeleted( ev.Timestamp, ev.Entity.Id, ev.Path.ToString())); await _db.SaveChangesAsync(); }
public static DocumentHistory DocumentHistory(System.Guid cADModelId) { DocumentHistory documentHistory = new DocumentHistory(); documentHistory.ProgramInfo = ProgramInfo(); documentHistory.CreatedBy = CreatedBy(cADModelId); documentHistory.ModifiedBy = ModifiedBy(); documentHistory.PersonInfo = PersonInfo(); return(documentHistory); }
public static DocumentHistoryDto MapToDocumentHistoryDto(DocumentHistory documentHistory) { return(new DocumentHistoryDto() { ModifiedAt = documentHistory.ModifiedAt, DocumentTitle = documentHistory.DocumentTitle, Author = documentHistory.ModifiedByUser.FirstName + " " + documentHistory.ModifiedByUser.LastName, CaseNumber = documentHistory.CaseNumber, DocumentCategoryName = documentHistory.DocumentCategoryName, DocumentDescription = documentHistory.DocumentDescription, DocumentPath = documentHistory.DocumentPath }); }
public TransactionalNumericEditBox(DocumentHistory history) { BeginSpin += () => history.BeginTransaction(); EndSpin += () => { history.CommitTransaction(); history.EndTransaction(); }; Submitted += s => { if (history.IsTransactionActive) { history.RollbackTransaction(); } }; }
private void Updated(DocmsContext ctx, string path, int contentId) { var now = DateTime.UtcNow; ctx.DocumentHistories.Add(DocumentHistory.DocumentUpdated( DateTime.UtcNow, contentId, path, "stragekey", "text/plain", 5 + contentId.ToString().Length, Hash.CalculateHash(Encoding.UTF8.GetBytes("Hello" + contentId)), now, now)); }
static void Main(string[] args) { var doc = new Document(); var his = new DocumentHistory(); doc.Content = "Testing Memento Pattern!"; his.Push(doc.CreateState()); doc.FontName = "TimeNewRoman"; his.Push(doc.CreateState()); Console.WriteLine(doc); doc.Restore(his.Pop); Console.WriteLine(doc); }
private void DeleteDocument(DocumentHistory history) { _logger.LogDebug("delete document: {0}", history.Path); if (!_documentsByPath.TryGetValue(history.Path, out var document)) { _logger.LogWarning($"invalid delete history found: {history.Id}"); _deletableHistories.Add(history); } else { document.Histories.Add(history); document.Deleted = true; _documentsByPath.Remove(document.Path); } }
public void ChangesCanBeTestedForContainment() { var h = new DocumentHistory(); h.Add(FakeChange("foo")); h.Add(FakeChange("bar")); h.Add(FakeChange("baz")); Assert.IsTrue(h.Contains("foo")); Assert.IsTrue(h.Contains("bar")); Assert.IsTrue(h.Contains("baz")); Assert.IsFalse(h.Contains("xxx")); Assert.IsFalse(h.Contains("yyy")); Assert.IsFalse(h.Contains("zzz")); }
public GetHistoryResponse GetHistory(GetHistoryRequest request) { if (request == null) { throw new ArgumentNullException("request"); } // Must have the documentId you'd like to add annotations to. // If you only have the document cache URI, DocumentFactory.LoadFromUri needs to be called. if (string.IsNullOrEmpty(request.DocumentId)) { throw new ArgumentNullException("documentId"); } IList <DocumentHistoryItem> items = null; var cache = ServiceHelper.Cache; using (var document = DocumentFactory.LoadFromCache(cache, request.DocumentId)) { // Ensure we have the document. DocumentHelper.CheckLoadFromCache(document); DocumentHistory history = document.History; items = history.GetItems(); if (items != null && request.ClearHistory) { history.Clear(); document.SaveToCache(); } } if (_loggingDocumentHistory) { ShowHistory(request.DocumentId, items); } DocumentHistoryItem[] itemsArray = new DocumentHistoryItem[items.Count]; items.CopyTo(itemsArray, 0); GetHistoryResponse response = new GetHistoryResponse { Items = itemsArray }; return(response); }
public async Task Handle(DomainEventNotification <DocumentUpdatedEvent> notification, CancellationToken cancellationToken = default) { var ev = notification.Event; _db.DocumentHistories .Add(DocumentHistory.DocumentUpdated( ev.Timestamp, ev.Entity.Id, ev.Path.ToString(), ev.Data.StorageKey, ev.ContentType, ev.Data.Length, ev.Data.Hash, ev.Created, ev.LastModified)); await _db.SaveChangesAsync(); }
public override IDocumentHistory ToModel() { var model = new DocumentHistory { Id = Id, AuditId = AuditId, DocumentTypeId = (DocumentTypes)DocumentTypeId, Filename = Filename, PrintedOn = PrintedOn, PrintedBy = PrintedBy, CreatedOn = CreatedOn, CreatedById = CreatedById, LastModifiedOn = LastModifiedOn, LastModifiedById = LastModifiedById }; return(model); }
private void AddToHistory(Document document) { var documentHistoryRecord = new DocumentHistory() { DocumentHistoryId = 0, Document = document, DocumentId = document.DocumentId, ModifiedAt = DateTime.UtcNow, ModifiedByUser = _dbContext.UserInfo.FirstOrDefault(u => u.UserId == 1), ModifiedByUserId = 1, DocumentPath = document.DocumentPath, CaseNumber = document.Case.CaseNumber, DocumentCategoryName = document.DocumentCategory.DocumentCategoryTitle, DocumentDescription = document.Description, DocumentTitle = document.Title }; _dbContext.DocumentHistory.Add(documentHistoryRecord); _dbContext.SaveChanges(); }
public static DocumentHistoryDto MapToDocumentHistoryDto(DocumentHistory documentHistory, IkarusContext _dbContext, int id) { var documentHistoryDto = new DocumentHistoryDto() { ModifiedAt = documentHistory.ModifiedAt, DocumentTitle = documentHistory.DocumentTitle, Author = documentHistory.ModifiedByUser.FirstName + " " + documentHistory.ModifiedByUser.LastName, CaseNumber = documentHistory.CaseNumber, DocumentCategoryName = documentHistory.DocumentCategoryName, DocumentDescription = documentHistory.DocumentDescription, DocumentPath = documentHistory.DocumentPath, }; var extension = Path.GetExtension(documentHistoryDto.DocumentPath).Replace(".", ""); if (extension != null) { documentHistoryDto.IconPath = _dbContext.FileType.FirstOrDefault(c => c.Extension == extension).IconPath; } return(documentHistoryDto); }
/// <summary> /// 追加修订历史信息 /// </summary> /// <param name="userInfo">用户信息</param> /// <returns></returns> public bool AppendHistory(UserInfo userInfo) { if (userInfo == null) { return(false); } DocumentHistory history = new DocumentHistory(); history.Author.Code = userInfo.USER_ID; history.Author.Name = userInfo.USER_NAME; history.Author.Organization = userInfo.DEPT_NAME; history.Timestamp = DateTime.Now; if (this.textEditor1.DocumentInfo.Histories.Count <= 0) { history.Description = "创建"; } else { history.Description = "修订"; } this.textEditor1.DocumentInfo.Histories.Add(history); return(true); }
public bool ExternalRefreshFile(ExternalRefreshFileInput input) { var documentInfo = _context.DocumentInfos.FirstOrDefault(a => a.ExternalID == input.ID); if (documentInfo == null) { return(false); } DocumentHistory documentHistory = _context.DocumentHistories.FirstOrDefault(a => a.DocumentInfoId == documentInfo.Id && a.Version == documentInfo.CurrentVersion); documentInfo.Key = Guid.NewGuid().ToString(); documentHistory.Key = documentInfo.Key; if (!string.IsNullOrEmpty(input.NewID)) { documentInfo.ExternalID = input.NewID; } documentService.StoreDocumentFile(documentInfo, input.FilePath); _context.SaveChanges(); return(true); }
private static void runMemento() { var document = new Document(); var history = new DocumentHistory(document); document.Append("First revision"); history.SnapShot(); document.Bold(); history.SnapShot(); document.Italic(); history.SnapShot(); Console.WriteLine("Before restoring history."); Console.WriteLine(document.ToString()); history.Restore(1); Console.WriteLine("Revision 2 restored."); Console.WriteLine(document.ToString()); history.Restore(0); Console.WriteLine("Revision 1 restored."); Console.WriteLine(document.ToString()); }
/* * This method is used to (GET) get the Document History for a given Document and for a given user from the SignNow Application */ public DocumentHistory[] GetDocumentHistory(Oauth2Token token, string id) { DocumentHistory[] docshistory = new DocumentHistory[100]; try { string requestBody = JsonConvert.SerializeObject(token, Formatting.Indented); var client = new RestClient(); client.BaseUrl = config.GetApiBase(); var request = new RestRequest("/document" + "/" + id + "/history", Method.GET) .AddHeader("Authorization", "Bearer " + token.AccessToken); var httpResponse = client.Execute(request); string json = httpResponse.Content.ToString(); if (httpResponse.StatusCode.Equals(System.Net.HttpStatusCode.OK)) { JArray jarr = JArray.Parse(json); int i = 0; foreach (JObject jobj in jarr) { docshistory[i] = JsonConvert.DeserializeObject <DocumentHistory>(jobj.ToString()); i++; } } else if (httpResponse.StatusCode.Equals(System.Net.HttpStatusCode.BadRequest)) { docshistory[0] = JsonConvert.DeserializeObject <DocumentHistory>(json);; } } catch (Exception ex) { Console.WriteLine(string.Format("Exception: {0}", ex.Message)); throw; } return(docshistory); }
private static void SerializeBuildingSpaces(IEnumerable <BH.oM.XML.Environment.DocumentBuilder> documents, string fileName, XMLSettings settings) { if (!System.IO.Directory.Exists(fileName)) { System.IO.Directory.CreateDirectory(fileName); } foreach (BH.oM.XML.Environment.DocumentBuilder db in documents) { foreach (List <Panel> space in db.ElementsAsSpaces) { if (space.IsExternal(db.ElementsAsSpaces)) { Dictionary <String, object> spaceData = (space.Where(x => x.CustomData.ContainsKey("Space_Custom_Data")).FirstOrDefault() != null ? space.Where(x => x.CustomData.ContainsKey("Space_Custom_Data")).FirstOrDefault().CustomData["Space_Custom_Data"] as Dictionary <String, object> : new Dictionary <string, object>()); string spaceName = ""; if (spaceData.ContainsKey("SAM_SpaceName") && spaceData["SAM_SpaceName"] != null) { spaceName = spaceData["SAM_SpaceName"].ToString(); } else { spaceName = "Space-" + Guid.NewGuid().ToString().Replace("-", ""); } GBXML gbx = new GBXML(); SerializeCollection(space, db.Levels, db.UnassignedPanels, gbx, settings); //Document History DocumentHistory DocumentHistory = new DocumentHistory(); DocumentHistory.CreatedBy.Date = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"); gbx.DocumentHistory = DocumentHistory; XMLWriter.Save(fileName + spaceName + ".xml", gbx); } } } }
private bool AssertHistory(DocumentHistory history) { switch (history.Discriminator) { case DocumentHistoryDiscriminator.DocumentCreated: case DocumentHistoryDiscriminator.DocumentUpdated: return(!string.IsNullOrEmpty(history.StorageKey) && _blobKeysSet.Contains(history.StorageKey) && !string.IsNullOrEmpty(history.Path) && history.FileSize.HasValue && history.Created.HasValue && history.LastModified.HasValue); case DocumentHistoryDiscriminator.DocumentDeleted: return(string.IsNullOrEmpty(history.StorageKey) && !string.IsNullOrEmpty(history.Path) && !history.FileSize.HasValue && !history.Created.HasValue && !history.LastModified.HasValue); default: return(false); } }
public void ChangesCanBeAdded() { var h = new DocumentHistory(); Assert.IsNull(h.LatestChange); h.Add(FakeChange("foo")); Assert.AreEqual(1, h.ToList().Count); Assert.AreEqual("foo", h.ToList()[0].Id); Assert.AreEqual("foo", h.LatestChange.Id); h.Add(FakeChange("bar")); Assert.AreEqual(2, h.ToList().Count); Assert.AreEqual("foo", h.ToList()[0].Id); Assert.AreEqual("bar", h.ToList()[1].Id); Assert.AreEqual("bar", h.LatestChange.Id); h.Add(FakeChange("baz")); Assert.AreEqual(3, h.ToList().Count); Assert.AreEqual("foo", h.ToList()[0].Id); Assert.AreEqual("bar", h.ToList()[1].Id); Assert.AreEqual("baz", h.ToList()[2].Id); Assert.AreEqual("baz", h.LatestChange.Id); }
public async Task ExecuteAsync() { var logger = services.GetService <ILogger <Program> >(); logger.LogInformation("application started."); List <DocumentHistory> allDocumentHistories; List <Document> allDocuments; List <Blob> allBlobs; ILookup <string, DocumentHistory> allDocumentHistoriesByStorageKey; ILookup <string, Document> allDocumentsByStorageKey; ILookup <string, Blob> allBlobsByStorageKey; HashSet <string> blobKeysSet; using (var context = CreateContext(configuration)) { allDocumentHistories = (await context .DocumentHistories .ToListAsync() .ConfigureAwait(false)); allDocuments = (await context .Documents .ToListAsync() .ConfigureAwait(false)); allBlobs = (await context .Blobs .ToListAsync() .ConfigureAwait(false)); allDocumentHistoriesByStorageKey = allDocumentHistories.ToLookup(d => d.StorageKey); allDocumentsByStorageKey = allDocuments.ToLookup(d => d.StorageKey); allBlobsByStorageKey = allBlobs.ToLookup(d => d.StorageKey); } var blobKeys = dataStore.ListAllKeys(); blobKeysSet = new HashSet <string>(); foreach (var key in blobKeys) { if (blobKeysSet.Add(key)) { if (allDocumentHistoriesByStorageKey[key].Any()) { continue; } if (allDocumentsByStorageKey[key].Any()) { continue; } if (allBlobsByStorageKey[key].Any()) { continue; } logger.LogWarning("delete data for key: " + key); await dataStore.DeleteAsync(key).ConfigureAwait(false); } } var documentContext = new DocumentContext(allDocumentHistories, blobKeysSet, services); var maintainanceDocumentsByPath = documentContext.Documents.Where(d => !d.Deleted).ToLookup(d => d.Path); foreach (var dbDoc in allDocuments.Where(d => !string.IsNullOrEmpty(d.Path)).OrderBy(d => d.LastModified)) { if (!maintainanceDocumentsByPath[dbDoc.Path].Any()) { logger.LogWarning("no history document found. path: " + dbDoc.Path); await Task.Delay(300).ConfigureAwait(false); using (var context = CreateContext(configuration)) { var created = new DocumentHistory() { Id = Guid.NewGuid(), Discriminator = DocumentHistoryDiscriminator.DocumentCreated, Timestamp = DateTime.UtcNow, DocumentId = dbDoc.Id, Path = dbDoc.Path, StorageKey = dbDoc.StorageKey, ContentType = dbDoc.ContentType, FileSize = dbDoc.FileSize, Hash = dbDoc.Hash, Created = dbDoc.Created, LastModified = dbDoc.LastModified }; context.DocumentHistories.Add(created); var _blob = await context.Blobs.FindAsync(dbDoc.Path).ConfigureAwait(false); if (_blob != null) { context.Blobs.Remove(_blob); } var docPath = new DocumentPath(dbDoc.Path); await EnsureDirectoryExists(context, docPath.Parent).ConfigureAwait(false); context.Blobs.Add(new Blob() { Path = dbDoc.Path, Name = docPath.Name, ParentPath = docPath.Parent?.Value, DocumentId = dbDoc.Id, StorageKey = dbDoc.StorageKey, ContentType = dbDoc.ContentType, FileSize = dbDoc.FileSize, Hash = dbDoc.Hash, Created = dbDoc.Created, LastModified = dbDoc.LastModified, }); await context.SaveChangesAsync().ConfigureAwait(false); documentContext.Apply(created); } } } using (var context = CreateContext(configuration)) { var historyIdsToRemove = documentContext.DeletableHistories.Select(h => h.Id).ToList(); var rep = (historyIdsToRemove.Count / 1000) + 1; for (var i = 0; i < rep; i++) { var historyIdsToRemoveSubset = historyIdsToRemove.Skip(i * 1000).Take(1000).ToList(); var historiesToRemove = context.DocumentHistories.Where(h => historyIdsToRemoveSubset.Contains(h.Id)); context.DocumentHistories.RemoveRange(historiesToRemove); await context.SaveChangesAsync().ConfigureAwait(false); } } foreach (var doc in documentContext.Documents) { var firstHistory = doc.Histories.First(); if (firstHistory.Discriminator == DocumentHistoryDiscriminator.DocumentDeleted) { logger.LogWarning("deleting invalid first history. path: " + firstHistory.Path); using (var context = CreateContext(configuration)) { var history = await context.DocumentHistories.FindAsync(firstHistory.Id).ConfigureAwait(false); context.DocumentHistories.Remove(history); await context.SaveChangesAsync().ConfigureAwait(false); } if (doc.Histories.Count == 1) { continue; } } if (firstHistory.Discriminator == DocumentHistoryDiscriminator.DocumentUpdated) { logger.LogWarning("fix first history discriminator to document created. path: " + firstHistory.Path); using (var context = CreateContext(configuration)) { var history = await context.DocumentHistories.FindAsync(firstHistory.Id).ConfigureAwait(false); history.Discriminator = DocumentHistoryDiscriminator.DocumentCreated; context.DocumentHistories.Update(history); await context.SaveChangesAsync().ConfigureAwait(false); } } if (doc.Histories.Count > 1) { var lastHistory = doc.Histories.Last(); if (lastHistory.Discriminator == DocumentHistoryDiscriminator.DocumentCreated) { logger.LogWarning("fix last history discriminator to document updated. path: " + lastHistory.Path); using (var context = CreateContext(configuration)) { var history = await context.DocumentHistories.FindAsync(lastHistory.Id).ConfigureAwait(false); history.Discriminator = DocumentHistoryDiscriminator.DocumentUpdated; context.DocumentHistories.Update(history); await context.SaveChangesAsync().ConfigureAwait(false); } } foreach (var history in doc.Histories.Skip(1).Where(h => h != lastHistory)) { if (history.Discriminator == DocumentHistoryDiscriminator.DocumentCreated) { logger.LogWarning("fix history discriminator to document updated. path: " + history.Path); using (var context = CreateContext(configuration)) { var _history = await context.DocumentHistories.FindAsync(lastHistory.Id).ConfigureAwait(false); _history.Discriminator = DocumentHistoryDiscriminator.DocumentUpdated; context.DocumentHistories.Update(_history); await context.SaveChangesAsync().ConfigureAwait(false); } } } } } var documentIds = new HashSet <int>(allDocuments.Select(d => d.Id)); var paths = new HashSet <string>(allBlobs.Select(b => b.Path)); var allDocumentsByPath = allDocuments.ToLookup(d => d.Path); var allBlobsByPath = allBlobs.ToLookup(d => d.Path); foreach (var doc in documentContext.Documents) { if (doc.Deleted) { var documentCandidates = allDocumentsByPath[null] .Where(d => d.Hash == doc.Hash && d.FileSize == doc.FileSize && d.Created == doc.Created && d.LastModified == doc.LastModified) .ToList(); if (documentCandidates.Count != 1) { logger.LogWarning("virtual document where real document not found or specified. path: " + doc.Path); using (var context = CreateContext(configuration)) { var historyIdsToRemove = doc.Histories.Select(h => h.Id).ToList(); var historiesToRemove = context.DocumentHistories.Where(h => historyIdsToRemove.Contains(h.Id)); context.DocumentHistories.RemoveRange(historiesToRemove); await context.SaveChangesAsync().ConfigureAwait(false); } continue; } var document = documentCandidates.First(); await FixHistoryIfNeededAsync(configuration, document, doc).ConfigureAwait(false); documentIds.Remove(document.Id); } else { var document = allDocumentsByPath[doc.Path].SingleOrDefault(); if (document == null) { logger.LogWarning("virtual document where real document not found or specified. path: " + doc.Path); using (var context = CreateContext(configuration)) { var historyIdsToRemove = doc.Histories.Select(h => h.Id).ToList(); var historiesToRemove = context.DocumentHistories.Where(h => historyIdsToRemove.Contains(h.Id)); context.DocumentHistories.RemoveRange(historiesToRemove); await context.SaveChangesAsync().ConfigureAwait(false); } continue; } if (document.Hash != doc.Hash || document.FileSize != doc.FileSize || document.Hash != doc.Hash || document.StorageKey != doc.StorageKey || document.ContentType != doc.ContentType || document.LastModified != doc.LastModified || document.Created != doc.Created) { logger.LogWarning("document props does not match history. creating path. path: " + doc.Path); using (var context = CreateContext(configuration)) { var created = new DocumentHistory() { Id = Guid.NewGuid(), Discriminator = DocumentHistoryDiscriminator.DocumentUpdated, Timestamp = DateTime.UtcNow, DocumentId = document.Id, Path = document.Path, StorageKey = document.StorageKey, ContentType = document.ContentType, FileSize = document.FileSize, Hash = document.Hash, Created = document.Created, LastModified = document.LastModified }; context.DocumentHistories.Add(created); await context.SaveChangesAsync().ConfigureAwait(false); documentContext.Apply(created); } } await FixHistoryIfNeededAsync(configuration, document, doc).ConfigureAwait(false); var blob = allBlobsByPath[document.Path].SingleOrDefault(); if (blob == null || blob.DocumentId != document.Id || blob.FileSize != document.FileSize || blob.Hash != document.Hash || blob.StorageKey != document.StorageKey || blob.ContentType != document.ContentType || blob.LastModified != document.LastModified || blob.Created != document.Created) { using (var context = CreateContext(configuration)) { var _blob = await context.Blobs.FindAsync(blob.Path).ConfigureAwait(false); if (_blob != null) { context.Blobs.Remove(_blob); } var docPath = new DocumentPath(document.Path); await EnsureDirectoryExists(context, docPath.Parent).ConfigureAwait(false); context.Blobs.Add(new Blob() { Path = document.Path, Name = docPath.Name, ParentPath = docPath.Parent?.Value, DocumentId = document.Id, StorageKey = document.StorageKey, ContentType = document.ContentType, FileSize = document.FileSize, Hash = document.Hash, Created = document.Created, LastModified = document.LastModified, }); await context.SaveChangesAsync().ConfigureAwait(false); } } documentIds.Remove(document.Id); } doc.Histories .Select(h => h.StorageKey) .Where(h => !string.IsNullOrEmpty(h)) .ToList() .ForEach(h => blobKeysSet.Remove(h)); } foreach (var documentId in documentIds) { using (var context = CreateContext(configuration)) { var document = await context.Documents.FindAsync(documentId).ConfigureAwait(false); if (document != null) { context.Documents.Remove(document); } var blobs = await context.Blobs.FirstOrDefaultAsync(b => b.DocumentId == documentId).ConfigureAwait(false); if (blobs != null) { context.Blobs.RemoveRange(blobs); } if (document != null || blobs != null) { logger.LogWarning("delete document id: " + documentId + (document != null ? document.Path != null ? " path:" + document.Path : "" : "")); await context.SaveChangesAsync().ConfigureAwait(false); } } } foreach (var key in blobKeysSet) { logger.LogWarning("delete data for key: " + key); await dataStore.DeleteAsync(key).ConfigureAwait(false); } using (var context = CreateContext(configuration)) { var emptyContainers = await context.BlobContainers .Include(b => b.Entries) .Where(b => !b.Entries.Any()) .ToListAsync() .ConfigureAwait(false); context.BlobContainers.RemoveRange(emptyContainers); await context.SaveChangesAsync().ConfigureAwait(false); } }
private TangerineApp(string[] args) { ChangeTangerineSettingsFolderIfNeed(); Orange.UserInterface.Instance = new OrangeInterface(); Orange.UserInterface.Instance.Initialize(); Widget.EnableViewCulling = false; WidgetInput.AcceptMouseBeyondWidgetByDefault = false; if (!UserPreferences.Initialize()) { UserPreferences.Instance.Clear(); UserPreferences.Instance.Add(new AppUserPreferences()); UserPreferences.Instance.Add(new UI.SceneView.SceneUserPreferences()); UserPreferences.Instance.Add(new UI.Timeline.TimelineUserPreferences()); UserPreferences.Instance.Add(new UI.FilesystemView.FilesystemUserPreferences()); UserPreferences.Instance.Add(new CoreUserPreferences()); } #if WIN TangerineSingleInstanceKeeper.Initialize(args); TangerineSingleInstanceKeeper.AnotherInstanceArgsRecieved += OpenDocumentsFromArgs; Application.Exited += () => { TangerineSingleInstanceKeeper.Instance.ReleaseInstance(); }; #endif switch (AppUserPreferences.Instance.ColorThemeKind) { case ColorTheme.ColorThemeKind.Light: SetColorTheme(ColorTheme.CreateLightTheme(), Theme.ColorTheme.CreateLightTheme()); break; case ColorTheme.ColorThemeKind.Dark: SetColorTheme(ColorTheme.CreateDarkTheme(), Theme.ColorTheme.CreateDarkTheme()); break; case ColorTheme.ColorThemeKind.Custom: { bool isDark = AppUserPreferences.Instance.ColorTheme.IsDark; ColorTheme theme = null; var flags = BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Instance; foreach (var category in typeof(ColorTheme).GetProperties(flags)) { var categoryValue = category.GetValue(AppUserPreferences.Instance.ColorTheme); if (categoryValue == null) { if (theme == null) { theme = isDark ? ColorTheme.CreateDarkTheme() : ColorTheme.CreateLightTheme(); } category.SetValue(AppUserPreferences.Instance.ColorTheme, category.GetValue(theme)); category.SetValue(theme, null); } } SetColorTheme(AppUserPreferences.Instance.ColorTheme, AppUserPreferences.Instance.LimeColorTheme); break; } } Application.InvalidateWindows(); LoadFont(); DockManager.Initialize(new Vector2(1024, 768)); DockManager.Instance.DocumentAreaDropFilesGesture.Recognized += new ScenesDropHandler { ShouldCreateContextMenu = false }.Handle; TangerineMenu.Create(); var mainWidget = DockManager.Instance.MainWindowWidget; mainWidget.Window.AllowDropFiles = true; mainWidget.AddChangeWatcher(() => Project.Current, _ => { SetupMainWindowTitle(mainWidget); TangerineMenu.RebuildCreateImportedTypeMenu(); }); mainWidget.AddChangeWatcher(() => CoreUserPreferences.Instance.AnimationMode, _ => Document.Current?.ForceAnimationUpdate()); mainWidget.AddChangeWatcher(() => Document.Current?.Container, _ => Document.Current?.ForceAnimationUpdate()); Application.Exiting += () => Project.Current.Close(); Application.Exited += () => { AppUserPreferences.Instance.DockState = DockManager.Instance.ExportState(); SceneUserPreferences.Instance.VisualHintsRegistry = VisualHintsRegistry.Instance; Core.UserPreferences.Instance.Save(); Orange.The.Workspace.Save(); }; var timelinePanel = new Panel("Timeline"); var inspectorPanel = new Panel("Inspector"); var searchPanel = new Panel("Hierarchy"); var animationsPanel = new Panel("Animations"); var filesystemPanel = new Panel("Filesystem"); var consolePanel = new Panel("Console"); var backupHistoryPanel = new Panel("Backups"); var documentPanel = new Panel(DockManager.DocumentAreaId, undockable: false); documentPanel.PanelWidget = documentPanel.ContentWidget; var visualHintsPanel = new Panel("Visual Hints"); var attachmentPanel = new Panel("Model3D Attachment"); var remoteScriptingPanel = new Panel("Remote Scripting"); var dockManager = DockManager.Instance; new UI.Console(consolePanel); var root = dockManager.Model.WindowPlacements.First(); var placement = new LinearPlacement(LinearPlacementDirection.Horizontal); dockManager.AddPanel(timelinePanel, root, DockSite.Top, 0.3f); dockManager.DockPlacementTo(placement, root, DockSite.Bottom, 0.6f); dockManager.AppendPanelTo(documentPanel, placement, 0.5f); var commandHandlerList = CommandHandlerList.Global; var commandsDictionary = new Dictionary <string, Command> { { animationsPanel.Id, new Command(animationsPanel.Title) }, { timelinePanel.Id, new Command(timelinePanel.Title) }, { inspectorPanel.Id, new Command(inspectorPanel.Title) }, { searchPanel.Id, new Command(searchPanel.Title) }, { filesystemPanel.Id, new Command(filesystemPanel.Title) }, { consolePanel.Id, new Command(consolePanel.Title) }, { backupHistoryPanel.Id, new Command(backupHistoryPanel.Title) }, { visualHintsPanel.Id, new Command(visualHintsPanel.Title) }, { attachmentPanel.Id, new Command(attachmentPanel.Title) }, { remoteScriptingPanel.Id, new Command(remoteScriptingPanel.Title) }, }; foreach (var pair in commandsDictionary) { commandHandlerList.Connect(pair.Value, new PanelCommandHandler(pair.Key)); TangerineMenu.PanelsMenu.Add(pair.Value); } dockManager.AddPanel(inspectorPanel, placement, DockSite.Left); var filesystemPlacement = dockManager.AddPanel(filesystemPanel, placement, DockSite.Right); dockManager.AddPanel(searchPanel, filesystemPlacement, DockSite.Fill); dockManager.AddPanel(animationsPanel, filesystemPlacement, DockSite.Fill); dockManager.AddPanel(backupHistoryPanel, filesystemPlacement, DockSite.Fill); dockManager.AddPanel(consolePanel, filesystemPlacement, DockSite.Bottom, 0.3f); dockManager.AddPanel(visualHintsPanel, placement, DockSite.Right, 0.3f).Hidden = true; dockManager.AddPanel(attachmentPanel, placement, DockSite.Bottom, 0.3f).Hidden = true; dockManager.AddPanel(remoteScriptingPanel, placement, DockSite.Right, 0.3f).Hidden = true; DockManagerInitialState = dockManager.ExportState(); var documentViewContainer = InitializeDocumentArea(dockManager); documentPanel.ContentWidget.Nodes.Add(dockManager.DocumentArea); dockManager.ImportState(AppUserPreferences.Instance.DockState); Document.CloseConfirmation += doc => { var alert = new AlertDialog($"Save the changes to document '{doc.Path}' before closing?", "Yes", "No", "Cancel"); switch (alert.Show()) { case 0: return(Document.CloseAction.SaveChanges); case 1: return(Document.CloseAction.DiscardChanges); case -1: default: return(Document.CloseAction.Cancel); } }; mainWidget.Tasks.Add(HandleMissingDocumentsTask); Project.HandleMissingDocuments += missingDocuments => { foreach (var d in missingDocuments) { missingDocumentsList.Add(d); } }; Project.DocumentReloadConfirmation += doc => { if (doc.IsModified) { var modifiedAlert = new AlertDialog($"{doc.Path}\n\nThis file has been modified by another program and has unsaved changes.\nDo you want to reload it from disk? ", "Yes", "No"); var res = modifiedAlert.Show(); if (res == 1 || res == -1) { doc.History.ExternalModification(); return(false); } return(true); } if (CoreUserPreferences.Instance.ReloadModifiedFiles) { return(true); } var alert = new AlertDialog($"{doc.Path}\n\nThis file has been modified by another program.\nDo you want to reload it from disk? ", "Yes, always", "Yes", "No"); var r = alert.Show(); if (r == 0) { CoreUserPreferences.Instance.ReloadModifiedFiles = true; return(true); } if (r == 2) { doc.History.ExternalModification(); return(false); } return(true); }; Project.TempFileLoadConfirmation += path => { var alert = new AlertDialog($"Do you want to load autosaved version of '{path}'?", "Yes", "No"); return(alert.Show() == 0); }; Project.OpenFileOutsideProjectAttempt += (string filePath) => { var projectFilePath = SearhForCitproj(filePath); if (projectFilePath != null && Project.Current.CitprojPath != projectFilePath) { var alert = new AlertDialog($"You're trying to open a document outside the project directory. Change the current project to '{Path.GetFileName(projectFilePath)}'?", "Yes", "No"); if (alert.Show() == 0) { if (FileOpenProject.Execute(projectFilePath)) { Project.Current.OpenDocument(filePath, true); } return; } } else if (projectFilePath == null) { AlertDialog.Show("Can't open a document outside the project directory"); } }; Project.Tasks = dockManager.MainWindowWidget.Tasks; Project.Tasks.Add(new AutosaveProcessor(() => AppUserPreferences.Instance.AutosaveDelay)); BackupManager.Instance.Activate(Project.Tasks); Document.NodeDecorators.AddFor <Spline>(n => n.CompoundPostPresenter.Add(new UI.SceneView.SplinePresenter())); Document.NodeDecorators.AddFor <Viewport3D>(n => n.CompoundPostPresenter.Add(new UI.SceneView.Spline3DPresenter())); Document.NodeDecorators.AddFor <Viewport3D>(n => n.CompoundPostPresenter.Add(new UI.SceneView.Animation3DPathPresenter())); Document.NodeDecorators.AddFor <Widget>(n => { if (n.AsWidget.SkinningWeights == null) { n.AsWidget.SkinningWeights = new SkinningWeights(); } }); Document.NodeDecorators.AddFor <PointObject>(n => { if ((n as PointObject).SkinningWeights == null) { (n as PointObject).SkinningWeights = new SkinningWeights(); } }); Animation.EasingEnabledChecker = (animation) => { var doc = Document.Current; return(doc == null || doc.PreviewScene || animation != doc.Animation); }; if (SceneUserPreferences.Instance.VisualHintsRegistry != null) { VisualHintsRegistry.Instance = SceneUserPreferences.Instance.VisualHintsRegistry; } VisualHintsRegistry.Instance.RegisterDefaultHints(); Document.NodeDecorators.AddFor <Node>(n => n.SetTangerineFlag(TangerineFlags.SceneNode, true)); dockManager.UnhandledExceptionOccurred += e => { AlertDialog.Show(e.Message + "\n" + e.StackTrace); var doc = Document.Current; if (doc != null) { while (doc.History.IsTransactionActive) { doc.History.EndTransaction(); } var closeConfirmation = Document.CloseConfirmation; try { Document.CloseConfirmation = d => { var alert = new AlertDialog($"Save the changes to document '{d.Path}' before closing?", "Yes", "No"); switch (alert.Show()) { case 0: return(Document.CloseAction.SaveChanges); default: return(Document.CloseAction.DiscardChanges); } }; var fullPath = doc.FullPath; if (!File.Exists(fullPath)) { doc.Save(); } var path = doc.Path; Project.Current.CloseDocument(doc); Project.Current.OpenDocument(path); } finally { Document.CloseConfirmation = closeConfirmation; } } }; Document.NodeDecorators.AddFor <ParticleEmitter>(n => n.CompoundPostPresenter.Add(new UI.SceneView.ParticleEmitterPresenter())); DocumentHistory.AddOperationProcessorTypes(new[] { typeof(Core.Operations.TimelineHorizontalShift.Processor), typeof(Core.Operations.TimelineColumnRemove.Processor), typeof(Core.Operations.RemoveKeyframeRange.Processor), typeof(Core.Operations.SelectRow.Processor), typeof(Core.Operations.RenameAnimationProcessor), typeof(Core.Operations.SetProperty.Processor), typeof(Core.Operations.SetIndexedProperty.Processor), typeof(Core.Operations.RemoveKeyframe.Processor), typeof(Core.Operations.SetKeyframe.Processor), typeof(Core.Operations.InsertFolderItem.Processor), typeof(Core.Operations.AddIntoCollection <,> .Processor), typeof(Core.Operations.RemoveFromCollection <,> .Processor), typeof(Core.Operations.InsertIntoList.Processor), typeof(Core.Operations.RemoveFromList.Processor), typeof(Core.Operations.InsertIntoList <,> .Processor), typeof(Core.Operations.RemoveFromList <,> .Processor), typeof(Core.Operations.UnlinkFolderItem.Processor), typeof(Core.Operations.MoveNodes.Processor), typeof(Core.Operations.SetMarker.Processor), typeof(Core.Operations.DeleteMarker.Processor), typeof(Core.Operations.SetComponent.Processor), typeof(Core.Operations.DeleteComponent.Processor), typeof(Core.Operations.DistortionMeshProcessor), typeof(Core.Operations.SyncFolderDescriptorsProcessor), typeof(UI.SceneView.ResolutionPreviewOperation.Processor), typeof(UI.Timeline.Operations.SelectGridSpan.Processor), typeof(UI.Timeline.Operations.DeselectGridSpan.Processor), typeof(UI.Timeline.Operations.ClearGridSelection.Processor), typeof(UI.Timeline.Operations.ShiftGridSelection.Processor), typeof(UI.Timeline.Operations.SetCurrentColumn.Processor), typeof(UI.Timeline.Operations.SelectCurveKey.Processor), typeof(TriggersValidatorOnSetProperty), typeof(TriggersValidatorOnSetKeyframe), typeof(UpdateNodesAndApplyAnimatorsProcessor), typeof(RowsSynchronizer), typeof(Core.Operations.ReplaceContents.Processor), typeof(Core.Operations.DeleteRuler.Processor), typeof(Core.Operations.CreateRuler.Processor), }); DocumentHistory.AddOperationProcessorTypes(UI.Timeline.Timeline.GetOperationProcessorTypes()); RegisterCommands(); InitializeHotkeys(); AppUserPreferences.Instance.ToolbarModel.RefreshAfterLoad(); Toolbar = new ToolbarView(dockManager.ToolbarArea, AppUserPreferences.Instance.ToolbarModel); RefreshCreateNodeCommands(); Document.AttachingViews += doc => { if (doc.Views.Count == 0) { doc.Views.AddRange(new IDocumentView[] { new UI.Inspector.Inspector(inspectorPanel.ContentWidget), new UI.Timeline.Timeline(timelinePanel), new UI.SceneView.SceneView(documentViewContainer), new Panels.HierarchyPanel(searchPanel.ContentWidget), new Panels.BackupHistoryPanel(backupHistoryPanel.ContentWidget), new Panels.AnimationsPanel(animationsPanel.ContentWidget), // Use VisualHintsPanel sigleton because we need preserve its state between documents. VisualHintsPanel.Instance ?? VisualHintsPanel.Initialize(visualHintsPanel), new AttachmentPanel(attachmentPanel), }); UI.SceneView.SceneView.ShowNodeDecorationsPanelButton.Clicked = () => dockManager.TogglePanel(visualHintsPanel); } }; var proj = AppUserPreferences.Instance.CurrentProject; if (proj != null) { try { new Project(proj).Open(); } catch { AlertDialog.Show($"Cannot open project '{proj}'. It may be deleted or be otherwise unavailable."); } } OpenDocumentsFromArgs(args); WidgetContext.Current.Root.AddChangeWatcher(() => Project.Current, project => TangerineMenu.OnProjectChanged(project)); WidgetContext.Current.Root.AddChangeWatcher(() => ProjectUserPreferences.Instance.RecentDocuments.Count == 0 ? null : ProjectUserPreferences.Instance.RecentDocuments[0], document => TangerineMenu.RebuildRecentDocumentsMenu()); WidgetContext.Current.Root.AddChangeWatcher(() => AppUserPreferences.Instance.RecentProjects.Count == 0 ? null : AppUserPreferences.Instance.RecentProjects[0], document => TangerineMenu.RebuildRecentProjectsMenu()); new UI.FilesystemView.FilesystemPane(filesystemPanel); new UI.RemoteScripting.RemoteScriptingPane(remoteScriptingPanel); RegisterGlobalCommands(); Documentation.Init(); DocumentationComponent.Clicked = page => Documentation.ShowHelp(page); }