mirror of
https://github.com/awatertrevi/xamarin-neo4j.git
synced 2026-09-22 09:05:29 +00:00
Syntax highlighting + command palette
This commit is contained in:
@@ -7,7 +7,11 @@
|
|||||||
// © Xamarin.Neo4j.iOS
|
// © Xamarin.Neo4j.iOS
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using CoreGraphics;
|
using CoreGraphics;
|
||||||
|
using Foundation;
|
||||||
using UIKit;
|
using UIKit;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Platform.iOS;
|
using Xamarin.Forms.Platform.iOS;
|
||||||
@@ -19,12 +23,52 @@ namespace Xamarin.Neo4j.iOS.CustomRenderers
|
|||||||
{
|
{
|
||||||
public class QueryEditorRenderer : EditorRenderer
|
public class QueryEditorRenderer : EditorRenderer
|
||||||
{
|
{
|
||||||
|
private readonly string[] _keyWords =
|
||||||
|
{
|
||||||
|
// Clauses
|
||||||
|
"CALL", "CREATE", "DELETE", "DETACH", "FOREACH", "LOAD", "MATCH", "MERGE", "OPTIONAL", "REMOVE", "RETURN", "SET", "START", "UNION", "UNWIND", "WITH",
|
||||||
|
|
||||||
|
// Subclauses
|
||||||
|
"LIMIT", "ORDER", "SKIP", "WHERE", "YIELD",
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
"ASC", "ASCENDING", "ASSERT", "BY", "CSV", "DESC", "DESCENDING", "ON",
|
||||||
|
|
||||||
|
// Expressions
|
||||||
|
"ALL", "CASE", "COUNT", "ELSE", "END", "EXISTS", "THEN", "WHEN",
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
"AND", "AS", "CONTAINS", "DISTINCT", "ENDS", "IN", "IS", "NOT", "OR", "STARTS", "XOR",
|
||||||
|
|
||||||
|
// Schema
|
||||||
|
"CONSTRAINT", "CREATE", "DROP", "EXISTS", "INDEX", "NODE", "KEY", "UNIQUE",
|
||||||
|
|
||||||
|
// Hints
|
||||||
|
"INDEX", "JOIN", "SCAN", "USING",
|
||||||
|
|
||||||
|
// Literals
|
||||||
|
"FALSE", "NULL", "TRUE"
|
||||||
|
};
|
||||||
|
|
||||||
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
||||||
{
|
{
|
||||||
base.OnElementChanged(e);
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (e.NewElement != null)
|
||||||
|
{
|
||||||
|
Element.TextChanged += (sender, args) =>
|
||||||
|
{
|
||||||
|
HighlightWords(_keyWords);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (Control != null && Element != null)
|
if (Control != null && Element != null)
|
||||||
{
|
{
|
||||||
|
Control.AutocorrectionType = UITextAutocorrectionType.No;
|
||||||
|
Control.AutocapitalizationType = UITextAutocapitalizationType.None;
|
||||||
|
Control.SpellCheckingType = UITextSpellCheckingType.No;
|
||||||
|
Control.KeyboardType = UIKeyboardType.Default;
|
||||||
|
|
||||||
var executeButton = new UIBarButtonItem("Execute", UIBarButtonItemStyle.Done, (sender, args) =>
|
var executeButton = new UIBarButtonItem("Execute", UIBarButtonItemStyle.Done, (sender, args) =>
|
||||||
{
|
{
|
||||||
if (Element is QueryEditor queryEditor)
|
if (Element is QueryEditor queryEditor)
|
||||||
@@ -35,15 +79,85 @@ namespace Xamarin.Neo4j.iOS.CustomRenderers
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
|
var keyButtons = new[]
|
||||||
toolbar.Items = new[]
|
|
||||||
{
|
{
|
||||||
|
new UIBarButtonItem("(", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("(")),
|
||||||
|
new UIBarButtonItem(")", UIBarButtonItemStyle.Plain, (sender, args) => InsertText(")")),
|
||||||
|
new UIBarButtonItem("[", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("[")),
|
||||||
|
new UIBarButtonItem("]", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("]")),
|
||||||
|
new UIBarButtonItem(":", UIBarButtonItemStyle.Plain, (sender, args) => InsertText(":")),
|
||||||
|
new UIBarButtonItem("-", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("-")),
|
||||||
|
new UIBarButtonItem("\u2192", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("->")),
|
||||||
|
new UIBarButtonItem("\u2190", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("<-")),
|
||||||
|
|
||||||
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
|
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
|
||||||
|
|
||||||
executeButton
|
executeButton
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
|
||||||
|
toolbar.Items = keyButtons;
|
||||||
|
|
||||||
Control.InputAccessoryView = toolbar;
|
Control.InputAccessoryView = toolbar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HighlightWords(IEnumerable<string> wordsToHighlight)
|
||||||
|
{
|
||||||
|
var text = PreprocessText(Control.Text);
|
||||||
|
var attributedText = new NSMutableAttributedString(text);
|
||||||
|
|
||||||
|
// Iterate through the array and apply formatting to the editor's text.
|
||||||
|
foreach (var word in wordsToHighlight)
|
||||||
|
{
|
||||||
|
var regex = new Regex("\\b" + Regex.Escape(word) + "\\b", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
foreach (Match match in regex.Matches(text))
|
||||||
|
{
|
||||||
|
attributedText.AddAttribute(UIStringAttributeKey.ForegroundColor, Color.FromHex("#89982e").ToUIColor(),
|
||||||
|
new NSRange(match.Index, match.Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply text color formatting for text inside single quotes.
|
||||||
|
ApplyQuoteTextColorFormatting(text, attributedText, "'(.*?)'", Color.FromHex("#ae8b2d").ToUIColor());
|
||||||
|
|
||||||
|
// Apply text color formatting for text inside double quotes.
|
||||||
|
ApplyQuoteTextColorFormatting(text, attributedText, "\"(.*?)\"", Color.FromHex("#ae8b2d").ToUIColor());
|
||||||
|
|
||||||
|
attributedText.AddAttribute(UIStringAttributeKey.Font, UIFont.SystemFontOfSize((nfloat) Element.FontSize), new NSRange(0, attributedText.Length));
|
||||||
|
|
||||||
|
Control.AttributedText = attributedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertText(string text)
|
||||||
|
{
|
||||||
|
Control.InsertText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyQuoteTextColorFormatting(string text, NSMutableAttributedString attributedText,
|
||||||
|
string quotePattern, UIColor color)
|
||||||
|
{
|
||||||
|
var quoteRegex = new Regex(quotePattern);
|
||||||
|
|
||||||
|
foreach (Match match in quoteRegex.Matches(text))
|
||||||
|
{
|
||||||
|
attributedText.AddAttribute(UIStringAttributeKey.ForegroundColor, color,
|
||||||
|
new NSRange(match.Index, match.Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string PreprocessText(string text)
|
||||||
|
{
|
||||||
|
// Replace single quotation marks and their curly variants with: '
|
||||||
|
text = text.Replace("‘", "'");
|
||||||
|
text = text.Replace("’", "'");
|
||||||
|
|
||||||
|
// Replace double quotation marks and their curly variants with: "
|
||||||
|
text = text.Replace("“", "\"");
|
||||||
|
text = text.Replace("”", "\"");
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>nl.resoftware.pocketgraph</string>
|
<string>nl.resoftware.pocketgraph</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0.3</string>
|
<string>4</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.1.0</string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
@@ -26,4 +27,6 @@ using System.Runtime.InteropServices;
|
|||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
||||||
|
[assembly: ExportFont("RobotoMono-Regular.ttf", Alias = "RobotoMonoRegular")]
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using UIKit;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.iOS.Services;
|
using Xamarin.Neo4j.iOS.Services;
|
||||||
using Xamarin.Neo4j.Services;
|
using Xamarin.Neo4j.Services;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
|
|
||||||
[assembly: Dependency(typeof(ScreenSizeService))]
|
[assembly: Dependency(typeof(ScreenSizeService))]
|
||||||
namespace Xamarin.Neo4j.iOS.Services
|
namespace Xamarin.Neo4j.iOS.Services
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Neo4j.Driver;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.iOS.Services;
|
using Xamarin.Neo4j.iOS.Services;
|
||||||
using Xamarin.Neo4j.Services;
|
using Xamarin.Neo4j.Services;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
|
|
||||||
[assembly: Dependency(typeof(TrustManagerService))]
|
[assembly: Dependency(typeof(TrustManagerService))]
|
||||||
namespace Xamarin.Neo4j.iOS.Services
|
namespace Xamarin.Neo4j.iOS.Services
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// VersionService.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 02-03-2024
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j.iOS
|
||||||
|
//
|
||||||
|
|
||||||
|
using Foundation;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.iOS.Services;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
|
|
||||||
|
[assembly: Dependency(typeof(VersionService))]
|
||||||
|
namespace Xamarin.Neo4j.iOS.Services
|
||||||
|
{
|
||||||
|
public class VersionService : IVersionService
|
||||||
|
{
|
||||||
|
public string GetVersion() => NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"]?.ToString();
|
||||||
|
|
||||||
|
public string GetBuild() => NSBundle.MainBundle.InfoDictionary["CFBundleVersion"]?.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@
|
|||||||
<Compile Include="Security\NativeTrustManager.cs" />
|
<Compile Include="Security\NativeTrustManager.cs" />
|
||||||
<Compile Include="Services\ScreenSizeService.cs" />
|
<Compile Include="Services\ScreenSizeService.cs" />
|
||||||
<Compile Include="Services\TrustManagerService.cs" />
|
<Compile Include="Services\TrustManagerService.cs" />
|
||||||
|
<Compile Include="Services\VersionService.cs" />
|
||||||
<None Include="Entitlements.plist" />
|
<None Include="Entitlements.plist" />
|
||||||
<None Include="Info.plist" />
|
<None Include="Info.plist" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|||||||
Binary file not shown.
@@ -18,6 +18,11 @@ namespace Xamarin.Neo4j.Controls
|
|||||||
|
|
||||||
public event EventHandler ExecuteClicked;
|
public event EventHandler ExecuteClicked;
|
||||||
|
|
||||||
|
public QueryEditor()
|
||||||
|
{
|
||||||
|
FontFamily = "RobotoMonoRegular";
|
||||||
|
}
|
||||||
|
|
||||||
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
|
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
|
||||||
{
|
{
|
||||||
var sizeRequest = base.OnMeasure(widthConstraint, heightConstraint);
|
var sizeRequest = base.OnMeasure(widthConstraint, heightConstraint);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
<TableView VerticalOptions="StartAndExpand" Intent="Settings" Background="Transparent">
|
<TableView VerticalOptions="StartAndExpand" Intent="Settings" Background="Transparent">
|
||||||
<TableRoot>
|
<TableRoot>
|
||||||
<TableSection>
|
<TableSection>
|
||||||
|
<TextCell Text="{Binding VersionLabel}" />
|
||||||
<TextCell Text="Software Licenses" Command="{Binding Commands[OpenLicensesPage]}" />
|
<TextCell Text="Software Licenses" Command="{Binding Commands[OpenLicensesPage]}" />
|
||||||
</TableSection>
|
</TableSection>
|
||||||
</TableRoot>
|
</TableRoot>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Xamarin.Neo4j.Services
|
namespace Xamarin.Neo4j.Services.Interfaces
|
||||||
{
|
{
|
||||||
public interface IScreenSizeService
|
public interface IScreenSizeService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Neo4j.Driver;
|
using Neo4j.Driver;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.Services
|
namespace Xamarin.Neo4j.Services.Interfaces
|
||||||
{
|
{
|
||||||
public interface ITrustManagerService
|
public interface ITrustManagerService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Xamarin.Neo4j.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IVersionService
|
||||||
|
{
|
||||||
|
string GetVersion();
|
||||||
|
|
||||||
|
string GetBuild();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ using Neo4jClient.Cypher;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.Models;
|
using Xamarin.Neo4j.Models;
|
||||||
using Xamarin.Neo4j.Services;
|
using Xamarin.Neo4j.Services;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
using Xamarin.Neo4j.Utilities;
|
using Xamarin.Neo4j.Utilities;
|
||||||
|
|
||||||
[assembly: Dependency(typeof(Neo4jService))]
|
[assembly: Dependency(typeof(Neo4jService))]
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using Xamarin.Neo4j.Annotations;
|
|||||||
using Xamarin.Neo4j.Models;
|
using Xamarin.Neo4j.Models;
|
||||||
using Xamarin.Neo4j.Pages;
|
using Xamarin.Neo4j.Pages;
|
||||||
using Xamarin.Neo4j.Services;
|
using Xamarin.Neo4j.Services;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
using Xamarin.Neo4j.Utilities;
|
using Xamarin.Neo4j.Utilities;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.ViewModels
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
|
|||||||
@@ -14,12 +14,17 @@ using Xamarin.Essentials;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.Annotations;
|
using Xamarin.Neo4j.Annotations;
|
||||||
using Xamarin.Neo4j.Pages;
|
using Xamarin.Neo4j.Pages;
|
||||||
|
using Xamarin.Neo4j.Services.Interfaces;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.ViewModels
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
{
|
{
|
||||||
public class SettingsViewModel : ViewModelBase, INotifyPropertyChanged
|
public class SettingsViewModel : ViewModelBase, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
private string _versionLabel { get; set; }
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private IVersionService _versionService { get; set; }
|
||||||
|
|
||||||
public SettingsViewModel(INavigation navigation) : base(navigation)
|
public SettingsViewModel(INavigation navigation) : base(navigation)
|
||||||
{
|
{
|
||||||
@@ -32,6 +37,10 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
{
|
{
|
||||||
await Navigation.PushAsync(new LicensesPage());
|
await Navigation.PushAsync(new LicensesPage());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
_versionService = DependencyService.Get<IVersionService>();
|
||||||
|
|
||||||
|
VersionLabel = $"Version: {_versionService.GetVersion()} (Build: {_versionService.GetBuild()})";
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
@@ -39,5 +48,22 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Bindable Properties
|
||||||
|
|
||||||
|
public string VersionLabel
|
||||||
|
{
|
||||||
|
get => _versionLabel;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_versionLabel = value;
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(VersionLabel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,7 @@
|
|||||||
<EmbeddedResource Include="Visualization\neovis.html" />
|
<EmbeddedResource Include="Visualization\neovis.html" />
|
||||||
<None Remove="Resources\licenses.json" />
|
<None Remove="Resources\licenses.json" />
|
||||||
<EmbeddedResource Include="Resources\licenses.json" />
|
<EmbeddedResource Include="Resources\licenses.json" />
|
||||||
|
<None Remove="Assets\Fonts\RobotoMono-Regular.ttf" />
|
||||||
|
<EmbeddedResource Include="Assets\Fonts\RobotoMono-Regular.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user