protected virtual void OnAttributeContextMenu(AttributeContextMenuArgs args) { }
protected internal virtual void AttributeContextMenu(AttributeContextMenuArgs args) { var attr = args.Attribute; var attrWithRef = args.Attribute as PersistentObjectAttributeWithReference; #region Email // Send Email if (!attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && DataTypes.Text.Contains(attr.Type) && (attr.Rules.Contains("IsEmail") || attr.Rules.Contains("IsValidEmail"))) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["SendEmail"], async _ => { var mail = new Uri("mailto:" + attr.DisplayValue); await Launcher.LaunchUriAsync(mail); })); } #endregion #region Copy // Copy if (!attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && (DataTypes.Text.Contains(attr.Type) || DataTypes.Numeric.Contains(attr.Type) || DataTypes.Dates.Contains(attr.Type))) args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["Copy"], _ => Clipboard.SetText(attr.DisplayValue))); #endregion #region DateTimeOffset if (attr.Parent.IsInEdit && !attr.IsReadOnly && (attr.ClrType == typeof(DateTime) || attr.ClrType == typeof(DateTime?) || attr.ClrType == typeof(DateTimeOffset) || attr.ClrType == typeof(DateTimeOffset?) || attr.ClrType == typeof(TimeSpan) || attr.ClrType == typeof(TimeSpan?))) { DateTime? date = null; DateTimeOffset? offset = null; var isOffset = false; var isTime = false; var nullable = false; if (attr.ClrType == typeof(DateTime)) date = (DateTime)attr.Value; else if (attr.ClrType == typeof(DateTime?)) { date = (DateTime?)attr.Value; nullable = true; } else if (attr.ClrType == typeof(TimeSpan)) { isTime = true; date = new DateTime(((TimeSpan)attr.Value).Ticks); } else if (attr.ClrType == typeof(TimeSpan?)) { isTime = true; nullable = true; var ts = (TimeSpan?)attr.Value; if (ts.HasValue) date = new DateTime(ts.Value.Ticks); } else if (attr.ClrType == typeof(DateTimeOffset)) { isOffset = true; offset = (DateTimeOffset)attr.Value; date = offset.Value.DateTime; } else if (attr.ClrType == typeof(DateTimeOffset?)) { isOffset = true; offset = (DateTimeOffset?)attr.Value; date = offset.HasValue ? new DateTime?(offset.Value.DateTime) : null; nullable = true; } if (attr.Type.Contains("Date")) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["SetDate"], async _ => { var newDate = await date.OpenDatePicker(); if (newDate.HasValue && newDate.Value != date.GetValueOrDefault()) { if (!isOffset) attr.Value = newDate; else attr.Value = offset.HasValue ? new DateTimeOffset(newDate.Value, offset.Value.Offset) : new DateTimeOffset(newDate.Value); } })); } if (attr.Type.Contains("Time")) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["SetTime"], async _ => { var newTime = await date.OpenTimePicker(); if (newTime.HasValue && newTime.Value != date.GetValueOrDefault()) { if (!isOffset && !isTime) attr.Value = newTime; else if (isTime) attr.Value = new TimeSpan(newTime.Value.TimeOfDay.Hours, newTime.Value.TimeOfDay.Minutes, newTime.Value.TimeOfDay.Seconds); else if (isOffset) attr.Value = offset.HasValue ? new DateTimeOffset(newTime.Value, offset.Value.Offset) : new DateTimeOffset(newTime.Value); } })); } if (isOffset) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["SetTimeZone"], async _ => { string err = null; try { var timeZoneQuery = Client.CurrentClient.GetCachedObject<Query>("94b37097-6496-4d32-ae0b-99770defa828"); if (timeZoneQuery == null) { timeZoneQuery = await Service.Current.GetQueryAsync("94b37097-6496-4d32-ae0b-99770defa828"); if (timeZoneQuery != null) Client.CurrentClient.AddCachedObject(timeZoneQuery, "94b37097-6496-4d32-ae0b-99770defa828"); } Client.RootFrame.Navigate(new Uri("/Vidyano.Phone;component/View/Pages/QueryItemSelectPage.xaml?parent=" + attr.Parent.PagePath + "&attribute=" + attr.Name, UriKind.Relative)); } catch (Exception e) { err = e.Message; } if (!string.IsNullOrEmpty(err)) await Service.Current.Hooks.ShowNotification(err, NotificationType.Error); })); } if (attr.Value != null && !attr.IsRequired && nullable) args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["Clear"], _ => attr.Value = null)); args.AutoExecuteFirst = args.Commands.Count == 1; } #endregion #region Images // Open Image if (attr.ValueDirect != null && !attr.IsReadOnly && attr.Type == DataTypes.Image) { string ext = null; if (attr.ValueDirect.StartsWith("iVBOR")) ext = ".png"; else if (attr.ValueDirect.StartsWith("/9j/")) ext = ".jpg"; else if (attr.ValueDirect.StartsWith("R0lGOD")) ext = ".gif"; if (ext != null) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["OpenImage"], async _ => { var folder = ApplicationData.Current.LocalFolder; var file = await folder.CreateFileAsync(attr.Name + ext, CreationCollisionOption.ReplaceExisting); using (var s = await file.OpenStreamForWriteAsync()) { var bytes = Convert.FromBase64String(attr.ValueDirect); await s.WriteAsync(bytes, 0, bytes.Length); } await Launcher.LaunchFileAsync(file); })); args.AutoExecuteFirst = args.Commands.Count == 1; } } // Change Image if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.Image) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["ChangeImage"], _ => { var chooser = new PhotoChooserTask(); chooser.ShowCamera = true; int maxCaptureWidth = 720, maxCaptureHeight = 720; var captSize = attr.TypeHints["MaxCaptureResolution"]; if (captSize != null) { if (captSize != "Auto") { var parts = captSize.Split(new[] { 'x', 'X' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { if (!int.TryParse(parts[0], out maxCaptureWidth) || !int.TryParse(parts[1], out maxCaptureHeight)) maxCaptureWidth = maxCaptureHeight = 720; } } else maxCaptureWidth = maxCaptureHeight = 0; } if (maxCaptureWidth > 0 && maxCaptureHeight > 0) { chooser.PixelWidth = maxCaptureWidth; chooser.PixelHeight = maxCaptureHeight; } chooser.Completed += (sender, e) => { if (e.ChosenPhoto == null) return; var memoryStream = new MemoryStream(); e.ChosenPhoto.CopyTo(memoryStream); attr.Value = Convert.ToBase64String(memoryStream.ToArray()); }; chooser.Show(); })); args.AutoExecuteFirst = args.Commands.Count == 1; } // Remove Image if (attr.Parent.IsInEdit && !attr.IsReadOnly && !attr.IsRequired && attr.Type == DataTypes.Image && attr.Value != null) args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["RemoveImage"], _ => attr.Value = null)); #endregion #region BinaryFile // Open File if (attr.Type == DataTypes.BinaryFile && attr.Value != null) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["Open"], async _ => { var str = (args.Attribute.Value as String) ?? string.Empty; var parts = str.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2 && !string.IsNullOrEmpty(parts[0]) && !string.IsNullOrEmpty(parts[1])) { var folder = ApplicationData.Current.LocalFolder; var file = await folder.CreateFileAsync(parts[0], CreationCollisionOption.ReplaceExisting); using (var s = await file.OpenStreamForWriteAsync()) { var bytes = Convert.FromBase64String(parts[1]); await s.WriteAsync(bytes, 0, bytes.Length); } await Launcher.LaunchFileAsync(file); } })); args.AutoExecuteFirst = true; } #endregion #region Reference // Open Reference if (attr.Type == DataTypes.Reference && !string.IsNullOrEmpty(attr.DisplayValue) && attrWithRef.Lookup.CanRead && (!attr.Parent.IsInEdit || !attrWithRef.SelectInPlace)) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["OpenReference"], async _ => { try { await new Navigate().Execute(Service.Current.GetPersistentObjectAsync(attrWithRef.Lookup.PersistentObject.Id, attrWithRef.ObjectId)); } catch (Exception ex) { attrWithRef.Parent.SetNotification(ex.Message); } })); args.AutoExecuteFirst = args.Commands.Count == 1; } // Change Reference if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages[attr.Value != null ? "ChangeReference" : "SetReference"], _ => { attrWithRef.Lookup.SelectedItems.Clear(); Client.RootFrame.Navigate(new Uri("/Vidyano.Phone;component/View/Pages/QueryItemSelectPage.xaml?parent=" + attrWithRef.Parent.PagePath + "&attribute=" + attrWithRef.Name + "&navigationState=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(Client.RootFrame.GetNavigationState())), UriKind.Relative)); })); args.AutoExecuteFirst = args.Commands.Count == 1; } // New Reference if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null && attrWithRef.CanAddNewReference) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["NewReference"], async _ => { var parameters = new Dictionary<string, string> { { "PersistentObjectAttributeId", attrWithRef.Id } }; var po = await Service.Current.ExecuteActionAsync("Query.New", attrWithRef.Parent, attrWithRef.Lookup, null, parameters); if (po != null) { po.OwnerAttributeWithReference = attrWithRef; ((ICommand)new Navigate()).Execute(po); } })); args.AutoExecuteFirst = args.Commands.Count == 1; } // Remove Reference if (attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null && attrWithRef.CanRemoveReference) { args.Commands.Add(new AttributeContextMenuCommand(Service.Current.Messages["RemoveReference"], async _ => { await attrWithRef.ChangeReference(null); })); args.AutoExecuteFirst = args.Commands.Count == 1; } #endregion }
internal async void AttributeContextMenu(AttributeContextMenuArgs args) { var attr = args.Attribute; var attrWithRef = args.Attribute as PersistentObjectAttributeWithReference; #region Email // Send Email if (!attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && DataTypes.Text.Contains(attr.Type) && (attr.Rules.Contains("IsEmail") || attr.Rules.Contains("IsValidEmail"))) { args.Commands.Add(new UICommand(Service.Current.Messages["SendEmail"], async _ => { var mail = new Uri("mailto:" + attr.DisplayValue); await Windows.System.Launcher.LaunchUriAsync(mail); })); } #endregion #region Url // Send Url if (!attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && DataTypes.Text.Contains(attr.Type) && (attr.Rules.Contains("IsUrl") || attr.Rules.Contains("IsValidUrl"))) { args.Commands.Add(new UICommand(Service.Current.Messages["OpenUrl"], async _ => await Windows.System.Launcher.LaunchUriAsync(new Uri(attr.DisplayValue)))); } #endregion #region Copy // Copy if (!attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && (DataTypes.Text.Contains(attr.Type) || DataTypes.Numeric.Contains(attr.Type) || DataTypes.Dates.Contains(attr.Type))) { args.Commands.Add(new UICommand(Service.Current.Messages["Copy"], _ => { var package = new DataPackage(); package.SetText(attr.DisplayValue); Clipboard.SetContent(package); })); } #endregion #region Images // Change Image if (attr.Type == DataTypes.Image) { if (attr.Parent.IsInEdit && !attr.IsReadOnly) { args.Commands.Add(new UICommand(Service.Current.Messages["ChangeImage"], async _ => { if (((ApplicationView.Value != ApplicationViewState.Snapped) || ApplicationView.TryUnsnap())) { var filePicker = new FileOpenPicker(); filePicker.FileTypeFilter.Add(".jpg"); filePicker.FileTypeFilter.Add(".jpeg"); filePicker.FileTypeFilter.Add(".png"); filePicker.FileTypeFilter.Add(".gif"); filePicker.ViewMode = PickerViewMode.Thumbnail; filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; var file = await filePicker.PickSingleFileAsync(); if (file != null) { using (var stream = await file.OpenReadAsync()) { using (var dataReader = new DataReader(stream)) { var bytes = new byte[stream.Size]; await dataReader.LoadAsync((uint)stream.Size); dataReader.ReadBytes(bytes); attr.Value = Convert.ToBase64String(bytes); } } } } })); args.AutoExecuteFirst = args.Commands.Count == 1; } else { var previewFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("preview.png", CreationCollisionOption.ReplaceExisting); await FileIO.WriteBytesAsync(previewFile, Convert.FromBase64String(attr.ValueDirect)); await Windows.System.Launcher.LaunchFileAsync(previewFile); } } // Remove Image if (attr.Parent.IsInEdit && !attr.IsReadOnly && !attr.IsRequired && attr.Type == DataTypes.Image && attr.Value != null) { args.Commands.Add(new UICommand(Service.Current.Messages["RemoveImage"], _ => attr.Value = null)); } #endregion #region BinaryFile // Change File if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.BinaryFile && attr.Value != null) { args.Commands.Add(new UICommand(Service.Current.Messages["ChangeFile"], async _ => { var str = (attr.Value as String) ?? string.Empty; var parts = str.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2 && !string.IsNullOrEmpty(parts[0]) && !string.IsNullOrEmpty(parts[1])) { if (((ApplicationView.Value != ApplicationViewState.Snapped) || ApplicationView.TryUnsnap())) { var filePicker = new FileOpenPicker(); filePicker.ViewMode = PickerViewMode.List; filePicker.FileTypeFilter.Add("*"); filePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; var file = await filePicker.PickSingleFileAsync(); if (file != null) { using (var stream = await file.OpenReadAsync()) { using (var dataReader = new DataReader(stream)) { var bytes = new byte[stream.Size]; await dataReader.LoadAsync((uint)stream.Size); dataReader.ReadBytes(bytes); attr.Value = file.Name + "|" + Convert.ToBase64String(bytes); } } } } } })); args.AutoExecuteFirst = args.Commands.Count == 1; } // Save File if (attr.Type == DataTypes.BinaryFile && attr.Value != null) { args.Commands.Add(new UICommand(Service.Current.Messages["Save"], async _ => { var str = (args.Attribute.Value as String) ?? string.Empty; var parts = str.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2 && !string.IsNullOrEmpty(parts[0]) && !string.IsNullOrEmpty(parts[1])) { if (((ApplicationView.Value != ApplicationViewState.Snapped) || ApplicationView.TryUnsnap())) { var savePicker = new FileSavePicker(); savePicker.FileTypeChoices.Add(Service.Current.Messages["File"], new List<string> { parts[0].Substring(parts[0].LastIndexOf('.')) }); savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; savePicker.SuggestedFileName = parts[0]; var file = await savePicker.PickSaveFileAsync(); if (file != null) await FileIO.WriteBytesAsync(file, Convert.FromBase64String(parts[1])); } } })); } #endregion #region Reference // Open Reference if (attr.Type == DataTypes.Reference && !string.IsNullOrEmpty(attr.DisplayValue) && attrWithRef != null && attrWithRef.Lookup.CanRead && (!attr.Parent.IsInEdit || !attrWithRef.SelectInPlace)) { args.Commands.Add(new UICommand(Service.Current.Messages["OpenReference"], async _ => { try { await new Commands.Navigate().Execute(Service.Current.GetPersistentObjectAsync(attrWithRef.Lookup.PersistentObject.Id, attrWithRef.ObjectId)); } catch (Exception ex) { attrWithRef.Parent.SetNotification(ex.Message); } })); args.AutoExecuteFirst = true; } // Change Reference if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null && !attrWithRef.SelectInPlace) { args.Commands.Add(new UICommand(Service.Current.Messages["ChangeReference"], _ => { var frame = Window.Current.Content as Frame; if (frame != null) { attrWithRef.Lookup.SelectedItems.Clear(); frame.Navigate(typeof(QueryItemSelectPage), new JObject( new JProperty("Parent", attrWithRef.Parent.PagePath), new JProperty("Attribute", attrWithRef.Name), new JProperty("PreviousState", frame.GetNavigationState())).ToString(Formatting.None)); } })); } // New Reference if (attr.Parent.IsInEdit && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null && !attrWithRef.SelectInPlace && attrWithRef.CanAddNewReference) { args.Commands.Add(new UICommand(Service.Current.Messages["NewReference"], async _ => { var parameters = new Dictionary<string, string> { { "PersistentObjectAttributeId", attrWithRef.Id } }; var po = await Service.Current.ExecuteActionAsync("Query.New", attrWithRef.Parent, attrWithRef.Lookup, null, parameters); if (po != null) { po.OwnerAttributeWithReference = attrWithRef; ((System.Windows.Input.ICommand)new Commands.Navigate()).Execute(po); } })); } // Remove Reference if (attr.Parent.IsInEdit && !string.IsNullOrEmpty(attr.DisplayValue) && !attr.IsReadOnly && attr.Type == DataTypes.Reference && attrWithRef != null && !attrWithRef.SelectInPlace && attrWithRef.CanRemoveReference) { args.Commands.Add(new UICommand(Service.Current.Messages["RemoveReference"], async _ => { await attrWithRef.ChangeReference(null); })); } #endregion OnAttributeContextMenu(args); }