Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom find / replace dialog #42

Merged
merged 16 commits into from
Jun 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 29 additions & 10 deletions OfficeRibbonXEditor/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows;
using System.Collections.Generic;
using System.Windows;
using Autofac;
using OfficeRibbonXEditor.Interfaces;
using OfficeRibbonXEditor.Models;
Expand All @@ -15,6 +16,8 @@ public partial class App : Application
{
private readonly IContainer container;

private readonly Dictionary<IContentDialogBase, DialogHost> dialogs = new Dictionary<IContentDialogBase, DialogHost>();

public App()
{
var builder = new ContainerBuilder();
Expand All @@ -25,10 +28,7 @@ public App()
builder.RegisterType<DialogProvider>().As<IDialogProvider>();

builder.RegisterType<MainWindowViewModel>();
builder.RegisterType<DialogHostViewModel>();
builder.RegisterType<SettingsDialogViewModel>();
builder.RegisterType<AboutDialogViewModel>();
builder.RegisterType<CallbackDialogViewModel>();
DialogHostBase.RegisterDialogViewModels(builder);

this.container = builder.Build();
}
Expand All @@ -51,19 +51,38 @@ private void LaunchMainWindow()
var window = new MainWindow();
windowModel.Lexer = new XmlLexer {Editor = window.Editor};
window.DataContext = windowModel;
windowModel.LaunchingDialog += (o, e) => this.LaunchDialog(window, e.Data);
windowModel.LaunchingDialog += (o, e) => this.LaunchDialog(window, e.Content, e.ShowDialog);
windowModel.Closed += (o, e) => window.Close();
window.Show();
}
private void LaunchDialog(Window mainWindow, IContentDialogBase content)

private void LaunchDialog(Window mainWindow, IContentDialogBase content, bool showDialog)
{
if (content.IsUnique && !content.IsClosed && this.dialogs.TryGetValue(content, out var dialog))
{
dialog.Activate();
return;
}

var dialogModel = this.container.Resolve<DialogHostViewModel>();
var dialog = new DialogHost {DataContext = dialogModel, Owner = mainWindow};
dialog = new DialogHost {DataContext = dialogModel, Owner = mainWindow};
dialogModel.Content = content;
content.Closed += (o, e) => dialog.Close();
dialogModel.Closed += (o, e) => dialog.Close();
dialog.ShowDialog();

if (content.IsUnique)
{
this.dialogs[content] = dialog;
}

if (showDialog)
{
dialog.ShowDialog();
}
else
{
dialog.Show();
}
}
}
}
49 changes: 49 additions & 0 deletions OfficeRibbonXEditor/Controls/ClickSelectTextBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace OfficeRibbonXEditor.Controls
{
public class ClickSelectTextBox : TextBox
{
public ClickSelectTextBox()
{
this.AddHandler(PreviewMouseLeftButtonDownEvent,
new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
this.AddHandler(GotKeyboardFocusEvent,
new RoutedEventHandler(SelectAllText), true);
this.AddHandler(MouseDoubleClickEvent,
new RoutedEventHandler(SelectAllText), true);
}

private static void SelectivelyIgnoreMouseButton(object sender,
MouseButtonEventArgs e)
{
// Find the TextBox
DependencyObject parent = e.OriginalSource as UIElement;
while (parent != null && !(parent is TextBox))
parent = VisualTreeHelper.GetParent(parent);

if (parent != null)
{
var textBox = (TextBox)parent;
if (!textBox.IsKeyboardFocusWithin)
{
// If the text box is not yet focussed, give it the focus and
// stop further processing of this click event.
textBox.Focus();
e.Handled = true;
}
}
}

private static void SelectAllText(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is TextBox textBox)
{
textBox.SelectAll();
}
}
}
}
12 changes: 12 additions & 0 deletions OfficeRibbonXEditor/Controls/DialogControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,17 @@ public ResizeMode ResizeMode
get => (ResizeMode) this.GetValue(ResizeModeProperty);
set => this.SetValue(ResizeModeProperty, value);
}

public static readonly DependencyProperty InactiveOpacityProperty = DependencyProperty.Register(
nameof(InactiveOpacity),
typeof(double),
typeof(DialogControl),
new FrameworkPropertyMetadata(1.0));

public double InactiveOpacity
{
get => (double) this.GetValue(InactiveOpacityProperty);
set => this.SetValue(InactiveOpacityProperty, value);
}
}
}
63 changes: 63 additions & 0 deletions OfficeRibbonXEditor/Controls/Forms/FindAllResultsPanel.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 158 additions & 0 deletions OfficeRibbonXEditor/Controls/Forms/FindAllResultsPanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using OfficeRibbonXEditor.Models;
using ScintillaNET;
using CharacterRange = OfficeRibbonXEditor.Models.CharacterRange;

namespace OfficeRibbonXEditor.Controls.Forms
{
using CharacterRange = CharacterRange;

public partial class FindAllResultsPanel : UserControl
{
#region Fields

private List<CharacterRange> _findAllResults;
private Scintilla _scintilla;

#endregion Fields

#region Constructors

/// <summary>
/// Creates a new instance of FindAllResultsPanel
/// </summary>
public FindAllResultsPanel()
{
this.InitializeComponent();

this.FindResultsScintilla.Styles[Style.Default].Font = "Consolas";
this.FindResultsScintilla.Styles[Style.Default].Size = 10;

this.FindResultsScintilla.ClearAll();
}

#endregion Constructors

#region Properties

/// <summary>
/// Gets or sets the Scintilla control that was searched to generate the find results.
/// Allows the FindAllResults list to be double clicked and results indicated in the original Scintilla.
/// </summary>
public Scintilla Scintilla
{
get { return this._scintilla; }
set { this._scintilla = value; }
}

#endregion Properties

#region Methods

/// <summary>
/// Updates the find all results panel
/// </summary>
/// <param name="FindReplace">The FindReplace instance used to generate the find results.</param>
/// <param name="FindAllResults"></param>
public void UpdateFindAllResults(FindReplace FindReplace, List<CharacterRange> FindAllResults)
{
if (FindReplace.Scintilla == null)
return;
else
this.Scintilla = FindReplace.Scintilla;

this._findAllResults = new List<CharacterRange>(FindAllResults);

this.FindResultsScintilla.ClearAll();

Indicator _indicator = this.FindResultsScintilla.Indicators[16];
_indicator.ForeColor = Color.Red;
_indicator.Alpha = 100;
_indicator.Style = IndicatorStyle.RoundBox;
_indicator.Under = true;

this.FindResultsScintilla.IndicatorCurrent = _indicator.Index;

//Write lines
foreach (var item in this._findAllResults)
{
int startLine = this.Scintilla.LineFromPosition(item.cpMin);
int endLine = this.Scintilla.LineFromPosition(item.cpMax);

if (startLine == endLine)
{
string resultsLinePrefix = string.Format("Line {0}: ", startLine + 1);

this.FindResultsScintilla.AppendText(string.Format("{0}{1}",
resultsLinePrefix, this.Scintilla.Lines[startLine].Text));
}
}

//Highlight
int resultLineIndex = 0;
foreach (var item in this._findAllResults)
{
int startLine = this.Scintilla.LineFromPosition(item.cpMin);
int endLine = this.Scintilla.LineFromPosition(item.cpMax);

if (startLine == endLine)
{
string resultsLinePrefix = string.Format("Line {0}: ", startLine + 1);

int LinePos = this.Scintilla.Lines[startLine].Position;
int startPosInLine = item.cpMin - LinePos;

int lastLineStartPos = this.FindResultsScintilla.Lines[resultLineIndex].Position;

this.FindResultsScintilla.IndicatorFillRange(lastLineStartPos + resultsLinePrefix.Length + startPosInLine, item.cpMax - item.cpMin);

resultLineIndex++;
}
}
}

private void FindResultsScintilla_KeyUp(object sender, KeyEventArgs e)
{
int pos = this.FindResultsScintilla.CurrentPosition;
int selectedLine = this.FindResultsScintilla.LineFromPosition(pos);

if (this._findAllResults.Count > selectedLine)
{
CharacterRange CharRange = this._findAllResults[selectedLine];
this.Scintilla.SetSelection(CharRange.cpMin, CharRange.cpMax);
this.Scintilla.ScrollCaret();
}
}

private void FindResultsScintilla_MouseClick(object sender, MouseEventArgs e)
{
int pos = this.FindResultsScintilla.CharPositionFromPointClose((e.Location).X, (e.Location).Y);
if (pos == -1)
return;

int selectedLine = this.FindResultsScintilla.LineFromPosition(pos);

CharacterRange CharRange = this._findAllResults[selectedLine];
this.Scintilla.SetSelection(CharRange.cpMin, CharRange.cpMax);
this.Scintilla.ScrollCaret();
}

private void FindResultsScintilla_MouseDoubleClick(object sender, MouseEventArgs e)
{
int pos = this.FindResultsScintilla.CharPositionFromPointClose((e.Location).X, (e.Location).Y);
if (pos == -1)
return;

int selectedLine = this.FindResultsScintilla.LineFromPosition(pos);

CharacterRange CharRange = this._findAllResults[selectedLine];
this.Scintilla.SetSelection(CharRange.cpMin, CharRange.cpMax);
this.Scintilla.ScrollCaret();
this.Scintilla.Focus();
}

#endregion Methods
}
}
Loading