diff --git a/data/resources/StringResources.de.resx b/data/resources/StringResources.de.resx
index 12895dac1a..4b9d643011 100644
--- a/data/resources/StringResources.de.resx
+++ b/data/resources/StringResources.de.resx
@@ -229,6 +229,152 @@ Laden Sie ein AddIn aus dem Internet herunter, klicken Sie auf "AddIn installier
Unbekanntes Dateiformat:
+
+ Aus Archiv installieren...
+
+
+ Repository:
+
+
+ Suche:
+
+
+ Vorinstallierte AddIns anzeigen
+
+
+ Prereleases anzeigen
+
+
+ Sie können den AddInManager nicht deinstallieren. Er wird für die Wiederinstallation von AddIns benötigt!
+
+
+ SharpDevelop AddIn Repository
+
+
+ Erstellt von:
+
+
+ Abhängigkeiten:
+
+
+ Downloads:
+
+
+ Dateiname:
+
+
+ Installierte Version:
+
+
+ Zuletzt aktualisiert:
+
+
+ Weitere Informationen
+
+
+ Neue Version:
+
+
+ Bewertung:
+
+
+ Missbrauch melden
+
+
+ Version:
+
+
+ Lizenzvereinbarungen anzeigen
+
+
+ Folgende installierte AddIns hängen von "{0}" ab:
+
+{1}
+
+Sie werden nicht mehr funktionieren nachdem dieses AddIn deaktiviert wurde! Sind Sie sicher, dass Sie fortfahren möchten?
+
+
+ Das Paket "{0}" benötigt noch mindestens ein zusätzliches Paket:
+
+{1}
+
+Die Anwendung wird versuchen diese auch herunterzuladen und zu installieren. Wollen Sie fortfahren?
+
+
+ Das gewählte Paket enthält kein gültiges SharpDevelop AddIn.
+
+
+ &Akzeptieren
+
+
+ A&blehnen
+
+
+ Mit einem Klick auf "Akzeptieren" stimmen Sie den Lizenzbedingungen des oben angegebenen Paketes zu.
+Wenn Sie den Lizenzbedingungen nicht zustimmen, klicken Sie auf "Ablehnen".
+
+
+ Mit einem Klick auf "Akzeptieren" stimmen Sie den Lizenzbedingungen der oben angegebenen Pakete zu.
+Wenn Sie den Lizenzbedingungen nicht zustimmen, klicken Sie auf "Ablehnen".
+
+
+ Das folgende Paket hat eine Klicken-um-zu-akzeptieren-Lizenz:
+
+
+ Die folgenden Pakete haben eine Klicken-um-zu-akzeptieren-Lizenz:
+
+
+ Lizenzvereinbarungen
+
+
+ Hinzufügen
+
+
+ Nach unten
+
+
+ Nach oben
+
+
+ Name:
+
+
+ Entfernen
+
+
+ Quelle:
+
+
+ AddIns
+
+
+ Quellen
+
+
+ Folgende installierte AddIns hängen von "{0}" ab:
+
+{1}
+
+Sie werden nicht mehr funktionieren, nachdem dieses AddIn entfernt wurde! Sind Sie sicher, dass Sie fortfahren möchten?
+
+
+ SharpDevelop AddIns|*.sdaddin;*.addin|Alle Dateien|*.*
+
+
+ Klicken Sie hier um die Updates zu sehen.
+
+
+ Updates für SharpDevelop sind verfügbar
+
+
+ Verfügbar
+
+
+ Installiert
+
+
+ Updates
+
Diese Datei enthält inkonsistente Zeilenenden.
@@ -1504,9 +1650,18 @@ Beispiele: "120", "MainClass", "Main.cs, 120".
Hervorhebungsfarben importieren
+
+ Diese Version der Einstellungen wird nicht unterstützt!
+
+
+ Hiermit werden alle benutzerdefinierten Farben zurückgesetzt und die gewählten Einstellungen importiert. Wollen Sie fortfahren?
+
Wert
+
+ Alle auf Standard zurücksetzen
+
Beispieltext
@@ -1800,7 +1955,7 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen?
Code-Completion Detail-Einstellungen
- Die folgenden Einstellungen sind sprach-abhängig; einige sind nicht in allen Programmiersprachen verfügbar.
+ Die folgenden Einstellungen sind sprachabhängig; einige sind nicht in allen Programmiersprachen verfügbar.
Mit der folgenden Einstellung kann Code Completion komplett deaktiviert werden:
@@ -1862,6 +2017,12 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen?
Debugger
+
+ Decompiler aktivieren
+
+
+ Bearbeiten und Fortfahren (EnC) aktivieren
+
Ausnahmen
@@ -1892,6 +2053,12 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen?
Über einzeilige Properties springen
+
+ JIT-Optimierung unterdrücken
+
+
+ NGEN-Optimierung unterdrücken
+
Symbole
@@ -2351,6 +2518,12 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen?
Jeder Prozessor
+
+ Beliebige CPU (32-bit bevorzugt)
+
+
+ Beliebige CPU (64-bit bevorzugt)
+
Intel 64-bit Itanium Prozessor
@@ -2496,7 +2669,7 @@ Wollen Sie die neue Datei zum Projekt ${CurrentProjectName} hinzufügen?
Referenzpfade
- Pfad hinzufügem
+ Pfad hinzufügen
Immer
@@ -2711,6 +2884,9 @@ Sie können die Einstellungen auch in einer .user-Datei anstelle der Projektdate
Hin&zufügen
+
+ Fortgeschritten
+
< Zurück
@@ -3571,6 +3747,12 @@ wurde außerhalb der Applikation geändert. Wollen Sie die Datei neu laden?
Inkrementelle Suche (rückwärts):
+
+ {0} ist keine gültige .NET Assembly.
+
+
+ Auf {0} kann nicht zugegriffen werden oder es existiert nicht mehr.
+
Fehler beim Laden der Code-Completion-Informationen für ${Assembly} aus ${Filename}:
@@ -4448,6 +4630,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
.NET Framework-Erweiterung
+
+ WiX ist nicht installiert. Bitte laden Sie WiX von http://wixtoolset.org/ herunter.
+
Keine Unterschiede gefunden.
@@ -4469,6 +4654,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Visual Studio-Erweiterung
+
+ WPF Designer Miniaturansicht
+
Kopieren
@@ -4769,6 +4957,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Lesezeichen
+
+ Zum Arbeitsbereich hinzufügen
+
Zurück
@@ -4808,9 +4999,21 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Keine Suchergebnisse gefunden.
+
+ Assembly öffnen
+
+
+ Assembly aus Datei öffnen...
+
+
+ Assembly aus GAC öffnen...
+
Suche nach Klassenname
+
+ Arbeitsbereich {0}
+
Klassen
@@ -4895,6 +5098,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Haltepunkt deaktivieren
+
+ Bedingung bearbeiten...
+
Haltepunkt aktivieren
@@ -5273,6 +5479,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
in
+
+ <Kein Projekt>
+
${Count} Ergebnisse
@@ -5288,6 +5497,12 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Pro Datei
+
+ Pro Projekt
+
+
+ Pro Projekt und Datei
+
Wähle Darstellungsmodus
@@ -5408,6 +5623,21 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Konnte die Portable Class Library Tools nicht finden.
+
+ .NET Portable Teilmenge
+
+
+ Zwei oder mehr Frameworks müssen gewählt werden.
+
+
+ Ausgewähltes Profil:
+
+
+ Profil für portable Bibliothek auswählen
+
+
+ Um die Portable Class Library Tools ohne Visual Studio zu installieren, laden Sie die Datei (PortableLibraryTools.exe) auf Ihren Computer herunter und führen das Installationsprogramm von der Kommandozeile aus. Geben Sie zusätzlich den /buildmachine Schalter auf der Kommandozeile an.
+
Alle Knoten einklappen
@@ -5708,6 +5938,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Ressourcen-Codegenerator: Es konnte keine Ressourcen-Eigenschaft für die Ressource '{0}' erzeugt werden.
+
+ Kommentar
+
Inhalt
@@ -5720,6 +5953,12 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Kopiere Resourcenname
+
+ Kommentar bearbeiten
+
+
+ Einen neuen Text für den Ressourcen-Kommentar eingeben:
+
&Umbenennen
@@ -5736,6 +5975,9 @@ Bitte einen anderen verwenden.
Alle Dateien (*.*)
+
+ Alle bekannten Dateierweiterungen
+
Assemblydateien (*.exe;*.dll)
@@ -5919,6 +6161,9 @@ Bitte einen anderen verwenden.
Überschreibunden von ${Name}
+
+ Teile von ${Name}
+
Referenzen auf ${Name}
@@ -6684,6 +6929,12 @@ SharpDevelop 2 kompiliert Ressourcendateien anders: der Ressourcenname ist nicht
Gtk#-Anwendung
+
+ Bibliothek, die auf Windows, Silverlight, Windows Phone und Xbox verwendet werden kann.
+
+
+ Portable Klassenbibliothek
+
Erstellt eine einfache PRISM-Anwendung mit Bootstrapper und Infrastruktur.
diff --git a/data/resources/StringResources.es-mx.resx b/data/resources/StringResources.es-mx.resx
index d193c0515d..b1d1b61bb5 100644
--- a/data/resources/StringResources.es-mx.resx
+++ b/data/resources/StringResources.es-mx.resx
@@ -2733,15 +2733,15 @@ También puede elegir guardar la opción en el archivo .user en lugar de en el a
Código
-
- Avanzado
-
Abortar
&Agregar
+
+ Avanzado
+
< Atrás
diff --git a/data/resources/StringResources.es.resx b/data/resources/StringResources.es.resx
index f7825dc2bd..e526341f4a 100644
--- a/data/resources/StringResources.es.resx
+++ b/data/resources/StringResources.es.resx
@@ -2783,15 +2783,15 @@ También puede escoger almacenar el parámetro de configuración en el archivo .
Fuente
-
- Avanzado
-
Abortar
&Agregar
+
+ Avanzado
+
< Atrás
diff --git a/data/resources/StringResources.fr.resx b/data/resources/StringResources.fr.resx
index 8070e47e45..0ae573212f 100644
--- a/data/resources/StringResources.fr.resx
+++ b/data/resources/StringResources.fr.resx
@@ -2870,15 +2870,15 @@ Vous pouvez aussi choisir de stocker la configuration dans le fichier .user-file
Source
-
- Avancé
-
Stopper
&Ajouter
+
+ Avancé
+
< Retour
diff --git a/data/resources/StringResources.it.resx b/data/resources/StringResources.it.resx
index f15ed87494..bc18755ecb 100644
--- a/data/resources/StringResources.it.resx
+++ b/data/resources/StringResources.it.resx
@@ -2791,15 +2791,15 @@ Puoi anche scegliere di memorizzare le impostazioni in un file .user invece che
Sorgente
-
- Avanzate
-
Annulla
&Aggiungi
+
+ Avanzate
+
< Indietro
diff --git a/data/resources/StringResources.nl.resx b/data/resources/StringResources.nl.resx
index 24dd8cdf57..7a13b30f57 100644
--- a/data/resources/StringResources.nl.resx
+++ b/data/resources/StringResources.nl.resx
@@ -2879,15 +2879,15 @@ Er kan worden gekozen voor opslag van de instellingen in het .user bestand inpla
Bron
-
- Uitgebreid
-
Afbreken
&Toevoegen
+
+ Uitgebreid
+
< Terug
@@ -3740,6 +3740,12 @@ Noot: Dit beïnvloed eigen aangepaste opmaak niet.
Omgekeerd aanvullend zoeken:
+
+ {0} is ongeldig als .NET assembly
+
+
+ {0} is niet toegankelijk of bestaat niet meer.
+
Fout bij laden van code-completering informatie voor ${Assembly} van ${Filename}:
@@ -4638,6 +4644,9 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie
Visual Studio extensie
+
+ WPF ontwerper thumbnail overzicht
+
Kopieëren
@@ -4938,6 +4947,9 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie
Bladwijzers
+
+ Toevoegen aan werkruimte
+
Vorige
@@ -4977,9 +4989,21 @@ Microsoft.Tools.WindowsInstallerXml.Extenties.NetFxCompiler, WixNetFxExtentie
Géén zoekresultaten gevonden.
+
+ Open assembly...
+
+
+ Open assembly vanuit bestand...
+
+
+ Assembly openen vanuit GAK...
+
Zoeken in Klassen Overzicht
+
+ Werkruimte {0}
+
Klassen Overzicht
diff --git a/data/resources/StringResources.resx b/data/resources/StringResources.resx
index b2468ce9ed..fff0f64b87 100644
--- a/data/resources/StringResources.resx
+++ b/data/resources/StringResources.resx
@@ -287,7 +287,7 @@ Download an AddIn from the Internet, then click 'Install AddIn' and choose the d
View License Terms
- Following installed AddIns are dependent from "{0}":
+ Following installed AddIns are depending on "{0}":
{1}
@@ -351,7 +351,7 @@ If you do not agree to the license terms click "I Decline".
Repositories
- Following installed AddIns are dependent from "{0}":
+ Following installed AddIns are depending on "{0}":
{1}
@@ -2958,15 +2958,15 @@ You can also choose to store the setting in the .user-file instead of the projec
Source
-
- Advanced
-
Abort
&Add
+
+ Advanced
+
< Back
@@ -4891,6 +4891,9 @@ Unable to find 'WelcomeDialogId' in Dialogs.wxs
Visual Studio Extension
+
+ WPF Designer Thumbnail View
+
Copy
@@ -5222,6 +5225,9 @@ Unable to find 'WelcomeDialogId' in Dialogs.wxs
Bookmarks
+
+ Add to workspace
+
Back
@@ -5261,9 +5267,21 @@ Unable to find 'WelcomeDialogId' in Dialogs.wxs
No search results found.
+
+ Open assembly
+
+
+ Open assembly from file...
+
+
+ Open assembly from GAC...
+
Class View Search
+
+ Workspace {0}
+
Classes
@@ -5760,6 +5778,9 @@ Shows the full callstack of the error.
in
used like this: occurrences IN files
+
+ <no project>
+
${Count} occurrences
@@ -5775,6 +5796,12 @@ Shows the full callstack of the error.
Per file
+
+ Per project
+
+
+ Per project and file
+
Select search list mode
@@ -6466,6 +6493,9 @@ Removed the end part of the original message ", reason '${Message}'" since this
Overrides of ${Name}
+
+ Parts of ${Name}
+
References to ${Name}
Title for search results for references
diff --git a/data/resources/StringResources.tr.resx b/data/resources/StringResources.tr.resx
index e0258a191c..6773c2e533 100644
--- a/data/resources/StringResources.tr.resx
+++ b/data/resources/StringResources.tr.resx
@@ -2732,15 +2732,15 @@ Ayrıca bir ayarı proje dosyası yerine kullanıcı dosyası(.user-file) içind
Kaynak
-
- Gelişmiş
-
Başarısız
Ekle
+
+ Gelişmiş
+
< Geri
diff --git a/samples/XamlDesigner/Document.cs b/samples/XamlDesigner/Document.cs
index 95d1580700..21a28e35e5 100644
--- a/samples/XamlDesigner/Document.cs
+++ b/samples/XamlDesigner/Document.cs
@@ -206,7 +206,14 @@ namespace ICSharpCode.XamlDesigner
{
OutlineRoot = null;
using (var xmlReader = XmlReader.Create(new StringReader(Text))) {
- DesignSurface.LoadDesigner(xmlReader, null);
+ XamlLoadSettings settings = new XamlLoadSettings();
+ foreach (var assNode in Toolbox.Instance.AssemblyNodes)
+ {
+ settings.DesignerAssemblies.Add(assNode.Assembly);
+ }
+ settings.TypeFinder = MyTypeFinder.Instance;
+
+ DesignSurface.LoadDesigner(xmlReader, settings);
}
if (DesignContext.RootItem != null) {
OutlineRoot = OutlineNode.Create(DesignContext.RootItem);
diff --git a/samples/XamlDesigner/MainWindow.xaml b/samples/XamlDesigner/MainWindow.xaml
index 7efb54aefb..b3cd9e3b43 100644
--- a/samples/XamlDesigner/MainWindow.xaml
+++ b/samples/XamlDesigner/MainWindow.xaml
@@ -1,4 +1,4 @@
-
+
+
+
+
+
diff --git a/samples/XamlDesigner/MyTypeFinder.cs b/samples/XamlDesigner/MyTypeFinder.cs
new file mode 100644
index 0000000000..6f529d4514
--- /dev/null
+++ b/samples/XamlDesigner/MyTypeFinder.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using ICSharpCode.WpfDesign.XamlDom;
+
+namespace ICSharpCode.XamlDesigner
+{
+ public class MyTypeFinder : XamlTypeFinder
+ {
+ public override Assembly LoadAssembly(string name)
+ {
+ foreach (var assemblyNode in Toolbox.Instance.AssemblyNodes)
+ {
+ if (assemblyNode.Name == name)
+ return assemblyNode.Assembly;
+ }
+
+ return null;
+ }
+
+ public override XamlTypeFinder Clone()
+ {
+ return _instance;
+ }
+
+ private static object lockObj = new object();
+
+ private static MyTypeFinder _instance;
+ public static MyTypeFinder Instance
+ {
+ get
+ {
+ lock (lockObj)
+ {
+ if (_instance == null)
+ {
+ _instance = new MyTypeFinder();
+ _instance.ImportFrom(CreateWpfTypeFinder());
+ }
+ }
+
+ return _instance;
+ }
+ }
+ }
+}
diff --git a/samples/XamlDesigner/Toolbox.cs b/samples/XamlDesigner/Toolbox.cs
index fcab34988b..d4880827a7 100644
--- a/samples/XamlDesigner/Toolbox.cs
+++ b/samples/XamlDesigner/Toolbox.cs
@@ -14,45 +14,47 @@ namespace ICSharpCode.XamlDesigner
public class Toolbox
{
public Toolbox()
- {
- AssemblyNodes = new ObservableCollection();
+ {
+ AssemblyNodes = new ObservableCollection();
LoadSettings();
- }
+ }
public static Toolbox Instance = new Toolbox();
- public ObservableCollection AssemblyNodes { get; private set; }
+ public ObservableCollection AssemblyNodes { get; private set; }
public void AddAssembly(string path)
- {
+ {
AddAssembly(path, true);
}
- void AddAssembly(string path, bool updateSettings)
- {
- var assembly = Assembly.LoadFile(path);
-
- var node = new AssemblyNode();
- node.Assembly = assembly;
- node.Path = path;
- foreach (var t in assembly.GetExportedTypes()) {
- if (IsControl(t) && Metadata.IsPopularControl(t)) {
- node.Controls.Add(new ControlNode() { Type = t });
- }
- }
+ void AddAssembly(string path, bool updateSettings)
+ {
+ var assembly = Assembly.LoadFile(path);
+
+ MyTypeFinder.Instance.RegisterAssembly(assembly);
+
+ var node = new AssemblyNode();
+ node.Assembly = assembly;
+ node.Path = path;
+ foreach (var t in assembly.GetExportedTypes()) {
+ if (IsControl(t) /* && Metadata.IsPopularControl(t) */) {
+ node.Controls.Add(new ControlNode() { Type = t });
+ }
+ }
- node.Controls.Sort(delegate(ControlNode c1, ControlNode c2) {
- return c1.Name.CompareTo(c2.Name);
- });
+ node.Controls.Sort(delegate(ControlNode c1, ControlNode c2) {
+ return c1.Name.CompareTo(c2.Name);
+ });
- AssemblyNodes.Add(node);
+ AssemblyNodes.Add(node);
if (updateSettings) {
if (Settings.Default.AssemblyList == null) {
Settings.Default.AssemblyList = new StringCollection();
- }
+ }
Settings.Default.AssemblyList.Add(path);
}
- }
+ }
public void Remove(AssemblyNode node)
{
@@ -61,42 +63,47 @@ namespace ICSharpCode.XamlDesigner
}
public void LoadSettings()
- {
+ {
if (Settings.Default.AssemblyList != null) {
foreach (var path in Settings.Default.AssemblyList) {
- AddAssembly(Environment.ExpandEnvironmentVariables(path), false);
+ try
+ {
+ AddAssembly(Environment.ExpandEnvironmentVariables(path), false);
+ }
+ catch (Exception ex)
+ { }
}
}
}
- static bool IsControl(Type t)
- {
- return !t.IsAbstract && !t.IsGenericTypeDefinition && t.IsSubclassOf(typeof(FrameworkElement));
- }
+ static bool IsControl(Type t)
+ {
+ return !t.IsAbstract && !t.IsGenericTypeDefinition && t.IsSubclassOf(typeof(FrameworkElement));
+ }
}
public class AssemblyNode
- {
- public AssemblyNode()
- {
- Controls = new List();
- }
+ {
+ public AssemblyNode()
+ {
+ Controls = new List();
+ }
- public Assembly Assembly { get; set; }
- public List Controls { get; private set; }
- public string Path { get; set; }
+ public Assembly Assembly { get; set; }
+ public List Controls { get; private set; }
+ public string Path { get; set; }
- public string Name {
- get { return Assembly.GetName().Name; }
- }
- }
+ public string Name {
+ get { return Assembly.GetName().Name; }
+ }
+ }
- public class ControlNode
- {
- public Type Type { get; set; }
+ public class ControlNode
+ {
+ public Type Type { get; set; }
- public string Name {
- get { return Type.Name; }
- }
- }
+ public string Name {
+ get { return Type.Name; }
+ }
+ }
}
diff --git a/samples/XamlDesigner/ToolboxView.xaml b/samples/XamlDesigner/ToolboxView.xaml
index 8c1d319ace..ee357bda70 100644
--- a/samples/XamlDesigner/ToolboxView.xaml
+++ b/samples/XamlDesigner/ToolboxView.xaml
@@ -3,18 +3,23 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Outline="clr-namespace:ICSharpCode.WpfDesign.Designer.OutlineView;assembly=ICSharpCode.WpfDesign.Designer"
xmlns:Default="clr-namespace:ICSharpCode.XamlDesigner">
+
+
+
+
+
+ ItemsSource="{Binding Controls}">
+ Text="{Binding Name}"
+ ToolTip="{Binding Path}" />
+ Text="{Binding Type.Name}" />
diff --git a/samples/XamlDesigner/ToolboxView.xaml.cs b/samples/XamlDesigner/ToolboxView.xaml.cs
index c674f3bc56..3527ebe666 100644
--- a/samples/XamlDesigner/ToolboxView.xaml.cs
+++ b/samples/XamlDesigner/ToolboxView.xaml.cs
@@ -1,3 +1,4 @@
+using System.IO;
using ICSharpCode.WpfDesign.Designer.OutlineView;
using System;
using System.Collections.Generic;
@@ -16,6 +17,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ICSharpCode.WpfDesign.Designer.Services;
+using Microsoft.Win32;
namespace ICSharpCode.XamlDesigner
{
@@ -73,5 +75,20 @@ namespace ICSharpCode.XamlDesigner
Toolbox.Instance.Remove(node);
}
}
+
+ private void BrowseForAssemblies_OnClick(object sender, RoutedEventArgs e)
+ {
+ var dlg = new OpenFileDialog();
+ dlg.Filter = "Assemblies (*.dll)|*.dll";
+ dlg.Multiselect = true;
+ dlg.CheckFileExists = true;
+ if (dlg.ShowDialog().Value)
+ {
+ foreach (var fileName in dlg.FileNames)
+ {
+ Toolbox.Instance.AddAssembly(fileName);
+ }
+ }
+ }
}
}
diff --git a/samples/XamlDesigner/XamlDesigner.csproj b/samples/XamlDesigner/XamlDesigner.csproj
index 3ccebb1cb4..8448d81cbf 100644
--- a/samples/XamlDesigner/XamlDesigner.csproj
+++ b/samples/XamlDesigner/XamlDesigner.csproj
@@ -129,6 +129,7 @@
+
MainWindow.xaml
diff --git a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
index 1230bf53d3..afde9cc667 100644
--- a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 19.07.2012
- * Time: 21:27
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.IO;
using ICSharpCode.Core;
@@ -53,4 +49,4 @@ namespace ICSharpCode.CodeAnalysis
set { PropertyService.Set("CodeAnalysis.FxCopPath", value); }
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsPanel.xaml.cs b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsPanel.xaml.cs
index 5f891d6b18..895ffb4a67 100644
--- a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 06/09/2012
- * Time: 18:27
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Text;
@@ -288,4 +284,4 @@ namespace ICSharpCode.CodeAnalysis
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsTreeNodes.cs b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsTreeNodes.cs
index 887e41da21..b096800820 100644
--- a/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsTreeNodes.cs
+++ b/src/AddIns/Analysis/CodeAnalysis/Src/AnalysisProjectOptionsTreeNodes.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 30.06.2012
- * Time: 20:55
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.ObjectModel;
using System.Drawing;
diff --git a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs
index c4bcbd3b74..7fff6d3bff 100644
--- a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 09.06.2012
- * Time: 17:03
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -108,4 +104,4 @@ namespace ICSharpCode.CodeCoverage
public ObservableCollection DisplayItems {get; private set;}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageProjectOptionsPanel.xaml.cs b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageProjectOptionsPanel.xaml.cs
index fb859df06c..75a57d8082 100644
--- a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageProjectOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageProjectOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 09.06.2012
- * Time: 15:01
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Specialized;
using System.IO;
@@ -86,4 +82,4 @@ namespace ICSharpCode.CodeCoverage
IsDirty = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/CodeQuality/Gui/Commands/AnalyzeCodeQualityCommand.cs b/src/AddIns/Analysis/CodeQuality/Gui/Commands/AnalyzeCodeQualityCommand.cs
index 73771df9d2..679116ecb0 100644
--- a/src/AddIns/Analysis/CodeQuality/Gui/Commands/AnalyzeCodeQualityCommand.cs
+++ b/src/AddIns/Analysis/CodeQuality/Gui/Commands/AnalyzeCodeQualityCommand.cs
@@ -3,7 +3,7 @@
using System;
using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop;
namespace ICSharpCode.CodeQuality.Gui
{
@@ -11,7 +11,7 @@ namespace ICSharpCode.CodeQuality.Gui
{
public override void Run()
{
- WorkbenchSingleton.Workbench.ShowView(new AnalyzeCodeQualityViewContent());
+ SD.Workbench.ShowView(new AnalyzeCodeQualityViewContent());
}
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Properties/AssemblyInfo.cs b/src/AddIns/Analysis/CodeQuality/Properties/AssemblyInfo.cs
index 026b23db59..2caec555b7 100644
--- a/src/AddIns/Analysis/CodeQuality/Properties/AssemblyInfo.cs
+++ b/src/AddIns/Analysis/CodeQuality/Properties/AssemblyInfo.cs
@@ -1,4 +1,7 @@
-#region Using directives
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+#region Using directives
using System;
using System.Reflection;
diff --git a/src/AddIns/Analysis/CodeQuality/Reporting/BaseReport.cs b/src/AddIns/Analysis/CodeQuality/Reporting/BaseReport.cs
index 57f5ca9687..6dffc2332d 100644
--- a/src/AddIns/Analysis/CodeQuality/Reporting/BaseReport.cs
+++ b/src/AddIns/Analysis/CodeQuality/Reporting/BaseReport.cs
@@ -1,11 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 25.02.2012
- * Time: 21:04
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/src/AddIns/Analysis/CodeQuality/Reporting/DependencyReport.cs b/src/AddIns/Analysis/CodeQuality/Reporting/DependencyReport.cs
index 3e0c2b4111..c877b6f8f8 100644
--- a/src/AddIns/Analysis/CodeQuality/Reporting/DependencyReport.cs
+++ b/src/AddIns/Analysis/CodeQuality/Reporting/DependencyReport.cs
@@ -1,11 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 25.02.2012
- * Time: 21:17
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
diff --git a/src/AddIns/Analysis/CodeQuality/Reporting/OverviewReport.cs b/src/AddIns/Analysis/CodeQuality/Reporting/OverviewReport.cs
index c46d3d3324..f061439914 100644
--- a/src/AddIns/Analysis/CodeQuality/Reporting/OverviewReport.cs
+++ b/src/AddIns/Analysis/CodeQuality/Reporting/OverviewReport.cs
@@ -1,11 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 13.02.2012
- * Time: 19:46
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
diff --git a/src/AddIns/Analysis/CodeQuality/Reporting/ReportViewModel.cs b/src/AddIns/Analysis/CodeQuality/Reporting/ReportViewModel.cs
index 3546c5de1a..e707dea584 100644
--- a/src/AddIns/Analysis/CodeQuality/Reporting/ReportViewModel.cs
+++ b/src/AddIns/Analysis/CodeQuality/Reporting/ReportViewModel.cs
@@ -1,11 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 26.02.2012
- * Time: 18:10
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using ICSharpCode.CodeQuality.Engine.Dom;
diff --git a/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Properties/AssemblyInfo.cs b/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Properties/AssemblyInfo.cs
index ae1129cedd..78d1c22343 100644
--- a/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Properties/AssemblyInfo.cs
+++ b/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Properties/AssemblyInfo.cs
@@ -1,10 +1,14 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+#region Using directives
+
using System;
using System.Reflection;
using System.Runtime.InteropServices;
+#endregion
+
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
diff --git a/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications/src/MSpecTestFramework.cs b/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications/src/MSpecTestFramework.cs
index 4bee3cbe46..c5906f9eee 100644
--- a/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications/src/MSpecTestFramework.cs
+++ b/src/AddIns/Analysis/MachineSpecifications/MachineSpecifications/src/MSpecTestFramework.cs
@@ -39,4 +39,4 @@ namespace ICSharpCode.MachineSpecifications
return false;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs
index 9a7d98568b..b5c4601111 100644
--- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs
+++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs
@@ -11,6 +11,7 @@ using ICSharpCode.Profiler.Controller;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.Profiler.AddIn
{
@@ -39,7 +40,7 @@ namespace ICSharpCode.Profiler.AddIn
wasStarted = false;
}
- public Task RunInOutputPadAsync(MessageViewCategory outputCategory, string program, params string[] arguments)
+ public Task RunInOutputPadAsync(IOutputCategory outputCategory, string program, params string[] arguments)
{
throw new NotImplementedException();
}
diff --git a/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs b/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
index 2b10c2bf62..86804f2079 100644
--- a/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisIdeOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 23.07.2012
- * Time: 20:13
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -105,4 +101,4 @@ namespace ICSharpCode.SourceAnalysis
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisOptionsPanel.xaml.cs b/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisOptionsPanel.xaml.cs
index 5cc0950e2c..8d2935cc6b 100644
--- a/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisOptionsPanel.xaml.cs
+++ b/src/AddIns/Analysis/SourceAnalysis/Src/AnalysisOptionsPanel.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 21.07.2012
- * Time: 18:51
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -124,4 +120,4 @@ namespace ICSharpCode.SourceAnalysis
return newSettingsFile;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs b/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs
index 8fef1f1174..7f6e07be4e 100644
--- a/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs
+++ b/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs
@@ -4,12 +4,13 @@
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting
{
public interface IUnitTestTaskService
{
- MessageViewCategory BuildMessageViewCategory { get; }
+ IOutputCategory BuildMessageViewCategory { get; }
void ClearExceptCommentTasks();
void Add(SDTask task);
bool SomethingWentWrong { get; }
diff --git a/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs b/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs
index 1ba24447ad..3255984c5e 100644
--- a/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs
+++ b/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs
@@ -4,6 +4,7 @@
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting
{
@@ -14,7 +15,7 @@ namespace ICSharpCode.UnitTesting
TaskService.ClearExceptCommentTasks();
}
- public MessageViewCategory BuildMessageViewCategory {
+ public IOutputCategory BuildMessageViewCategory {
get { return TaskService.BuildMessageViewCategory; }
}
diff --git a/src/AddIns/Analysis/UnitTesting/Service/ITestService.cs b/src/AddIns/Analysis/UnitTesting/Service/ITestService.cs
index 16ffb6cdb6..e51319ed8e 100644
--- a/src/AddIns/Analysis/UnitTesting/Service/ITestService.cs
+++ b/src/AddIns/Analysis/UnitTesting/Service/ITestService.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting
{
@@ -18,7 +19,7 @@ namespace ICSharpCode.UnitTesting
///
ITestFramework GetTestFrameworkForProject(IProject project);
- MessageViewCategory UnitTestMessageView { get; }
+ IOutputCategory UnitTestMessageView { get; }
///
/// Gets the current test solution.
diff --git a/src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs b/src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs
index 1b43050bd1..314c309af3 100644
--- a/src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs
+++ b/src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Workbench;
using ICSharpCode.UnitTesting.Frameworks;
namespace ICSharpCode.UnitTesting
@@ -34,7 +35,7 @@ namespace ICSharpCode.UnitTesting
#region UnitTestMessageView
MessageViewCategory unitTestMessageView;
- public MessageViewCategory UnitTestMessageView {
+ public IOutputCategory UnitTestMessageView {
get {
if (unitTestMessageView == null) {
MessageViewCategory.Create(ref unitTestMessageView,
diff --git a/src/AddIns/Analysis/UnitTesting/Test/Project/DoubleNestedTestClassWithBaseType.cs b/src/AddIns/Analysis/UnitTesting/Test/Project/DoubleNestedTestClassWithBaseType.cs
index c51ec3491c..d7336fa0fe 100644
--- a/src/AddIns/Analysis/UnitTesting/Test/Project/DoubleNestedTestClassWithBaseType.cs
+++ b/src/AddIns/Analysis/UnitTesting/Test/Project/DoubleNestedTestClassWithBaseType.cs
@@ -1,11 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: trecio
- * Date: 2011-10-23
- * Time: 16:15
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
index 1b79772f5f..06862d7ce7 100644
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
+++ b/src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
@@ -115,9 +115,9 @@ namespace ICSharpCode.UnitTesting.Frameworks
void ClearTasks()
{
- taskService.BuildMessageViewCategory.ClearText();
+ taskService.BuildMessageViewCategory.Clear();
taskService.ClearExceptCommentTasks();
- testService.UnitTestMessageView.ClearText();
+ testService.UnitTestMessageView.Clear();
}
void ShowUnitTestsPad()
@@ -132,7 +132,7 @@ namespace ICSharpCode.UnitTesting.Frameworks
void ShowOutputPad()
{
- workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront();
+ testService.UnitTestMessageView.Activate(true);
}
void ResetTestResults()
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd b/src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd
index 53b7453e1b..98b613190b 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Resources/CSharp-Semantic.xshd
@@ -38,6 +38,8 @@
+
+
TODO
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs
index 3c6328355f..3ff19aafe6 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs
@@ -53,10 +53,11 @@ namespace CSharpBinding.Completion
var stringBuilder = new StringBuilder();
var formatter = new ParameterHighlightingOutputFormatter(stringBuilder, highlightedParameterIndex);
ambience.ConvertEntity(Method, formatter, FormattingOptionsFactory.CreateSharpDevelop());
- var inlineBuilder = new HighlightedInlineBuilder(stringBuilder.ToString());
+ string code = stringBuilder.ToString();
+ var inlineBuilder = new RichTextModel();
inlineBuilder.SetFontWeight(formatter.parameterStartOffset, formatter.parameterLength, FontWeights.Bold);
header.Inlines.Clear();
- header.Inlines.AddRange(inlineBuilder.CreateRuns());
+ header.Inlines.AddRange(new RichText(code, inlineBuilder).CreateRuns());
}
public object Content {
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/BuildOptions.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/BuildOptions.xaml.cs
index 9b30e84bec..f2efb12c28 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/BuildOptions.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/BuildOptions.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 05/02/2012
- * Time: 19:54
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -76,4 +72,4 @@ namespace CSharpBinding.OptionPanels
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs
index 8d143a3e5f..374e1060f9 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs
@@ -239,8 +239,8 @@ namespace CSharpBinding
{
internal readonly string newCode;
- public RenameResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, string newCode, HighlightedInlineBuilder builder = null, HighlightingColor defaultTextColor = null)
- : base(fileName, startLocation, endLocation, offset, length, builder, defaultTextColor)
+ public RenameResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, string newCode, RichText richText = null, HighlightingColor defaultTextColor = null)
+ : base(fileName, startLocation, endLocation, offset, length, richText, defaultTextColor)
{
this.newCode = newCode;
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs
index b37a6d8b64..168fbdfa8a 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs
@@ -99,9 +99,9 @@ namespace CSharpBinding.Refactoring
AstType interfaceTypeNode = refactoringContext.CreateShortType("System.ComponentModel", "INotifyPropertyChanged", 0);
var directBaseTypes = currentClass.DirectBaseTypes.Where(t => t.FullName != "System.Object");
if (currentClassDeclaration.BaseTypes.Count > 0) {
- script.InsertText(insertion, ", " + interfaceTypeNode.GetText() + " ");
+ script.InsertText(insertion, ", " + interfaceTypeNode + " ");
} else {
- script.InsertText(insertion, " : " + interfaceTypeNode.GetText() + " ");
+ script.InsertText(insertion, " : " + interfaceTypeNode + " ");
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
index 9a7115b3ae..1638959b29 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/OverrideEqualsGetHashCodeMethodsDialog.xaml.cs
@@ -320,7 +320,7 @@ namespace CSharpBinding.Refactoring
method.Body.Add(new VariableDeclarationStatement(
currentType.Clone(),
"other",
- new CastExpression(currentType.Clone(), new IdentifierExpression("obj"))));
+ new IdentifierExpression("obj").CastAs(currentType.Clone())));
method.Body.Add(new IfElseStatement(
new BinaryOperatorExpression(new IdentifierExpression("other"), BinaryOperatorType.Equality, new PrimitiveExpression(null, "null")),
new ReturnStatement(new PrimitiveExpression(false, "false"))));
diff --git a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/LinkerOptions.xaml.cs b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/LinkerOptions.xaml.cs
index 81088e358f..c9e1f494c7 100644
--- a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/LinkerOptions.xaml.cs
+++ b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/LinkerOptions.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 21.04.2012
- * Time: 20:14
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.ComponentModel;
using System.Windows;
@@ -170,4 +166,4 @@ namespace ICSharpCode.CppBinding.Project
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/PreprocessorOptions.xaml.cs b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/PreprocessorOptions.xaml.cs
index 81f0922fb7..13cfc626f6 100644
--- a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/PreprocessorOptions.xaml.cs
+++ b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/PreprocessorOptions.xaml.cs
@@ -1,10 +1,6 @@
-/*
- * Created by SharpDevelop.
- * User: Peter Forstmeier
- * Date: 14.04.2012
- * Time: 17:53
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.ComponentModel;
using System.Windows;
@@ -139,4 +135,4 @@ namespace ICSharpCode.CppBinding.Project
IsDirty = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs
index 11e57f5cf0..70b57db6e9 100644
--- a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs
@@ -1,3 +1,6 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -163,4 +166,4 @@ namespace Xebic.Parsers.ES3
return result;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs
index a20ac34e85..be1435b21d 100644
--- a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs
@@ -1,3 +1,6 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
using System;
using System.Collections.Generic;
using System.Text;
@@ -171,4 +174,4 @@ namespace Xebic.Parsers.ES3
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
index f5a2a16bbf..7748b14573 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
@@ -1,4 +1,7 @@
-using System;
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
@@ -116,4 +119,4 @@ namespace PythonBinding.Tests.Parsing
Assert.AreEqual(0, count);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/NodeWrapper.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/NodeWrapper.cs
deleted file mode 100644
index d7b8335b8d..0000000000
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/NodeWrapper.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-
-namespace ICSharpCode.XamlBinding
-{
- public class NodeWrapper {
- public string ElementName { get; set; }
- public string Name { get; set; }
-
- public int StartOffset { get; set; }
- public int EndOffset { get; set; }
-
- public IList Children { get; set; }
- }
-}
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
index 975f82cfe2..b42dc3f77d 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
@@ -91,7 +91,6 @@
-
CodeCompletion.xaml
Code
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs
index e20bab95b9..e7345fdf25 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineContentHost.xaml.cs
@@ -2,10 +2,13 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.IO;
+using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using ICSharpCode.Core;
+using ICSharpCode.NRefactory.Xml;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
@@ -34,56 +37,64 @@ namespace ICSharpCode.XamlBinding
if (this.editor == null || !FileUtility.IsEqualFileName(this.editor.FileName, e.FileName))
return;
- #warning Reimplement XAML outline
-// var cu = e.NewSyntaxTree as XamlSyntaxTree;
-//
-// if (cu != null && cu.TreeRootNode != null)
-// UpdateTree(cu.TreeRootNode);
+ var parseInfo = e.NewParseInformation as XamlFullParseInformation;
+ if (parseInfo != null && parseInfo.Document != null)
+ UpdateTree(parseInfo.Document);
}
- void UpdateTree(NodeWrapper root)
+ void UpdateTree(AXmlDocument root)
{
- if (this.treeView.Root == null)
- this.treeView.Root = BuildNode(root);
- else
- UpdateNode(this.treeView.Root as XamlOutlineNode, root);
+ if (treeView.Root == null) {
+ treeView.Root = new XamlOutlineNode {
+ ElementName = "Document Root",
+ Name = Path.GetFileName(editor.FileName),
+ Editor = editor
+ };
+ }
+
+ UpdateNode(treeView.Root as XamlOutlineNode, root);
}
- void UpdateNode(XamlOutlineNode node, NodeWrapper dataNode)
+ void UpdateNode(XamlOutlineNode node, AXmlObject dataNode)
{
- if (dataNode != null && node != null) {
- node.Name = dataNode.Name;
- node.ElementName = dataNode.ElementName;
- node.Marker = editor.Document.CreateAnchor(Utils.MinMax(dataNode.StartOffset, 0, editor.Document.TextLength));
- node.EndMarker = editor.Document.CreateAnchor(Utils.MinMax(dataNode.EndOffset, 0, editor.Document.TextLength));
-
- int childrenCount = node.Children.Count;
- int dataCount = dataNode.Children.Count;
-
- for (int i = 0; i < Math.Max(childrenCount, dataCount); i++) {
- if (i >= childrenCount) {
- node.Children.Add(BuildNode(dataNode.Children[i]));
- } else if (i >= dataCount) {
- while (node.Children.Count > dataCount)
- node.Children.RemoveAt(dataCount);
- } else {
- UpdateNode(node.Children[i] as XamlOutlineNode, dataNode.Children[i]);
- }
+ if (dataNode == null || node == null)
+ return;
+ if (dataNode is AXmlElement) {
+ var item = (AXmlElement)dataNode;
+ node.Name = item.GetAttributeValue("Name") ?? item.GetAttributeValue(XamlConst.XamlNamespace, "Name");
+ node.ElementName = item.Name;
+ }
+ node.Marker = editor.Document.CreateAnchor(Utils.MinMax(dataNode.StartOffset, 0, editor.Document.TextLength));
+ node.EndMarker = editor.Document.CreateAnchor(Utils.MinMax(dataNode.EndOffset, 0, editor.Document.TextLength));
+
+ var dataChildren = dataNode.Children.OfType().ToList();
+
+ int childrenCount = node.Children.Count;
+ int dataCount = dataChildren.Count;
+
+ for (int i = 0; i < Math.Max(childrenCount, dataCount); i++) {
+ if (i >= childrenCount) {
+ node.Children.Add(BuildNode(dataChildren[i]));
+ } else if (i >= dataCount) {
+ while (node.Children.Count > dataCount)
+ node.Children.RemoveAt(dataCount);
+ } else {
+ UpdateNode(node.Children[i] as XamlOutlineNode, dataChildren[i]);
}
}
}
- XamlOutlineNode BuildNode(NodeWrapper item)
+ XamlOutlineNode BuildNode(AXmlElement item)
{
- XamlOutlineNode node = new XamlOutlineNode() {
- Name = item.Name,
- ElementName = item.ElementName,
+ XamlOutlineNode node = new XamlOutlineNode {
+ Name = item.GetAttributeValue("Name") ?? item.GetAttributeValue(XamlConst.XamlNamespace, "Name"),
+ ElementName = item.Name,
Marker = editor.Document.CreateAnchor(Utils.MinMax(item.StartOffset, 0, editor.Document.TextLength - 1)),
EndMarker = editor.Document.CreateAnchor(Utils.MinMax(item.EndOffset, 0, editor.Document.TextLength - 1)),
Editor = editor
};
- foreach (var child in item.Children)
+ foreach (var child in item.Children.OfType())
node.Children.Add(BuildNode(child));
return node;
@@ -96,9 +107,7 @@ namespace ICSharpCode.XamlBinding
}
public object OutlineContent {
- get {
- return this;
- }
+ get { return this; }
}
public void Dispose()
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs
index 5c209e9422..2d27ff7169 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlOutlineNode.cs
@@ -6,12 +6,14 @@ using System.Linq;
using System.Windows;
using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.TreeView;
namespace ICSharpCode.XamlBinding
{
- class XamlOutlineNode : SharpTreeNode {
+ class XamlOutlineNode : SharpTreeNode
+ {
string elementName, name;
public string ElementName {
@@ -107,5 +109,9 @@ namespace ICSharpCode.XamlBinding
public override object Text {
get { return (!string.IsNullOrEmpty(Name) ? ElementName + " (" + Name + ")" : ElementName); }
}
+
+ public override object Icon {
+ get { return SD.ResourceService.GetImageSource("Icons.16x16.HtmlElements.Element"); }
+ }
}
}
diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs
index e1e4297054..f72284a4c8 100644
--- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs
+++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs
@@ -31,9 +31,10 @@ namespace ICSharpCode.XamlBinding
public static XamlUnresolvedFile Create(FileName fileName, ITextSource fileContent, AXmlDocument document)
{
XamlUnresolvedFile file = new XamlUnresolvedFile(fileName);
+ ReadOnlyDocument textDocument = new ReadOnlyDocument(fileContent, fileName);
- file.errors.AddRange(document.SyntaxErrors.Select(err => new Error(ErrorType.Error, err.Description)));
- var visitor = new XamlDocumentVisitor(file, fileContent);
+ file.errors.AddRange(document.SyntaxErrors.Select(err => new Error(ErrorType.Error, err.Description, textDocument.GetLocation(err.StartOffset))));
+ var visitor = new XamlDocumentVisitor(file, textDocument);
visitor.VisitDocument(document);
if (visitor.TypeDefinition != null)
file.topLevel = new[] { visitor.TypeDefinition };
@@ -130,10 +131,10 @@ namespace ICSharpCode.XamlBinding
AXmlDocument currentDocument;
ReadOnlyDocument textDocument;
- public XamlDocumentVisitor(IUnresolvedFile file, ITextSource fileContent)
+ public XamlDocumentVisitor(IUnresolvedFile file, ReadOnlyDocument textDocument)
{
this.file = file;
- textDocument = new ReadOnlyDocument(fileContent, file.FileName);
+ this.textDocument = textDocument;
}
public override void VisitDocument(AXmlDocument document)
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
index 5115ddb504..ce4ae66e32 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
+++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
@@ -165,7 +165,7 @@
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml
index 7134b3fa66..06b62a35e2 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml
+++ b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml
@@ -22,7 +22,7 @@
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.PauseOnHandledExceptions}" />
-
+
-
+
+
+
+
@@ -16,7 +16,35 @@
+
+
-
\ No newline at end of file
+
+
+
+
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs
index e3e8752606..b943873896 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs
@@ -4,6 +4,7 @@
using System;
using System.Diagnostics;
using System.Windows;
+using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using System.Windows.Media.Animation;
@@ -78,7 +79,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
if (designPanel != null && grayOut == null && optionService != null && optionService.GrayOutDesignSurfaceExceptParentContainerWhenDragging) {
grayOut = new GrayOutDesignerExceptActiveArea();
grayOut.designSurfaceRectangle = new RectangleGeometry(
- new Rect(new Point(0, 0), designPanel.RenderSize));
+ new Rect(0, 0, ((Border)designPanel.Child).Child.RenderSize.Width, ((Border)designPanel.Child).Child.RenderSize.Height));
grayOut.designPanel = designPanel;
grayOut.adornerPanel = new AdornerPanel();
grayOut.adornerPanel.Order = AdornerOrder.BehindForeground;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/InfoTextEnterArea.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/InfoTextEnterArea.cs
new file mode 100644
index 0000000000..3664828270
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/InfoTextEnterArea.cs
@@ -0,0 +1,101 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Threading;
+using System.Windows.Media.Animation;
+using ICSharpCode.WpfDesign.Adorners;
+using ICSharpCode.WpfDesign.Designer.Services;
+
+namespace ICSharpCode.WpfDesign.Designer.Controls
+{
+ ///
+ /// Gray out everything except a specific area.
+ ///
+ sealed class InfoTextEnterArea : FrameworkElement
+ {
+ Geometry designSurfaceRectangle;
+ Geometry activeAreaGeometry;
+ Geometry combinedGeometry;
+ AdornerPanel adornerPanel;
+ IDesignPanel designPanel;
+ const double MaxOpacity = 0.3;
+
+ public InfoTextEnterArea()
+ {
+ this.IsHitTestVisible = false;
+ }
+
+ public Geometry ActiveAreaGeometry {
+ get { return activeAreaGeometry; }
+ set {
+ activeAreaGeometry = value;
+ combinedGeometry = activeAreaGeometry;
+ }
+ }
+
+ Rect currentAnimateActiveAreaRectToTarget;
+
+ internal void AnimateActiveAreaRectTo(Rect newRect)
+ {
+ if (newRect.Equals(currentAnimateActiveAreaRectToTarget))
+ return;
+ activeAreaGeometry.BeginAnimation(
+ RectangleGeometry.RectProperty,
+ new RectAnimation(newRect, new Duration(new TimeSpan(0,0,0,0,100))),
+ HandoffBehavior.SnapshotAndReplace);
+ currentAnimateActiveAreaRectToTarget = newRect;
+ }
+
+ internal static void Start(ref InfoTextEnterArea grayOut, ServiceContainer services, UIElement activeContainer, string text)
+ {
+ Debug.Assert(activeContainer != null);
+ Start(ref grayOut, services, activeContainer, new Rect(activeContainer.RenderSize), text);
+ }
+
+ internal static void Start(ref InfoTextEnterArea grayOut, ServiceContainer services, UIElement activeContainer, Rect activeRectInActiveContainer, string text)
+ {
+ Debug.Assert(services != null);
+ Debug.Assert(activeContainer != null);
+ DesignPanel designPanel = services.GetService() as DesignPanel;
+ OptionService optionService = services.GetService();
+ if (designPanel != null && grayOut == null && optionService != null && optionService.GrayOutDesignSurfaceExceptParentContainerWhenDragging) {
+ grayOut = new InfoTextEnterArea();
+ grayOut.designSurfaceRectangle = new RectangleGeometry(
+ new Rect(0, 0, ((Border)designPanel.Child).Child.RenderSize.Width, ((Border)designPanel.Child).Child.RenderSize.Height));
+ grayOut.designPanel = designPanel;
+ grayOut.adornerPanel = new AdornerPanel();
+ grayOut.adornerPanel.Order = AdornerOrder.Background;
+ grayOut.adornerPanel.SetAdornedElement(designPanel.Context.RootItem.View, null);
+ grayOut.ActiveAreaGeometry = new RectangleGeometry(activeRectInActiveContainer, 0, 0, (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement));
+ var tb = new TextBlock(){Text = text};
+ tb.FontSize = 10;
+ tb.ClipToBounds = true;
+ tb.Width = ((FrameworkElement) activeContainer).ActualWidth;
+ tb.Height = ((FrameworkElement) activeContainer).ActualHeight;
+ tb.VerticalAlignment = VerticalAlignment.Top;
+ tb.HorizontalAlignment = HorizontalAlignment.Left;
+ tb.RenderTransform = (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement);
+ grayOut.adornerPanel.Children.Add(tb);
+
+ designPanel.Adorners.Add(grayOut.adornerPanel);
+ }
+ }
+
+ static readonly TimeSpan animationTime = new TimeSpan(2000000);
+
+ internal static void Stop(ref InfoTextEnterArea grayOut)
+ {
+ if (grayOut != null) {
+ IDesignPanel designPanel = grayOut.designPanel;
+ AdornerPanel adornerPanelToRemove = grayOut.adornerPanel;
+ designPanel.Adorners.Remove(adornerPanelToRemove);
+ grayOut = null;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/MarginHandle.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/MarginHandle.cs
index cfb44b5289..4ca3199ec6 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/MarginHandle.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/MarginHandle.cs
@@ -60,7 +60,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
///
/// Gets the Stub for this handle
///
- public MarginStub Stub {get; private set;}
+ public MarginStub Stub {get; protected set;}
///
/// Gets/Sets the angle by which handle rotates.
@@ -70,7 +70,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
///
/// Gets/Sets the angle by which the Margin display has to be rotated
///
- public double TextTransform{
+ public virtual double TextTransform{
get{
if((double)orientation==90 || (double)orientation == 180)
return 180;
@@ -109,6 +109,9 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
get { return orientation; }
}
+ protected MarginHandle()
+ { }
+
public MarginHandle(DesignItem adornedControlItem, AdornerPanel adornerPanel, HandleOrientation orientation)
{
Debug.Assert(adornedControlItem!=null);
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
index 13371e3019..5333abb315 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
@@ -9,6 +9,10 @@ using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.WpfDesign.Designer.Services;
+using System.Windows.Media;
+using ICSharpCode.WpfDesign.Designer.Converters;
+using System.Globalization;
+using System.Windows.Data;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
@@ -17,12 +21,17 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
static PanelMoveAdorner()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PanelMoveAdorner),
- new FrameworkPropertyMetadata(typeof(PanelMoveAdorner)));
+ new FrameworkPropertyMetadata(typeof(PanelMoveAdorner)));
}
+
+ private ScaleTransform scaleTransform;
public PanelMoveAdorner(DesignItem item)
{
this.item = item;
+
+ scaleTransform = new ScaleTransform(1.0, 1.0);
+ this.LayoutTransform = scaleTransform;
}
DesignItem item;
@@ -30,8 +39,23 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
e.Handled = true;
- item.Services.Selection.SetSelectedComponents(new DesignItem [] { item }, SelectionTypes.Auto);
+ item.Services.Selection.SetSelectedComponents(new DesignItem [] { item }, SelectionTypes.Auto);
new DragMoveMouseGesture(item, false).Start(item.Services.DesignPanel, e);
}
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ var surface = this.TryFindParent();
+ if (surface != null && surface.ZoomControl != null)
+ {
+ var bnd = new Binding("CurrentZoom") {Source = surface.ZoomControl};
+ bnd.Converter = InvertedZoomConverter.Instance;
+
+ BindingOperations.SetBinding(scaleTransform, ScaleTransform.ScaleXProperty, bnd);
+ BindingOperations.SetBinding(scaleTransform, ScaleTransform.ScaleYProperty, bnd);
+ }
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs
index 6a06abc89f..686c4e646a 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs
@@ -6,6 +6,11 @@ using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using System.Windows.Media;
+using ICSharpCode.WpfDesign.Designer.Converters;
+using System.Globalization;
+using System.Windows.Data;
+
namespace ICSharpCode.WpfDesign.Designer.Controls
{
@@ -13,106 +18,124 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
/// A Small icon which shows up a menu containing common properties
///
public class QuickOperationMenu : Control
- {
- static QuickOperationMenu()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof (QuickOperationMenu), new FrameworkPropertyMetadata(typeof (QuickOperationMenu)));
- }
-
- private MenuItem _mainHeader;
-
- ///
- /// Contains Default values in the Sub menu for example "HorizontalAlignment" has "HorizontalAlignment.Stretch" as it's value.
- ///
- private readonly Dictionary
+
Code
@@ -99,6 +112,7 @@
+
@@ -109,15 +123,14 @@
-
- DesignSurface.xaml
-
+
Code
+
Code
@@ -127,6 +140,8 @@
+
+
Code
@@ -190,9 +205,7 @@
PropertyContextMenu.xaml
-
- PropertyGridView.xaml
-
+
@@ -217,6 +230,7 @@
+
@@ -228,6 +242,8 @@
+
+
{8035765F-D51F-4A0C-A746-2FD100E19419}
ICSharpCode.SharpDevelop.Widgets
@@ -326,4 +342,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
index 5ec62b627d..edbb41d40d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Windows.Markup;
+using System.Windows;
using ICSharpCode.WpfDesign.XamlDom;
@@ -87,6 +88,28 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
if (ComponentRegistered != null) {
ComponentRegistered(this, new DesignItemEventArgs(site));
}
+
+ if (_context.RootItem != null && !string.IsNullOrEmpty(site.Name)) {
+ var nameScope = _context.RootItem.Component as INameScope;
+ nameScope = NameScope.GetNameScope((DependencyObject) _context.RootItem.Component);
+ var fnd = nameScope.FindName(site.Name);
+
+ if (fnd != null) {
+ string newNm = site.Name + "_Copy";
+ fnd = nameScope.FindName(newNm);
+ if (fnd == null)
+ site.Name = newNm;
+ else {
+ int i = 1;
+ while (fnd != null) {
+ newNm = site.Name + "_Copy" + i;
+ fnd = nameScope.FindName(newNm);
+ i++;
+ }
+ site.Name = newNm;
+ }
+ }
+ }
return site;
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs
index d2110647d5..82df2c8ca0 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs
@@ -22,6 +22,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
{
readonly XamlDocument _doc;
readonly XamlDesignItem _rootItem;
+ readonly XamlParserSettings _parserSettings;
internal readonly XamlComponentService _componentService;
readonly XamlEditOperations _xamlEditOperations;
@@ -81,13 +82,22 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
EditorManager.RegisterAssembly(designerAssembly);
}
- XamlParserSettings parserSettings = new XamlParserSettings();
- parserSettings.TypeFinder = loadSettings.TypeFinder;
- parserSettings.CreateInstanceCallback = this.Services.ExtensionManager.CreateInstanceWithCustomInstanceFactory;
- parserSettings.ServiceProvider = this.Services;
- _doc = XamlParser.Parse(xamlReader, parserSettings);
- if(_doc==null)
- loadSettings.ReportErrors(xamlErrorService);
+ _parserSettings = new XamlParserSettings();
+ _parserSettings.TypeFinder = loadSettings.TypeFinder;
+ _parserSettings.CreateInstanceCallback = this.Services.ExtensionManager.CreateInstanceWithCustomInstanceFactory;
+ _parserSettings.ServiceProvider = this.Services;
+ _doc = XamlParser.Parse(xamlReader, _parserSettings);
+
+ loadSettings.ReportErrors(xamlErrorService);
+
+ if (_doc == null) {
+ string message;
+ if (xamlErrorService != null && xamlErrorService.Errors.Count > 0)
+ message = xamlErrorService.Errors[0].Message;
+ else
+ message = "Could not load document.";
+ throw new XamlLoadException(message);
+ }
_rootItem = _componentService.RegisterXamlComponentRecursive(_doc.RootElement);
@@ -97,7 +107,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
}
- _xamlEditOperations=new XamlEditOperations(this,parserSettings);
+ _xamlEditOperations=new XamlEditOperations(this,_parserSettings);
}
@@ -116,6 +126,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
get { return _rootItem; }
}
+ ///
+ /// Gets the parser Settings being used
+ ///
+ public XamlParserSettings ParserSettings {
+ get { return _parserSettings; }
+ }
+
///
/// Opens a new change group used to batch several changes.
/// ChangeGroups work as transactions and are used to support the Undo/Redo system.
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs
index 83ae4df39f..abac9ec74c 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs
@@ -49,8 +49,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
}
public override string Name {
- get { return (string)this.Properties["Name"].ValueOnInstance; }
- set { this.Properties["Name"].SetValue(value); }
+ get { return _xamlObject.Name; }
+ set { _xamlObject.Name = value; }
+ }
+
+ public override string Key {
+ get { return XamlObject.GetXamlAttribute("Key"); }
+ set { XamlObject.SetXamlAttribute("Key", value); }
}
#if EventHandlerDebugging
@@ -65,13 +70,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
#if EventHandlerDebugging
Debug.WriteLine("Add event handler to " + this.ComponentType.Name + " (handler count=" + (++totalEventHandlerCount) + ")");
#endif
- this.Properties["Name"].ValueChanged += value;
+ _xamlObject.NameChanged += value;
}
remove {
#if EventHandlerDebugging
Debug.WriteLine("Remove event handler from " + this.ComponentType.Name + " (handler count=" + (--totalEventHandlerCount) + ")");
#endif
- this.Properties["Name"].ValueChanged -= value;
+ _xamlObject.NameChanged -= value;
}
}
@@ -142,7 +147,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
public override DesignItem Clone()
{
- throw new NotImplementedException();
+ DesignItem item = null;
+ var xaml = XamlStaticTools.GetXaml(this.XamlObject);
+ XamlDesignItem rootItem = Context.RootItem as XamlDesignItem;
+ var obj = XamlParser.ParseSnippet(rootItem.XamlObject, xaml, ((XamlDesignContext) Context).ParserSettings);
+ if (obj != null)
+ {
+ item = ((XamlDesignContext)Context)._componentService.RegisterXamlComponentRecursive(obj);
+ }
+ return item;
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs
index 0bf80bee22..6a652dabbb 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs
@@ -161,7 +161,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
void AddInParent(DesignItem parent,IList pastedItems)
{
IEnumerable rects = pastedItems.Select(i => new Rect(new Point(0, 0), new Point((double)i.Properties["Width"].ValueOnInstance, (double)i.Properties["Height"].ValueOnInstance)));
- var operation = PlacementOperation.TryStartInsertNewComponents(parent, pastedItems, rects.ToList(), PlacementType.AddItem);
+ var operation = PlacementOperation.TryStartInsertNewComponents(parent, pastedItems, rects.ToList(), PlacementType.PasteItem);
ISelectionService selection = _context.Services.Selection;
selection.SetSelectedComponents(pastedItems);
if(operation!=null)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlLoadSettings.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlLoadSettings.cs
index 0f3030521f..eb59dd6070 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlLoadSettings.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlLoadSettings.cs
@@ -16,7 +16,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
{
public readonly ICollection DesignerAssemblies = new List();
public readonly List> CustomServiceRegisterFunctions = new List>();
- public Action ReportErrors;
+ public Action ReportErrors = (errorService) => { };
XamlTypeFinder typeFinder = XamlTypeFinder.CreateWpfTypeFinder();
public XamlTypeFinder TypeFinder {
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs
index b83db4808e..7099aa828d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs
@@ -7,15 +7,18 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using ICSharpCode.WpfDesign.XamlDom;
using ICSharpCode.WpfDesign.Designer.Services;
+using System.Collections.Specialized;
namespace ICSharpCode.WpfDesign.Designer.Xaml
{
- sealed class XamlModelCollectionElementsCollection : IList
+ sealed class XamlModelCollectionElementsCollection : IList, INotifyCollectionChanged
{
readonly XamlModelProperty modelProperty;
readonly XamlProperty property;
readonly XamlDesignContext context;
+ public event NotifyCollectionChangedEventHandler CollectionChanged;
+
public XamlModelCollectionElementsCollection(XamlModelProperty modelProperty, XamlProperty property)
{
this.modelProperty = modelProperty;
@@ -45,6 +48,9 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
while (this.Count > 0) {
RemoveAt(this.Count - 1);
}
+
+ if (CollectionChanged != null)
+ CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public bool Contains(DesignItem item)
@@ -77,7 +83,9 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
int index = IndexOf(item);
if (index < 0)
return false;
+
RemoveAt(index);
+
return true;
}
@@ -151,11 +159,17 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
{
Debug.Assert(property.CollectionElements[index] == item.XamlObject);
property.CollectionElements.RemoveAt(index);
+
+ if (CollectionChanged != null)
+ CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
}
void InsertInternal(int index, XamlDesignItem item)
{
property.CollectionElements.Insert(index, item.XamlObject);
+
+ if (CollectionChanged != null)
+ CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
sealed class InsertAction : ITransactionItem
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs
index d39a45b2fe..2a2c4904f9 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs
@@ -4,22 +4,29 @@
using System;
using System.Windows;
using ICSharpCode.WpfDesign.XamlDom;
+using System.Collections;
+using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.Designer.Xaml
{
sealed class XamlModelPropertyCollection : DesignItemPropertyCollection
{
XamlDesignItem _item;
+ Dictionary propertiesDictionary = new Dictionary();
public XamlModelPropertyCollection(XamlDesignItem item)
{
this._item = item;
}
-
public override DesignItemProperty GetProperty(string name)
{
- return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name));
+ XamlModelProperty property;
+ if (propertiesDictionary.TryGetValue(name, out property))
+ return property;
+ property = new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name));
+ propertiesDictionary.Add(name, property);
+ return property;
}
public override DesignItemProperty GetAttachedProperty(Type ownerType, string name)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml
index e193f8eee7..0b149ec427 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml
@@ -3,5 +3,8 @@
+
+
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
index e83a8bc05b..610ddf7592 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
@@ -81,10 +81,23 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
return grid;
}
+ private DesignItem IntializePasteOperationsCannotAddTest()
+ {
+ var grid = CreateGridContextWithDesignSurface("
public class ModelTestHelper
{
+ public const string DesignerTestsNamespace = "clr-namespace:ICSharpCode.WpfDesign.Tests.Designer;assembly=ICSharpCode.WpfDesign.Tests";
+
protected StringBuilder log;
protected XamlDesignContext CreateContext(string xaml)
@@ -33,6 +37,11 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
context.Services.Component.ComponentUnregistered += delegate(object sender, DesignItemEventArgs e) {
log.AppendLine("Unregister " + ItemIdentity(e.Item));
};*/
+
+ // create required service mocks
+ var designPanel = MockRepository.GenerateStub();
+ designPanel.Stub(dp => dp.Adorners).Return(new System.Collections.Generic.List());
+ context.Services.AddService(typeof(IDesignPanel), designPanel);
return context;
}
@@ -40,7 +49,8 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
{
XamlDesignContext context = CreateContext(@"");
Canvas canvas = (Canvas)context.RootItem.Component;
DesignItem canvasChild = context.Services.Component.GetDesignItem(canvas.Children[0]);
@@ -54,7 +64,8 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
expectedXaml =
"\n" +
("";
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs
index 1973bc3a33..1b0c322563 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs
@@ -8,6 +8,7 @@ using System.Xml;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Data;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer;
using ICSharpCode.WpfDesign.Designer.Xaml;
@@ -235,5 +236,160 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
"", canvas.Context);
AssertLog("");
}
+
+ [Test]
+ public void AddMultiBindingToTextBox()
+ {
+ DesignItem button = CreateCanvasContext("");
+ DesignItem canvas = button.Parent;
+ DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
+ canvas.Properties["Children"].CollectionElements.Add(textBox);
+
+ textBox.Properties[TextBox.TextProperty].SetValue(new MultiBinding());
+ DesignItem multiBindingItem = textBox.Properties[TextBox.TextProperty].Value;
+ multiBindingItem.Properties["Converter"].SetValue(new MyMultiConverter());
+
+ DesignItemProperty bindingsProp = multiBindingItem.ContentProperty;
+ Assert.IsTrue(bindingsProp.IsCollection);
+ Assert.AreEqual(bindingsProp.Name, "Bindings");
+
+ DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
+ bindingItem.Properties["Path"].SetValue("SomeProperty");
+ bindingsProp.CollectionElements.Add(bindingItem);
+
+ string expectedXaml = "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "";
+
+ AssertCanvasDesignerOutput(expectedXaml, button.Context);
+ AssertLog("");
+ }
+
+ [Test]
+ public void AddSimpleBinding()
+ {
+ DesignItem button = CreateCanvasContext("");
+ DesignItem canvas = button.Parent;
+ DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
+ canvas.Properties["Children"].CollectionElements.Add(textBox);
+
+ textBox.Properties[TextBox.TextProperty].SetValue(new Binding());
+ textBox.Properties[TextBox.TextProperty].Value.Properties["Path"].SetValue("SomeProperty");
+
+ string expectedXaml = "\n" +
+ "\n";
+
+ AssertCanvasDesignerOutput(expectedXaml, button.Context);
+ AssertLog("");
+ }
+
+ [Test]
+ public void AddBindingWithStaticResource()
+ {
+ DesignItem button = CreateCanvasContext("");
+ DesignItem canvas = button.Parent;
+ DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
+ canvas.Properties["Children"].CollectionElements.Add(textBox);
+
+ DesignItemProperty resProp = canvas.Properties.GetProperty("Resources");
+ Assert.IsTrue(resProp.IsCollection);
+ DesignItem exampleClassItem = canvas.Services.Component.RegisterComponentForDesigner(new ExampleClass());
+ exampleClassItem.Key = "bindingSource";
+ resProp.CollectionElements.Add(exampleClassItem);
+
+ DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
+ textBox.Properties[TextBox.TextProperty].SetValue(bindingItem);
+ bindingItem.Properties["Path"].SetValue("StringProp");
+ bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
+ bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
+
+ string expectedXaml = "\n" +
+ " \n" +
+ "\n" +
+ "\n" +
+ "";
+
+ AssertCanvasDesignerOutput(expectedXaml, button.Context);
+ AssertLog("");
+ }
+
+ void AddBindingWithStaticResourceWhereResourceOnSameElement(bool setBindingPropertiesAfterSet)
+ {
+ DesignItem button = CreateCanvasContext("");
+ DesignItem canvas = button.Parent;
+ DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
+ canvas.Properties["Children"].CollectionElements.Add(textBox);
+
+ DesignItemProperty resProp = textBox.Properties.GetProperty("Resources");
+ Assert.IsTrue(resProp.IsCollection);
+ DesignItem exampleClassItem = canvas.Services.Component.RegisterComponentForDesigner(new ExampleClass());
+ exampleClassItem.Key = "bindingSource";
+ resProp.CollectionElements.Add(exampleClassItem);
+
+ DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
+ if (!setBindingPropertiesAfterSet) {
+ bindingItem.Properties["Path"].SetValue("StringProp");
+ bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
+ bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
+ }
+ textBox.Properties[TextBox.TextProperty].SetValue(bindingItem);
+ if (setBindingPropertiesAfterSet) {
+ bindingItem.Properties["Path"].SetValue("StringProp");
+ bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
+ bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
+ }
+
+ string expectedXaml = "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "";
+
+ AssertCanvasDesignerOutput(expectedXaml, button.Context);
+ AssertLog("");
+ }
+
+ [Test]
+ public void AddBindingWithStaticResourceWhereResourceOnSameElement()
+ {
+ AddBindingWithStaticResourceWhereResourceOnSameElement(false);
+ }
+
+ [Test]
+ public void AddBindingWithStaticResourceWhereResourceOnSameElementAlt()
+ {
+ AddBindingWithStaticResourceWhereResourceOnSameElement(true);
+ }
+ }
+
+ public class MyMultiConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return null;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return new object[targetTypes.Length];
+ }
+ }
+
+ public class ExampleClass
+ {
+ string stringProp;
+
+ public string StringProp {
+ get { return stringProp; }
+ set { stringProp = value; }
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/OutlineView/InsertTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/OutlineView/InsertTests.cs
index b52d33e70e..bdcb418e3e 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/OutlineView/InsertTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/OutlineView/InsertTests.cs
@@ -104,7 +104,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
}
[Test]
- [Ignore]
+ //[Ignore]
public void CheckGridChildrenCountWhenCopy()
{
InsertIntoGridByCopy();
@@ -113,7 +113,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
}
[Test]
- [Ignore]
+ //[Ignore]
public void CheckStackPanelChildrenCountWhenCopy()
{
InsertIntoGridByCopy();
@@ -122,25 +122,24 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
}
[Test]
- [Ignore]
+ //[Ignore]
public void CheckElementsInOutlineWhenCopy()
{
InsertIntoGridByCopy();
- Assert.AreEqual(_gridButtonNode, _outline.Children[0]);
- Assert.AreEqual(_stackPanelButtonNode, _outline.Children[1]);
- Assert.AreEqual(_stackPanelNode, _outline.Children[2]);
- Assert.AreEqual(_stackPanelButtonNode, _stackPanelButtonNode.Children[0]);
+ Assert.AreEqual(_gridButtonNode.DesignItem.Component.GetType(), _outline.Children[0].DesignItem.Component.GetType());
+ Assert.AreEqual(_stackPanelButtonNode.DesignItem.Component.GetType(), _outline.Children[1].DesignItem.Component.GetType());
+ Assert.AreEqual(_stackPanelNode.DesignItem.Component.GetType(), _outline.Children[2].DesignItem.Component.GetType());
}
[Test]
- [Ignore]
+ //[Ignore]
public void CheckElementsInDesignerWhenCopy()
{
InsertIntoGridByCopy();
Assert.AreEqual(_gridButton, _grid.ContentProperty.CollectionElements[0]);
- Assert.AreEqual(_stackPanelButton, _grid.ContentProperty.CollectionElements[1]);
- Assert.AreEqual(_stackPanel, _grid.ContentProperty.CollectionElements[2]);
- Assert.AreEqual(_stackPanelButton, _stackPanel.ContentProperty.CollectionElements[0]);
+ Assert.AreEqual(_stackPanelButton.Component.GetType(), _grid.ContentProperty.CollectionElements[1].Component.GetType());
+ Assert.AreEqual(_stackPanel.Component.GetType(), _grid.ContentProperty.CollectionElements[2].Component.GetType());
+ Assert.AreEqual(_stackPanelButton.Component.GetType(), _stackPanel.ContentProperty.CollectionElements[0].Component.GetType());
}
#endregion
}
@@ -177,11 +176,11 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
[Test]
public void CanInsertIntoButton()
{
- /* Insert Image into the Grid's button. This has to be false since some of the
- * ContentControl are not allowed to add element's by moving elements
+ /* Insert Image into the Grid's button. This has now to be true because a button can now
+ * add element's by moving elements
* See DefaultPlacementBehavior.CanContentControlAdd() */
- Assert.IsFalse(_gridButtonNode.CanInsert(new[] {_stackPanelImageNode}, null, false));
+ Assert.IsTrue(_gridButtonNode.CanInsert(new[] {_stackPanelImageNode}, null, false));
}
#region Insert element by Cut operation.
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/SetPropertyTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/SetPropertyTests.cs
new file mode 100644
index 0000000000..ac1ee42aa2
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/SetPropertyTests.cs
@@ -0,0 +1,49 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Markup;
+
+using NUnit.Framework;
+
+namespace ICSharpCode.WpfDesign.Tests.Designer
+{
+ [TestFixture]
+ public class SetPropertyTests : ModelTestHelper
+ {
+ [Test]
+ public void SetContentToBinding()
+ {
+ DesignItem button = CreateCanvasContext("");
+ button.Properties.GetProperty("Content").SetValue(new Binding());
+ AssertCanvasDesignerOutput("", button.Context);
+ }
+
+ [Test, Ignore("Properties are not present in XAML DOM")]
+ public void SetContentToStaticResource()
+ {
+ DesignItem button = CreateCanvasContext(@"");
+ button.Properties.GetProperty("Content").SetValue(new StaticResourceExtension("MyBrush"));
+ // TODO : maybe we should support positional arguments from ctors as well => {StaticResource MyBrush}?
+ AssertCanvasDesignerOutput("", button.Context);
+ }
+
+ [Test, Ignore("Properties are not present in XAML DOM")]
+ public void SetContentToXStatic()
+ {
+ DesignItem button = CreateCanvasContext("");
+ button.Properties.GetProperty("Content").SetValue(new StaticExtension("Button.ClickModeProperty"));
+ AssertCanvasDesignerOutput("", button.Context);
+ }
+
+ [Test]
+ public void SetContentToString()
+ {
+ DesignItem button = CreateCanvasContext("");
+ button.Properties.GetProperty("Content").SetValue("Hello World!");
+ AssertCanvasDesignerOutput("", button.Context);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj
index 971b2682bf..b83b19e35a 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj
@@ -44,6 +44,9 @@
+
+ ..\..\..\..\..\Libraries\RhinoMocks\Rhino.Mocks.dll
+
4.0
@@ -66,6 +69,7 @@
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs
index 0928cc50fd..f21923390f 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs
@@ -7,7 +7,6 @@ using NUnit.Framework;
namespace ICSharpCode.WpfDesign.Tests.XamlDom
{
[TestFixture]
- [Ignore("Broken on .NET 4")]
public class SimpleLoadTests : TestHelper
{
[Test]
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/WhitespaceTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/WhitespaceTests.cs
index a1bfd201d0..71d3d4b6be 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/WhitespaceTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/WhitespaceTests.cs
@@ -7,7 +7,6 @@ using NUnit.Framework;
namespace ICSharpCode.WpfDesign.Tests.XamlDom
{
[TestFixture]
- [Ignore("Broken on .NET 4")]
public class WhitespaceTests : TestHelper
{
[Test]
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs
index d37c2c82d1..f1ae0c21ba 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs
@@ -51,7 +51,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
XamlPropertyInfo info = property.propertyInfo;
object collection = info.GetValue(property.ParentObject.Instance);
- CollectionSupport.Insert(info.ReturnType, collection, item, index);
+ if (!CollectionSupport.TryInsert(info.ReturnType, collection, item, index)) {
+ CollectionSupport.AddToCollection(info.ReturnType, collection, item);
+ }
item.ParentProperty = property;
property.InsertNodeInCollection(item.GetNodeForCollection(), index);
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
index f41ca0f023..b51e5409f2 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
@@ -68,10 +68,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
} else if (collectionInstance is ResourceDictionary) {
object val = newElement.GetValueFor(null);
object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null;
- if (key == null) {
- if (val is Style)
- key = ((Style)val).TargetType;
- }
+ //if (key == null || key == "") {
+ // if (val is Style)
+ // key = ((Style)val).TargetType;
+ //}
+ if (key == null || key == "")
+ key = val;
((ResourceDictionary)collectionInstance).Add(key, val);
} else {
collectionType.InvokeMember(
@@ -94,6 +96,21 @@ namespace ICSharpCode.WpfDesign.XamlDom
CultureInfo.InvariantCulture);
}
+ ///
+ /// Adds a value at the specified index in the collection. A return value indicates whether the Insert succeeded.
+ ///
+ /// True if the Insert succeeded, false if the collection type does not support Insert.
+ internal static bool TryInsert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index)
+ {
+ try {
+ Insert(collectionType, collectionInstance, newElement, index);
+ } catch (MissingMethodException) {
+ return false;
+ }
+
+ return true;
+ }
+
static readonly Type[] RemoveAtParameters = { typeof(int) };
///
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/DesignTimeProperties.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/DesignTimeProperties.cs
new file mode 100644
index 0000000000..e58f6957ee
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/DesignTimeProperties.cs
@@ -0,0 +1,116 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System.Security.Cryptography;
+using System.Windows;
+
+namespace ICSharpCode.WpfDesign.XamlDom
+{
+ ///
+ /// Helper Class for the Design Time Properties used by VS and Blend
+ ///
+ public class DesignTimeProperties : FrameworkElement
+ {
+ #region IsHidden
+
+ public static bool GetIsHidden(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(IsHiddenProperty);
+ }
+
+ public static void SetIsHidden(DependencyObject obj, bool value)
+ {
+ obj.SetValue(IsHiddenProperty, value);
+ }
+
+ public static readonly DependencyProperty IsHiddenProperty =
+ DependencyProperty.RegisterAttached("IsHidden", typeof(bool), typeof(DesignTimeProperties));
+
+ #endregion
+
+ #region IsLocked
+
+ public static bool GetIsLocked(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(IsLockedProperty);
+ }
+
+ public static void SetIsLocked(DependencyObject obj, bool value)
+ {
+ obj.SetValue(IsLockedProperty, value);
+ }
+
+ public static readonly DependencyProperty IsLockedProperty =
+ DependencyProperty.RegisterAttached("IsLocked", typeof(bool), typeof(DesignTimeProperties));
+
+ #endregion
+
+ #region DataContext
+
+ public static object GetDataContext(DependencyObject obj)
+ {
+ return (object)obj.GetValue(DataContextProperty);
+ }
+
+ public static void SetDataContext(DependencyObject obj, bool value)
+ {
+ obj.SetValue(DataContextProperty, value);
+ }
+
+ public static readonly DependencyProperty DataContextProperty =
+ DependencyProperty.RegisterAttached("DataContext", typeof(object), typeof(DesignTimeProperties));
+
+ #endregion
+
+ #region DesignSource
+
+ public static object GetDesignSource(DependencyObject obj)
+ {
+ return (object)obj.GetValue(DesignSourceProperty);
+ }
+
+ public static void SetDesignSource(DependencyObject obj, bool value)
+ {
+ obj.SetValue(DesignSourceProperty, value);
+ }
+
+ public static readonly DependencyProperty DesignSourceProperty =
+ DependencyProperty.RegisterAttached("DesignSource", typeof(object), typeof(DesignTimeProperties));
+
+ #endregion
+
+ #region DesignWidth
+
+ public static double GetDesignWidth(DependencyObject obj)
+ {
+ return (double)obj.GetValue(DesignWidthProperty);
+ }
+
+ public static void SetDesignWidth(DependencyObject obj, double value)
+ {
+ obj.SetValue(DesignWidthProperty, value);
+ }
+
+ public static readonly DependencyProperty DesignWidthProperty =
+ DependencyProperty.RegisterAttached("DesignWidth", typeof(double), typeof(DesignTimeProperties));
+
+ #endregion
+
+ #region DesignHeight
+
+ public static double GetDesignHeight(DependencyObject obj)
+ {
+ return (double)obj.GetValue(DesignHeightProperty);
+ }
+
+ public static void SetDesignHeight(DependencyObject obj, double value)
+ {
+ obj.SetValue(DesignHeightProperty, value);
+ }
+
+ public static readonly DependencyProperty DesignHeightProperty =
+ DependencyProperty.RegisterAttached("DesignHeight", typeof(double), typeof(DesignTimeProperties));
+
+ #endregion
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupCompatibilityProperties.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupCompatibilityProperties.cs
new file mode 100644
index 0000000000..477e79fa9f
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupCompatibilityProperties.cs
@@ -0,0 +1,31 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System.Security.Cryptography;
+using System.Windows;
+
+namespace ICSharpCode.WpfDesign.XamlDom
+{
+ ///
+ /// Helper Class for the Markup Compatibility Properties used by VS and Blend
+ ///
+ public class MarkupCompatibilityProperties : FrameworkElement
+ {
+ #region Ignorable
+
+ public static string GetIgnorable(DependencyObject obj)
+ {
+ return (string)obj.GetValue(IgnorableProperty);
+ }
+
+ public static void SetIgnorable(DependencyObject obj, string value)
+ {
+ obj.SetValue(IgnorableProperty, value);
+ }
+
+ public static readonly DependencyProperty IgnorableProperty =
+ DependencyProperty.RegisterAttached("Ignorable", typeof(string), typeof(MarkupCompatibilityProperties));
+
+ #endregion
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs
index af2b0a6c9a..0ed22768ff 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs
@@ -18,6 +18,40 @@ namespace ICSharpCode.WpfDesign.XamlDom
///
public static bool CanPrint(XamlObject obj)
{
+ if (obj.ElementType == typeof(System.Windows.Data.MultiBinding) ||
+ obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) {
+ return false;
+ }
+
+ foreach (var property in obj.Properties.Where((prop) => prop.IsSet))
+ {
+ var value = property.PropertyValue;
+ if (value is XamlTextValue)
+ continue;
+ else
+ {
+ XamlObject xamlObject = value as XamlObject;
+ if (xamlObject == null || !xamlObject.IsMarkupExtension)
+ return false;
+ else {
+ var staticResource = xamlObject.Instance as System.Windows.StaticResourceExtension;
+ if (staticResource != null &&
+ staticResource.ResourceKey != null) {
+ XamlObject parent = GetNonMarkupExtensionParent(xamlObject);
+
+ if (parent != null) {
+ var parentLocalResource = parent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey);
+
+ // If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension
+ // must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource.
+ if (parentLocalResource != null)
+ return false;
+ }
+ }
+ }
+ }
+ }
+
return true;
}
@@ -53,5 +87,16 @@ namespace ICSharpCode.WpfDesign.XamlDom
sb.Append("}");
return sb.ToString();
}
+
+ private static XamlObject GetNonMarkupExtensionParent(XamlObject markupExtensionObject)
+ {
+ System.Diagnostics.Debug.Assert(markupExtensionObject.IsMarkupExtension);
+
+ XamlObject obj = markupExtensionObject;
+ while (obj != null && obj.IsMarkupExtension) {
+ obj = obj.ParentObject;
+ }
+ return obj;
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs
new file mode 100644
index 0000000000..0ea8458426
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/NameScopeHelper.cs
@@ -0,0 +1,48 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Markup;
+
+namespace ICSharpCode.WpfDesign.XamlDom
+{
+ ///
+ /// Static methods to help with operations on Xaml elements.
+ ///
+ internal static class NameScopeHelper
+ {
+ ///
+ /// Finds the XAML namescope for the specified object and uses it to unregister the old name and then register the new name.
+ ///
+ /// The object where the name was changed.
+ /// The old name.
+ /// The new name.
+ public static void NameChanged(XamlObject namedObject, string oldName, string newName)
+ {
+ var obj = namedObject;
+ while (obj != null) {
+ var nameScope = obj.Instance as INameScope;
+ if (nameScope == null) {
+ var depObj = obj.Instance as DependencyObject;
+ if (depObj != null)
+ nameScope = NameScope.GetNameScope(depObj);
+ }
+ if (nameScope != null) {
+ if (oldName != null) {
+ try {
+ nameScope.UnregisterName(oldName);
+ } catch (Exception x) {
+ Debug.WriteLine(x.Message);
+ }
+ }
+ if (newName != null) {
+ nameScope.RegisterName(newName, namedObject.Instance);
+ }
+ break;
+ }
+ obj = obj.ParentObject;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
index 7fc0d99da0..01ba32c1cd 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
@@ -69,9 +69,12 @@
+
+
+
@@ -88,4 +91,4 @@
-
\ No newline at end of file
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs
index 95c48c552e..05b67541a7 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs
@@ -10,6 +10,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
///
public static class XamlConstants
{
+ #region Namespaces
+
///
/// The namespace used to identify "xmlns".
/// Value: "http://www.w3.org/2000/xmlns/"
@@ -27,5 +29,35 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// Value: "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
///
public const string PresentationNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
+
+ ///
+ /// The namespace used for the DesignTime schema.
+ /// Value: "http://schemas.microsoft.com/expression/blend/2008"
+ ///
+ public const string DesignTimeNamespace = "http://schemas.microsoft.com/expression/blend/2008";
+
+ ///
+ /// The namespace used for the MarkupCompatibility schema.
+ /// Value: "http://schemas.openxmlformats.org/markup-compatibility/2006"
+ ///
+ public const string MarkupCompatibilityNamespace = "http://schemas.openxmlformats.org/markup-compatibility/2006";
+
+ #endregion
+
+ #region Common property names
+
+ ///
+ /// The name of the Resources property.
+ /// Value: "Resources"
+ ///
+ public const string ResourcesPropertyName = "Resources";
+
+ ///
+ /// The name of xmlns.
+ /// Value: "xmlns"
+ ///
+ public const string Xmlns = "xmlns";
+
+ #endregion
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
index 5b62424e57..452ebd719d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
@@ -5,6 +5,11 @@ using System;
using System.ComponentModel;
using System.Windows.Markup;
using System.Xml;
+using System.IO;
+using System.Linq;
+using System.Windows.Documents;
+using System.Windows.Media;
+using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.XamlDom
{
@@ -18,6 +23,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
IServiceProvider _serviceProvider;
XamlTypeFinder _typeFinder;
+
+ int namespacePrefixCounter;
internal XmlDocument XmlDocument {
get { return _xmlDoc; }
@@ -165,19 +172,90 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (forProperty != null && hasStringConverter) {
return new XamlTextValue(this, c.ConvertToInvariantString(ctx, instance));
}
+
+ string ns = GetNamespaceFor(elementType);
+ string prefix = GetPrefixForNamespace(ns);
-
- XmlElement xml = _xmlDoc.CreateElement(elementType.Name, GetNamespaceFor(elementType));
-
- if (hasStringConverter) {
+ XmlElement xml = _xmlDoc.CreateElement(prefix, elementType.Name, ns);
+
+ if (hasStringConverter && XamlObject.GetContentPropertyName(elementType) != null) {
xml.InnerText = c.ConvertToInvariantString(instance);
+ } else if (instance is Brush) { // TODO: this is a hacky fix, because Brush Editor doesn't
+ // edit Design Items and so we have no XML, only the Brush
+ // object and we need to parse the Brush to XAML!
+ var s = new MemoryStream();
+ XamlWriter.Save(instance, s);
+ s.Seek(0, SeekOrigin.Begin);
+ XmlDocument doc = new XmlDocument();
+ doc.Load(s);
+ xml = (XmlElement)_xmlDoc.ImportNode(doc.DocumentElement, true);
+
+ var attLst = xml.Attributes.Cast().ToList();
+ foreach (XmlAttribute att in attLst) {
+ if (att.Name.StartsWith(XamlConstants.Xmlns)) {
+ var rootAtt = doc.DocumentElement.GetAttributeNode(att.Name);
+ if (rootAtt != null && rootAtt.Value == att.Value) {
+ xml.Attributes.Remove(att);
+ }
+ }
+ }
}
+
return new XamlObject(this, xml, elementType, instance);
}
internal string GetNamespaceFor(Type type)
{
+ if (type == typeof (DesignTimeProperties))
+ return XamlConstants.DesignTimeNamespace;
+ if (type == typeof (MarkupCompatibilityProperties))
+ return XamlConstants.MarkupCompatibilityNamespace;
+
return _typeFinder.GetXmlNamespaceFor(type.Assembly, type.Namespace);
}
+
+ internal string GetPrefixForNamespace(string @namespace)
+ {
+ if (@namespace == XamlConstants.PresentationNamespace)
+ {
+ return null;
+ }
+
+ string prefix = _xmlDoc.DocumentElement.GetPrefixOfNamespace(@namespace);
+
+ if (String.IsNullOrEmpty(prefix))
+ {
+ prefix = _typeFinder.GetPrefixForXmlNamespace(@namespace);
+
+ string existingNamespaceForPrefix = null;
+ if (!String.IsNullOrEmpty(prefix))
+ {
+ existingNamespaceForPrefix = _xmlDoc.DocumentElement.GetNamespaceOfPrefix(prefix);
+ }
+
+ if (String.IsNullOrEmpty(prefix) ||
+ !String.IsNullOrEmpty(existingNamespaceForPrefix) &&
+ existingNamespaceForPrefix != @namespace)
+ {
+ do
+ {
+ prefix = "Controls" + namespacePrefixCounter++;
+ } while (!String.IsNullOrEmpty(_xmlDoc.DocumentElement.GetNamespaceOfPrefix(prefix)));
+ }
+
+ string xmlnsPrefix = _xmlDoc.DocumentElement.GetPrefixOfNamespace(XamlConstants.XmlnsNamespace);
+ System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(xmlnsPrefix));
+
+ _xmlDoc.DocumentElement.SetAttribute(xmlnsPrefix + ":" + prefix, @namespace);
+
+ if (@namespace == XamlConstants.DesignTimeNamespace)
+ {
+ var ignorableProp = new XamlProperty(this._rootElement,new XamlDependencyPropertyInfo(MarkupCompatibilityProperties.IgnorableProperty,true));
+ ignorableProp.SetAttribute(prefix);
+ }
+ }
+
+ return prefix;
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
index d9cb3b1aa6..5a01a340ce 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
+using System.Linq;
using System.Windows.Markup;
using System.Xml;
using System.Windows.Data;
@@ -23,7 +24,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
Type elementType;
object instance;
List properties = new List();
-
+ string contentPropertyName;
+ XamlProperty nameProperty;
+ string runtimeNameProperty;
+
/// For use by XamlParser only.
internal XamlObject(XamlDocument document, XmlElement element, Type elementType, object instance)
{
@@ -32,13 +36,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
this.elementType = elementType;
this.instance = instance;
- var contentAttrs = elementType.GetCustomAttributes(typeof(ContentPropertyAttribute), true) as ContentPropertyAttribute[];
- if (contentAttrs != null && contentAttrs.Length > 0) {
- this.contentPropertyName = contentAttrs[0].Name;
- }
+ this.contentPropertyName = GetContentPropertyName(elementType);
ServiceProvider = new XamlObjectServiceProvider(this);
CreateWrapper();
+
+ var rnpAttrs = elementType.GetCustomAttributes(typeof(RuntimeNamePropertyAttribute), true) as RuntimeNamePropertyAttribute[];
+ if (rnpAttrs != null && rnpAttrs.Length > 0 && !String.IsNullOrEmpty(rnpAttrs[0].Name)) {
+ runtimeNameProperty = rnpAttrs[0].Name;
+ }
}
/// For use by XamlParser only.
@@ -99,17 +105,34 @@ namespace ICSharpCode.WpfDesign.XamlDom
XmlAttribute xmlAttribute;
- internal XmlAttribute XmlAttribute {
+ internal XmlAttribute XmlAttribute {
get { return xmlAttribute; }
set {
xmlAttribute = value;
- element = VirualAttachTo(XmlElement, value.OwnerElement);
+ element = VirtualAttachTo(XmlElement, value.OwnerElement);
}
}
- static XmlElement VirualAttachTo(XmlElement e, XmlElement target)
+ string GetPrefixOfNamespace(string ns, XmlElement target)
+ {
+ var prefix = target.GetPrefixOfNamespace(ns);
+ if (!string.IsNullOrEmpty(prefix))
+ return prefix;
+ var obj = this;
+ while (obj != null)
+ {
+ prefix = obj.XmlElement.GetPrefixOfNamespace(ns);
+ if (!string.IsNullOrEmpty(prefix))
+ return prefix;
+ obj = obj.ParentObject;
+ }
+ return null;
+ }
+
+ XmlElement VirtualAttachTo(XmlElement e, XmlElement target)
{
- var prefix = target.GetPrefixOfNamespace(e.NamespaceURI);
+ var prefix = GetPrefixOfNamespace(e.NamespaceURI, target);
+
XmlElement newElement = e.OwnerDocument.CreateElement(prefix, e.LocalName, e.NamespaceURI);
foreach (XmlAttribute a in target.Attributes) {
@@ -130,24 +153,41 @@ namespace ICSharpCode.WpfDesign.XamlDom
return newElement;
}
+ ///
+ /// Gets the name of the content property for the specified element type, or null if not available.
+ ///
+ /// The element type to get the content property name for.
+ /// The name of the content property for the specified element type, or null if not available.
+ internal static string GetContentPropertyName(Type elementType)
+ {
+ var contentAttrs = elementType.GetCustomAttributes(typeof(ContentPropertyAttribute), true) as ContentPropertyAttribute[];
+ if (contentAttrs != null && contentAttrs.Length > 0) {
+ return contentAttrs[0].Name;
+ }
+
+ return null;
+ }
+
internal override void AddNodeTo(XamlProperty property)
- {
- if (!UpdateXmlAttribute(true)) {
+ {
+ XamlObject holder;
+ if (!UpdateXmlAttribute(true, out holder)) {
property.AddChildNodeToProperty(element);
}
UpdateMarkupExtensionChain();
}
internal override void RemoveNodeFromParent()
- {
+ {
if (XmlAttribute != null) {
XmlAttribute.OwnerElement.RemoveAttribute(XmlAttribute.Name);
xmlAttribute = null;
} else {
- if (!UpdateXmlAttribute(false)) {
+ XamlObject holder;
+ if (!UpdateXmlAttribute(false, out holder)) {
element.ParentNode.RemoveChild(element);
}
- }
+ }
//TODO: PropertyValue still there
//UpdateMarkupExtensionChain();
}
@@ -155,23 +195,48 @@ namespace ICSharpCode.WpfDesign.XamlDom
//TODO: reseting path property for binding doesn't work in XamlProperty
//use CanResetValue()
internal void OnPropertyChanged(XamlProperty property)
- {
- UpdateXmlAttribute(false);
+ {
+ XamlObject holder;
+ if (!UpdateXmlAttribute(false, out holder)) {
+ if (holder != null &&
+ holder.XmlAttribute != null) {
+ holder.XmlAttribute.OwnerElement.RemoveAttributeNode(holder.XmlAttribute);
+ holder.xmlAttribute = null;
+ holder.ParentProperty.AddChildNodeToProperty(holder.element);
+
+ bool isThisUpdated = false;
+ foreach(XamlObject propXamlObject in holder.Properties.Where((prop) => prop.IsSet).Select((prop) => prop.PropertyValue).OfType()) {
+ XamlObject innerHolder;
+ bool updateResult = propXamlObject.UpdateXmlAttribute(true, out innerHolder);
+ Debug.Assert(updateResult);
+
+ if (propXamlObject == this)
+ isThisUpdated = true;
+ }
+ if (!isThisUpdated)
+ this.UpdateXmlAttribute(true, out holder);
+ }
+ }
UpdateMarkupExtensionChain();
+
+ if (property == NameProperty) {
+ if (NameChanged != null)
+ NameChanged(this, EventArgs.Empty);
+ }
}
void UpdateMarkupExtensionChain()
{
var obj = this;
- while (obj != null && obj.IsMarkupExtension) {
+ while (obj != null && obj.IsMarkupExtension && obj.ParentProperty != null) {
obj.ParentProperty.UpdateValueOnInstance();
obj = obj.ParentObject;
- }
+ }
}
- bool UpdateXmlAttribute(bool force)
+ bool UpdateXmlAttribute(bool force, out XamlObject holder)
{
- var holder = FindXmlAttributeHolder();
+ holder = FindXmlAttributeHolder();
if (holder == null && force && IsMarkupExtension) {
holder = this;
}
@@ -238,17 +303,63 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
- string contentPropertyName;
-
///
/// Gets the name of the content property.
///
public string ContentPropertyName {
get {
- return contentPropertyName;
+ return contentPropertyName;
+ }
+ }
+
+ ///
+ /// Gets which property name of the type maps to the XAML x:Name attribute.
+ ///
+ public string RuntimeNameProperty {
+ get {
+ return runtimeNameProperty;
+ }
+ }
+
+ ///
+ /// Gets which property of the type maps to the XAML x:Name attribute.
+ ///
+ public XamlProperty NameProperty {
+ get {
+ if(nameProperty == null && runtimeNameProperty != null)
+ nameProperty = FindOrCreateProperty(runtimeNameProperty);
+
+ return nameProperty;
}
}
+ ///
+ /// Gets/Sets the name of this XamlObject.
+ ///
+ public string Name {
+ get
+ {
+ string name = GetXamlAttribute("Name");
+
+ if (String.IsNullOrEmpty(name)) {
+ if (NameProperty != null && NameProperty.IsSet)
+ name = (string)NameProperty.ValueOnInstance;
+ }
+
+ if (name == String.Empty)
+ name = null;
+
+ return name;
+ }
+ set
+ {
+ if (String.IsNullOrEmpty(value))
+ this.SetXamlAttribute("Name", null);
+ else
+ this.SetXamlAttribute("Name", value);
+ }
+ }
+
///
/// Finds the specified property, or creates it if it doesn't exist.
///
@@ -258,7 +369,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
throw new ArgumentNullException("propertyName");
// if (propertyName == ContentPropertyName)
-// return
+// return
foreach (XamlProperty p in properties) {
if (!p.IsAttached && p.PropertyName == propertyName)
@@ -318,10 +429,51 @@ namespace ICSharpCode.WpfDesign.XamlDom
///
public void SetXamlAttribute(string name, string value)
{
+ XamlProperty runtimeNameProperty = null;
+ bool isNameChange = false;
+
+ if (name == "Name") {
+ isNameChange = true;
+ string oldName = GetXamlAttribute("Name");
+
+ if (String.IsNullOrEmpty(oldName)) {
+ runtimeNameProperty = this.NameProperty;
+ if (runtimeNameProperty != null) {
+ if (runtimeNameProperty.IsSet)
+ oldName = (string)runtimeNameProperty.ValueOnInstance;
+ else
+ runtimeNameProperty = null;
+ }
+ }
+
+ if (String.IsNullOrEmpty(oldName))
+ oldName = null;
+
+ NameScopeHelper.NameChanged(this, oldName, value);
+ }
+
if (value == null)
element.RemoveAttribute(name, XamlConstants.XamlNamespace);
else
element.SetAttribute(name, XamlConstants.XamlNamespace, value);
+
+ if (isNameChange) {
+ bool nameChangedAlreadyRaised = false;
+ if (runtimeNameProperty != null) {
+ var handler = new EventHandler((sender, e) => nameChangedAlreadyRaised = true);
+ this.NameChanged += handler;
+
+ try {
+ runtimeNameProperty.Reset();
+ }
+ finally {
+ this.NameChanged -= handler;
+ }
+ }
+
+ if (NameChanged != null && !nameChangedAlreadyRaised)
+ NameChanged(this, EventArgs.Empty);
+ }
}
///
@@ -333,7 +485,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
void CreateWrapper()
{
- if (Instance is Binding) {
+ if (Instance is BindingBase) {
wrapper = new BindingWrapper();
} else if (Instance is StaticResourceExtension) {
wrapper = new StaticResourceWrapper();
@@ -344,7 +496,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
object ProvideValue()
- {
+ {
if (wrapper != null) {
return wrapper.ProvideValue();
}
@@ -353,8 +505,22 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal string GetNameForMarkupExtension()
{
- return XmlElement.Name;
+ string markupExtensionName = XmlElement.Name;
+
+ // By convention a markup extension class name typically includes an "Extension" suffix.
+ // When you reference the markup extension in XAML the "Extension" suffix is optional.
+ // If present remove it to avoid bloating the XAML.
+ if (markupExtensionName.EndsWith("Extension", StringComparison.Ordinal)) {
+ markupExtensionName = markupExtensionName.Substring(0, markupExtensionName.Length - 9);
+ }
+
+ return markupExtensionName;
}
+
+ ///
+ /// Is raised when the name of this XamlObject changes.
+ ///
+ public event EventHandler NameChanged;
}
abstract class MarkupExtensionWrapper
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs
index 523c477125..9bb120195f 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs
@@ -56,14 +56,34 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// Gets the target object (the DependencyObject instance on which a property should be set)
///
public object TargetObject {
- get { return XamlObject.ParentProperty.ParentObject.Instance; }
+ get {
+ var parentProperty = XamlObject.ParentProperty;
+
+ if (parentProperty == null) {
+ return null;
+ }
+
+ if (parentProperty.IsCollection) {
+ return parentProperty.ValueOnInstance;
+ }
+
+ return parentProperty.ParentObject.Instance;
+ }
}
///
/// Gets the target dependency property.
///
public object TargetProperty {
- get { return XamlObject.ParentProperty.DependencyProperty; }
+ get {
+ var parentProperty = XamlObject.ParentProperty;
+
+ if (parentProperty == null) {
+ return null;
+ }
+
+ return parentProperty.DependencyProperty;
+ }
}
#endregion
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
index 0d9abcf9cb..3b05419726 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
@@ -9,6 +9,7 @@ using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
+using System.Windows.Interop;
using System.Windows.Markup;
using System.Xml;
@@ -137,7 +138,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (attribute.NamespaceURI.Length > 0)
return attribute.NamespaceURI;
else
- return attribute.OwnerElement.GetNamespaceOfPrefix("");
+ {
+ var ns = attribute.OwnerElement.GetNamespaceOfPrefix("");
+ if (string.IsNullOrEmpty(ns)) {
+ ns = XamlConstants.PresentationNamespace;
+ }
+ return ns;
+ }
}
readonly static object[] emptyObjectArray = new object[0];
@@ -148,10 +155,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
if (errorSink != null) {
var lineInfo = node as IXmlLineInfo;
+ var msg = x.Message;
+ if (x.InnerException != null)
+ msg += " (" + x.InnerException.Message + ")";
if (lineInfo != null) {
- errorSink.ReportError(x.Message, lineInfo.LineNumber, lineInfo.LinePosition);
+ errorSink.ReportError(msg, lineInfo.LineNumber, lineInfo.LinePosition);
} else {
- errorSink.ReportError(x.Message, 0, 0);
+ errorSink.ReportError(msg, 0, 0);
}
if (currentXamlObject != null) {
currentXamlObject.HasErrors = true;
@@ -244,8 +254,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (attribute.Name == "xml:space") {
continue;
}
- if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace)
+ if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace) {
+ if (attribute.LocalName == "Name") {
+ try {
+ NameScopeHelper.NameChanged(obj, null, attribute.Value);
+ } catch (Exception x) {
+ ReportException(x, attribute);
+ }
+ }
continue;
+ }
+
ParseObjectAttribute(obj, attribute);
}
@@ -265,7 +284,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
{
- XamlPropertyValue setDefaultValueTo = null;
+ bool isDefaultValueSet = false;
object defaultPropertyValue = null;
XamlProperty defaultCollectionProperty = null;
@@ -275,26 +294,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
foreach (XmlNode childNode in GetNormalizedChildNodes(element)) {
-
- // I don't know why the official XamlReader runs the property getter
- // here, but let's try to imitate it as good as possible
- if (defaultProperty != null && !defaultProperty.IsCollection) {
- for (; combinedNormalizedChildNodes > 0; combinedNormalizedChildNodes--) {
- defaultProperty.GetValue(obj.Instance);
- }
- }
-
XmlElement childElement = childNode as XmlElement;
if (childElement != null) {
if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
continue;
if (ObjectChildElementIsPropertyElement(childElement)) {
- // I don't know why the official XamlReader runs the property getter
- // here, but let's try to imitate it as good as possible
- if (defaultProperty != null && !defaultProperty.IsCollection) {
- defaultProperty.GetValue(obj.Instance);
- }
ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
continue;
}
@@ -307,28 +312,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
} else {
- if (setDefaultValueTo != null)
+ if (defaultProperty == null)
+ throw new XamlLoadException("This element does not have a default value, cannot assign to it");
+
+ if (isDefaultValueSet)
throw new XamlLoadException("default property may have only one value assigned");
- setDefaultValueTo = childValue;
+
+ obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue));
+ isDefaultValueSet = true;
}
}
}
-
- if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty) {
- // Runs even when defaultValueSet==false!
- // Again, no idea why the official XamlReader does this.
- defaultProperty.GetValue(obj.Instance);
- }
- if (setDefaultValueTo != null) {
- if (defaultProperty == null) {
- throw new XamlLoadException("This element does not have a default value, cannot assign to it");
- }
- obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueTo));
- }
}
-
- int combinedNormalizedChildNodes;
-
+
IEnumerable GetNormalizedChildNodes(XmlElement element)
{
XmlNode node = element.FirstChild;
@@ -346,8 +342,6 @@ namespace ICSharpCode.WpfDesign.XamlDom
&& (node.NodeType == XmlNodeType.Text
|| node.NodeType == XmlNodeType.CDATA
|| node.NodeType == XmlNodeType.SignificantWhitespace)) {
- combinedNormalizedChildNodes++;
-
if (text != null) text.Value += node.Value;
else cData.Value += node.Value;
XmlNode nodeToDelete = node;
@@ -455,6 +449,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
static XamlPropertyInfo GetPropertyInfo(object elementInstance, Type elementType, XmlAttribute attribute, XamlTypeFinder typeFinder)
{
+ var ret = GetXamlSpecialProperty(attribute);
+ if (ret != null)
+ return ret;
if (attribute.LocalName.Contains(".")) {
return GetPropertyInfo(typeFinder, elementInstance, elementType, GetAttributeNamespace(attribute), attribute.LocalName);
} else {
@@ -462,6 +459,21 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
+ internal static XamlPropertyInfo GetXamlSpecialProperty(XmlAttribute attribute)
+ {
+ if (attribute.LocalName == "Ignorable" && attribute.NamespaceURI == XamlConstants.MarkupCompatibilityNamespace) {
+ return FindAttachedProperty(typeof(MarkupCompatibilityProperties), attribute.LocalName);
+ } else if (attribute.LocalName == "DesignHeight" && attribute.NamespaceURI == XamlConstants.DesignTimeNamespace) {
+ return FindAttachedProperty(typeof(DesignTimeProperties), attribute.LocalName);
+ } else if (attribute.LocalName == "DesignWidth" && attribute.NamespaceURI == XamlConstants.DesignTimeNamespace) {
+ return FindAttachedProperty(typeof(DesignTimeProperties), attribute.LocalName);
+ } else if (attribute.LocalName == "IsHidden" && attribute.NamespaceURI == XamlConstants.DesignTimeNamespace) {
+ return FindAttachedProperty(typeof(DesignTimeProperties), attribute.LocalName);
+ }
+
+ return null;
+ }
+
internal static XamlPropertyInfo GetPropertyInfo(XamlTypeFinder typeFinder, object elementInstance, Type elementType, string xmlNamespace, string localName)
{
string typeName, propertyName;
@@ -556,8 +568,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlPropertyValue childValue = ParseValue(childNode);
if (childValue != null) {
if (propertyInfo.IsCollection) {
- CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue);
- collectionProperty.ParserAddCollectionElement(element, childValue);
+ if (collectionInstance!=null) {
+ CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue);
+ collectionProperty.ParserAddCollectionElement(element, childValue);
+ }
} else {
if (valueWasSet)
throw new XamlLoadException("non-collection property may have only one child element");
@@ -610,6 +624,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
if(xmlnsAttribute!=null)
element.Attributes.Remove(xmlnsAttribute);
+ //Remove namespace Attributes defined in the Xaml Root from the Pasted Snippet!
+ List removeAttributes = new List();
+ foreach (XmlAttribute attrib in element.Attributes) {
+ if (attrib.Name.StartsWith("xmlns:")) {
+ var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value);
+ if (rootPrefix == null) {
+ //todo: check if we can add to root, (maybe same ns exists)
+ root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true));
+ removeAttributes.Add(attrib);
+ } else if (rootPrefix == attrib.Name.Substring(6)) {
+ removeAttributes.Add(attrib);
+ }
+ }
+ }
+ foreach (var removeAttribute in removeAttributes) {
+ element.Attributes.Remove(removeAttribute);
+ }
+ //end remove
+
XamlParser parser = new XamlParser();
parser.settings = settings;
parser.document = root.OwnerDocument;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
index 54293d7738..bf56fb5ec2 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
@@ -1,455 +1,491 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Text;
-using System.Xml;
-using System.Windows;
-using System.Windows.Markup;
-
-namespace ICSharpCode.WpfDesign.XamlDom
-{
- ///
- /// Describes a property on a .
- ///
- [DebuggerDisplay("XamlProperty: {PropertyName}")]
- public sealed class XamlProperty
- {
- XamlObject parentObject;
- internal readonly XamlPropertyInfo propertyInfo;
- XamlPropertyValue propertyValue;
-
- CollectionElementsCollection collectionElements;
- bool isCollection;
-
- static readonly IList emptyCollectionElementsArray = new XamlPropertyValue[0];
-
- // for use by parser only
- internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue)
- : this(parentObject, propertyInfo)
- {
- PossiblyNameChanged(null, propertyValue);
-
- this.propertyValue = propertyValue;
- if (propertyValue != null) {
- propertyValue.ParentProperty = this;
- }
-
- UpdateValueOnInstance();
- }
-
- internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
- {
- this.parentObject = parentObject;
- this.propertyInfo = propertyInfo;
-
- if (propertyInfo.IsCollection) {
- isCollection = true;
- collectionElements = new CollectionElementsCollection(this);
- }
- }
-
- ///
- /// Gets the parent object for which this property was declared.
- ///
- public XamlObject ParentObject {
- get { return parentObject; }
- }
-
- ///
- /// Gets the property name.
- ///
- public string PropertyName {
- get { return propertyInfo.Name; }
- }
-
- ///
- /// Gets the type the property is declared on.
- ///
- public Type PropertyTargetType {
- get { return propertyInfo.TargetType; }
- }
-
- ///
- /// Gets if this property is an attached property.
- ///
- public bool IsAttached {
- get { return propertyInfo.IsAttached; }
- }
-
- ///
- /// Gets if this property is an event.
- ///
- public bool IsEvent {
- get { return propertyInfo.IsEvent; }
- }
-
- ///
- /// Gets the return type of the property.
- ///
- public Type ReturnType {
- get { return propertyInfo.ReturnType; }
- }
-
- ///
- /// Gets the type converter used to convert property values to/from string.
- ///
- public TypeConverter TypeConverter {
- get { return propertyInfo.TypeConverter; }
- }
-
- ///
- /// Gets the category of the property.
- ///
- public string Category {
- get { return propertyInfo.Category; }
- }
-
- ///
- /// Gets the value of the property. Can be null if the property is a collection property.
- ///
- public XamlPropertyValue PropertyValue {
- get { return propertyValue; }
- set { SetPropertyValue(value); }
- }
-
- ///
- /// Gets if the property is a collection property.
- ///
- public bool IsCollection {
- get { return isCollection; }
- }
-
- ///
- /// Gets the collection elements of the property. Is empty if the property is not a collection.
- ///
- public IList CollectionElements {
- get { return collectionElements ?? emptyCollectionElementsArray; }
- }
-
- ///
- /// Gets if the property is set.
- ///
- public bool IsSet {
- get { return propertyValue != null ||
- _propertyElement != null; // collection
- }
- }
-
- ///
- /// Occurs when the value of the IsSet property has changed.
- ///
- public event EventHandler IsSetChanged;
-
- ///
- /// Occurs when the value of the property has changed.
- ///
- public event EventHandler ValueChanged;
-
- ///
- /// Occurs when MarkupExtension evaluated PropertyValue dosn't changed but ValueOnInstance does.
- ///
- public event EventHandler ValueOnInstanceChanged;
-
- void SetPropertyValue(XamlPropertyValue value)
- {
- // Binding...
- //if (IsCollection) {
- // throw new InvalidOperationException("Cannot set the value of collection properties.");
- //}
-
- bool wasSet = this.IsSet;
-
- PossiblyNameChanged(propertyValue, value);
-
- //reset expression
- var xamlObject = propertyValue as XamlObject;
- if (xamlObject != null && xamlObject.IsMarkupExtension)
- propertyInfo.ResetValue(parentObject.Instance);
-
- ResetInternal();
-
- propertyValue = value;
- propertyValue.ParentProperty = this;
- propertyValue.AddNodeTo(this);
- UpdateValueOnInstance();
-
- ParentObject.OnPropertyChanged(this);
-
- if (!wasSet) {
- if (IsSetChanged != null) {
- IsSetChanged(this, EventArgs.Empty);
- }
- }
-
- if (ValueChanged != null) {
- ValueChanged(this, EventArgs.Empty);
- }
- }
-
- internal void UpdateValueOnInstance()
- {
- if (PropertyValue != null) {
- try {
- ValueOnInstance = PropertyValue.GetValueFor(propertyInfo);
- }
- catch {
- Debug.WriteLine("UpdateValueOnInstance() failed");
- }
- }
- }
-
- ///
- /// Resets the properties value.
- ///
- public void Reset()
- {
- if (IsSet) {
-
- propertyInfo.ResetValue(parentObject.Instance);
- ResetInternal();
-
- ParentObject.OnPropertyChanged(this);
-
- if (IsSetChanged != null) {
- IsSetChanged(this, EventArgs.Empty);
- }
- if (ValueChanged != null) {
- ValueChanged(this, EventArgs.Empty);
- }
- }
- }
-
- void ResetInternal()
- {
- if (propertyValue != null) {
- propertyValue.RemoveNodeFromParent();
- propertyValue.ParentProperty = null;
- propertyValue = null;
- }
- if (_propertyElement != null) {
- _propertyElement.ParentNode.RemoveChild(_propertyElement);
- _propertyElement = null;
- }
- }
-
- XmlElement _propertyElement;
-
- internal void ParserSetPropertyElement(XmlElement propertyElement)
- {
- XmlElement oldPropertyElement = _propertyElement;
- if (oldPropertyElement == propertyElement) return;
-
- _propertyElement = propertyElement;
-
- if (oldPropertyElement != null && IsCollection) {
- Debug.WriteLine("Property element for " + this.PropertyName + " already exists, merging..");
- foreach (XamlPropertyValue val in this.collectionElements) {
- val.RemoveNodeFromParent();
- val.AddNodeTo(this);
- }
- oldPropertyElement.ParentNode.RemoveChild(oldPropertyElement);
- }
- }
-
- internal void AddChildNodeToProperty(XmlNode newChildNode)
- {
- if (this.IsCollection) {
- // this is the default collection
- InsertNodeInCollection(newChildNode, collectionElements.Count);
- return;
- }
- if (_propertyElement == null) {
- if (PropertyName == parentObject.ContentPropertyName) {
- parentObject.XmlElement.InsertBefore(newChildNode, parentObject.XmlElement.FirstChild);
- return;
- }
- _propertyElement = parentObject.OwnerDocument.XmlDocument.CreateElement(
- this.PropertyTargetType.Name + "." + this.PropertyName,
- parentObject.OwnerDocument.GetNamespaceFor(this.PropertyTargetType)
- );
- parentObject.XmlElement.InsertBefore(_propertyElement, parentObject.XmlElement.FirstChild);
- }
- _propertyElement.AppendChild(newChildNode);
- }
-
- internal void InsertNodeInCollection(XmlNode newChildNode, int index)
- {
- Debug.Assert(index >= 0 && index <= collectionElements.Count);
- XmlElement collection = _propertyElement;
- if (collection == null) {
- if (collectionElements.Count == 0 && this.PropertyName != this.ParentObject.ContentPropertyName) {
- // we have to create the collection element
- _propertyElement = parentObject.OwnerDocument.XmlDocument.CreateElement(
- this.PropertyTargetType.Name + "." + this.PropertyName,
- parentObject.OwnerDocument.GetNamespaceFor(this.PropertyTargetType)
- );
- parentObject.XmlElement.AppendChild(_propertyElement);
- collection = _propertyElement;
- } else {
- // this is the default collection
- collection = parentObject.XmlElement;
- }
- }
- if (collectionElements.Count == 0) {
- // collection is empty -> we may insert anywhere
- collection.AppendChild(newChildNode);
- } else if (index == collectionElements.Count) {
- // insert after last element in collection
- collection.InsertAfter(newChildNode, collectionElements[collectionElements.Count - 1].GetNodeForCollection());
- } else {
- // insert before specified index
- collection.InsertBefore(newChildNode, collectionElements[index].GetNodeForCollection());
- }
- }
-
- internal XmlAttribute SetAttribute(string value)
- {
- string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType);
- string name;
- if (IsAttached)
- name = PropertyTargetType.Name + "." + PropertyName;
- else
- name = PropertyName;
-
- var element = ParentObject.XmlElement;
- if (string.IsNullOrEmpty(element.GetPrefixOfNamespace(ns))) {
- element.SetAttribute(name, value);
- return element.GetAttributeNode(name);
- } else {
- element.SetAttribute(name, ns, value);
- return element.GetAttributeNode(name, ns);
- }
- }
-
- internal string GetNameForMarkupExtension()
- {
- string name;
- if (IsAttached)
- name = PropertyTargetType.Name + "." + PropertyName;
- else
- name = PropertyName;
-
- var element = ParentObject.XmlElement;
- string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType);
- var prefix = element.GetPrefixOfNamespace(ns);
- if (string.IsNullOrEmpty(prefix))
- return name;
- else
- return prefix + ":" + name;
- }
-
- ///
- /// used internally by the XamlParser.
- /// Add a collection element that already is part of the XML DOM.
- ///
- internal void ParserAddCollectionElement(XmlElement collectionPropertyElement, XamlPropertyValue val)
- {
- if (collectionPropertyElement != null && _propertyElement == null) {
- ParserSetPropertyElement(collectionPropertyElement);
- }
- collectionElements.AddInternal(val);
- val.ParentProperty = this;
- if (collectionPropertyElement != _propertyElement) {
- val.RemoveNodeFromParent();
- val.AddNodeTo(this);
- }
- }
-
- ///
- /// Gets/Sets the value of the property on the instance without updating the XAML document.
- ///
- public object ValueOnInstance {
- get {
- if (IsEvent) {
- if (propertyValue != null)
- return propertyValue.GetValueFor(null);
- else
- return null;
- } else {
- return propertyInfo.GetValue(parentObject.Instance);
- }
- }
- set {
- propertyInfo.SetValue(parentObject.Instance, value);
- if (ValueOnInstanceChanged != null)
- ValueOnInstanceChanged(this, EventArgs.Empty);
- }
- }
-
- ///
- /// Gets if this property is considered "advanced" and should be hidden by default in a property grid.
- ///
- public bool IsAdvanced {
- get { return propertyInfo.IsAdvanced; }
- }
-
- ///
- /// Gets the dependency property.
- ///
- public DependencyProperty DependencyProperty {
- get {
- return propertyInfo.DependencyProperty;
- }
- }
-
- void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue)
- {
- if (PropertyName == "Name" && ReturnType == typeof(string)) {
-
- string oldName = null;
- string newName = null;
-
- var oldTextValue = oldValue as XamlTextValue;
- if (oldTextValue != null) oldName = oldTextValue.Text;
-
- var newTextValue = newValue as XamlTextValue;
- if (newTextValue != null) newName = newTextValue.Text;
-
- var obj = ParentObject;
- while (obj != null) {
- var nameScope = obj.Instance as INameScope;
- if (nameScope == null) {
- if (obj.Instance is DependencyObject)
- nameScope = NameScope.GetNameScope((DependencyObject)obj.Instance);
- }
- if (nameScope != null) {
- if (oldName != null) {
- try {
- nameScope.UnregisterName(oldName);
- } catch (Exception x) {
- Debug.WriteLine(x.Message);
- }
- }
- if (newName != null) {
- nameScope.RegisterName(newName, ParentObject.Instance);
- }
- break;
- }
- obj = obj.ParentObject;
- }
- }
- }
-
- /*public bool IsAttributeSyntax {
- get {
- return attribute != null;
- }
- }
-
- public bool IsElementSyntax {
- get {
- return element != null;
- }
- }
-
- public bool IsImplicitDefaultProperty {
- get {
- return attribute == null && element == null;
- }
- }*/
- }
-}
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Windows;
+using System.Windows.Markup;
+
+namespace ICSharpCode.WpfDesign.XamlDom
+{
+ ///
+ /// Describes a property on a .
+ ///
+ [DebuggerDisplay("XamlProperty: {PropertyName}")]
+ public sealed class XamlProperty
+ {
+ XamlObject parentObject;
+ internal readonly XamlPropertyInfo propertyInfo;
+ XamlPropertyValue propertyValue;
+
+ CollectionElementsCollection collectionElements;
+ bool isCollection;
+ bool isResources;
+
+ static readonly IList emptyCollectionElementsArray = new XamlPropertyValue[0];
+
+ // for use by parser only
+ internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue)
+ : this(parentObject, propertyInfo)
+ {
+ PossiblyNameChanged(null, propertyValue);
+
+ this.propertyValue = propertyValue;
+ if (propertyValue != null) {
+ propertyValue.ParentProperty = this;
+ }
+
+ UpdateValueOnInstance();
+ }
+
+ internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
+ {
+ this.parentObject = parentObject;
+ this.propertyInfo = propertyInfo;
+
+ if (propertyInfo.IsCollection) {
+ isCollection = true;
+ collectionElements = new CollectionElementsCollection(this);
+
+ if (propertyInfo.Name.Equals(XamlConstants.ResourcesPropertyName, StringComparison.Ordinal) &&
+ propertyInfo.ReturnType == typeof(ResourceDictionary)) {
+ isResources = true;
+ }
+ }
+ }
+
+ ///
+ /// Gets the parent object for which this property was declared.
+ ///
+ public XamlObject ParentObject {
+ get { return parentObject; }
+ }
+
+ ///
+ /// Gets the property name.
+ ///
+ public string PropertyName {
+ get { return propertyInfo.Name; }
+ }
+
+ ///
+ /// Gets the type the property is declared on.
+ ///
+ public Type PropertyTargetType {
+ get { return propertyInfo.TargetType; }
+ }
+
+ ///
+ /// Gets if this property is an attached property.
+ ///
+ public bool IsAttached {
+ get { return propertyInfo.IsAttached; }
+ }
+
+ ///
+ /// Gets if this property is an event.
+ ///
+ public bool IsEvent {
+ get { return propertyInfo.IsEvent; }
+ }
+
+ ///
+ /// Gets the return type of the property.
+ ///
+ public Type ReturnType {
+ get { return propertyInfo.ReturnType; }
+ }
+
+ ///
+ /// Gets the type converter used to convert property values to/from string.
+ ///
+ public TypeConverter TypeConverter {
+ get { return propertyInfo.TypeConverter; }
+ }
+
+ ///
+ /// Gets the category of the property.
+ ///
+ public string Category {
+ get { return propertyInfo.Category; }
+ }
+
+ ///
+ /// Gets the value of the property. Can be null if the property is a collection property.
+ ///
+ public XamlPropertyValue PropertyValue {
+ get { return propertyValue; }
+ set { SetPropertyValue(value); }
+ }
+
+ ///
+ /// Gets if the property represents the FrameworkElement.Resources property that holds a locally-defined resource dictionary.
+ ///
+ public bool IsResources {
+ get { return isResources; }
+ }
+
+ ///
+ /// Gets if the property is a collection property.
+ ///
+ public bool IsCollection {
+ get { return isCollection; }
+ }
+
+ ///
+ /// Gets the collection elements of the property. Is empty if the property is not a collection.
+ ///
+ public IList CollectionElements {
+ get { return collectionElements ?? emptyCollectionElementsArray; }
+ }
+
+ ///
+ /// Gets if the property is set.
+ ///
+ public bool IsSet {
+ get { return propertyValue != null ||
+ _propertyElement != null; // collection
+ }
+ }
+
+ ///
+ /// Occurs when the value of the IsSet property has changed.
+ ///
+ public event EventHandler IsSetChanged;
+
+ ///
+ /// Occurs when the value of the property has changed.
+ ///
+ public event EventHandler ValueChanged;
+
+ ///
+ /// Occurs when MarkupExtension evaluated PropertyValue dosn't changed but ValueOnInstance does.
+ ///
+ public event EventHandler ValueOnInstanceChanged;
+
+ void SetPropertyValue(XamlPropertyValue value)
+ {
+ // Binding...
+ //if (IsCollection) {
+ // throw new InvalidOperationException("Cannot set the value of collection properties.");
+ //}
+
+ bool wasSet = this.IsSet;
+
+ PossiblyNameChanged(propertyValue, value);
+
+ //reset expression
+ var xamlObject = propertyValue as XamlObject;
+ if (xamlObject != null && xamlObject.IsMarkupExtension)
+ propertyInfo.ResetValue(parentObject.Instance);
+
+ ResetInternal();
+
+ propertyValue = value;
+ propertyValue.ParentProperty = this;
+ propertyValue.AddNodeTo(this);
+ UpdateValueOnInstance();
+
+ ParentObject.OnPropertyChanged(this);
+
+ if (!wasSet) {
+ if (IsSetChanged != null) {
+ IsSetChanged(this, EventArgs.Empty);
+ }
+ }
+
+ if (ValueChanged != null) {
+ ValueChanged(this, EventArgs.Empty);
+ }
+ }
+
+ internal void UpdateValueOnInstance()
+ {
+ if (PropertyValue != null) {
+ try {
+ ValueOnInstance = PropertyValue.GetValueFor(propertyInfo);
+ }
+ catch {
+ Debug.WriteLine("UpdateValueOnInstance() failed");
+ }
+ }
+ }
+
+ ///
+ /// Resets the properties value.
+ ///
+ public void Reset()
+ {
+ if (IsSet) {
+
+ propertyInfo.ResetValue(parentObject.Instance);
+ ResetInternal();
+
+ ParentObject.OnPropertyChanged(this);
+
+ if (IsSetChanged != null) {
+ IsSetChanged(this, EventArgs.Empty);
+ }
+ if (ValueChanged != null) {
+ ValueChanged(this, EventArgs.Empty);
+ }
+ }
+ }
+
+ void ResetInternal()
+ {
+ if (propertyValue != null) {
+ propertyValue.RemoveNodeFromParent();
+ propertyValue.ParentProperty = null;
+ propertyValue = null;
+ }
+ if (_propertyElement != null) {
+ _propertyElement.ParentNode.RemoveChild(_propertyElement);
+ _propertyElement = null;
+ }
+ }
+
+ XmlElement _propertyElement;
+
+ internal void ParserSetPropertyElement(XmlElement propertyElement)
+ {
+ XmlElement oldPropertyElement = _propertyElement;
+ if (oldPropertyElement == propertyElement) return;
+
+ _propertyElement = propertyElement;
+
+ if (oldPropertyElement != null && IsCollection) {
+ Debug.WriteLine("Property element for " + this.PropertyName + " already exists, merging..");
+ foreach (XamlPropertyValue val in this.collectionElements) {
+ val.RemoveNodeFromParent();
+ val.AddNodeTo(this);
+ }
+ oldPropertyElement.ParentNode.RemoveChild(oldPropertyElement);
+ }
+ }
+
+ bool IsFirstChildResources(XamlObject obj)
+ {
+ return obj.XmlElement.FirstChild != null &&
+ obj.XmlElement.FirstChild.Name.EndsWith("." + XamlConstants.ResourcesPropertyName) &&
+ obj.Properties.Where((prop) => prop.IsResources).FirstOrDefault() != null;
+ }
+
+ XmlElement CreatePropertyElement()
+ {
+ string ns = parentObject.OwnerDocument.GetNamespaceFor(parentObject.ElementType);
+ return parentObject.OwnerDocument.XmlDocument.CreateElement(
+ parentObject.OwnerDocument.GetPrefixForNamespace(ns),
+ parentObject.ElementType.Name + "." + this.PropertyName,
+ ns
+ );
+ }
+
+ internal void AddChildNodeToProperty(XmlNode newChildNode)
+ {
+ if (this.IsCollection) {
+ // this is the default collection
+ InsertNodeInCollection(newChildNode, collectionElements.Count);
+ return;
+ }
+ if (_propertyElement == null) {
+ if (PropertyName == parentObject.ContentPropertyName) {
+ if (IsFirstChildResources(parentObject)) {
+ // Resources element should always be first
+ parentObject.XmlElement.InsertAfter(newChildNode, parentObject.XmlElement.FirstChild);
+ }
+ else
+ parentObject.XmlElement.InsertBefore(newChildNode, parentObject.XmlElement.FirstChild);
+ return;
+ }
+ _propertyElement = CreatePropertyElement();
+
+ if (IsFirstChildResources(parentObject)) {
+ // Resources element should always be first
+ parentObject.XmlElement.InsertAfter(_propertyElement, parentObject.XmlElement.FirstChild);
+ }
+ else
+ parentObject.XmlElement.InsertBefore(_propertyElement, parentObject.XmlElement.FirstChild);
+ }
+ _propertyElement.AppendChild(newChildNode);
+ }
+
+ internal void InsertNodeInCollection(XmlNode newChildNode, int index)
+ {
+ Debug.Assert(index >= 0 && index <= collectionElements.Count);
+ XmlElement collection = _propertyElement;
+ if (collection == null) {
+ if (collectionElements.Count == 0 && this.PropertyName != this.ParentObject.ContentPropertyName) {
+ // we have to create the collection element
+ _propertyElement = CreatePropertyElement();
+
+ if (this.IsResources) {
+ parentObject.XmlElement.PrependChild(_propertyElement);
+ } else {
+ parentObject.XmlElement.AppendChild(_propertyElement);
+ }
+
+ collection = _propertyElement;
+ } else {
+ // this is the default collection
+ collection = parentObject.XmlElement;
+ }
+ }
+ if (collectionElements.Count == 0) {
+ // collection is empty -> we may insert anywhere
+ collection.AppendChild(newChildNode);
+ } else if (index == collectionElements.Count) {
+ // insert after last element in collection
+ collection.InsertAfter(newChildNode, collectionElements[collectionElements.Count - 1].GetNodeForCollection());
+ } else {
+ // insert before specified index
+ collection.InsertBefore(newChildNode, collectionElements[index].GetNodeForCollection());
+ }
+ }
+
+ internal XmlAttribute SetAttribute(string value)
+ {
+ string name;
+ var element = ParentObject.XmlElement;
+
+ if (IsAttached)
+ {
+ if (PropertyTargetType == typeof (DesignTimeProperties) || PropertyTargetType == typeof (MarkupCompatibilityProperties))
+ name = PropertyName;
+ else
+ name = PropertyTargetType.Name + "." + PropertyName;
+
+ string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType);
+ string prefix = element.GetPrefixOfNamespace(ns);
+
+ if (String.IsNullOrEmpty(prefix)) {
+ prefix = ParentObject.OwnerDocument.GetPrefixForNamespace(ns);
+ }
+
+ if (!string.IsNullOrEmpty(prefix)) {
+ element.SetAttribute(name, ns, value);
+ return element.GetAttributeNode(name, ns);
+ }
+ } else {
+ name = PropertyName;
+ }
+
+ element.SetAttribute(name, string.Empty, value);
+ return element.GetAttributeNode(name);
+ }
+
+ internal string GetNameForMarkupExtension()
+ {
+ if (IsAttached) {
+ string name = PropertyTargetType.Name + "." + PropertyName;
+
+ var element = ParentObject.XmlElement;
+ string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType);
+ var prefix = element.GetPrefixOfNamespace(ns);
+ if (string.IsNullOrEmpty(prefix))
+ return name;
+ else
+ return prefix + ":" + name;
+ } else
+ return PropertyName;
+ }
+
+ ///
+ /// used internally by the XamlParser.
+ /// Add a collection element that already is part of the XML DOM.
+ ///
+ internal void ParserAddCollectionElement(XmlElement collectionPropertyElement, XamlPropertyValue val)
+ {
+ if (collectionPropertyElement != null && _propertyElement == null) {
+ ParserSetPropertyElement(collectionPropertyElement);
+ }
+ collectionElements.AddInternal(val);
+ val.ParentProperty = this;
+ if (collectionPropertyElement != _propertyElement) {
+ val.RemoveNodeFromParent();
+ val.AddNodeTo(this);
+ }
+ }
+
+ ///
+ /// Gets/Sets the value of the property on the instance without updating the XAML document.
+ ///
+ public object ValueOnInstance {
+ get {
+ if (IsEvent) {
+ if (propertyValue != null)
+ return propertyValue.GetValueFor(null);
+ else
+ return null;
+ } else {
+ return propertyInfo.GetValue(parentObject.Instance);
+ }
+ }
+ set {
+ propertyInfo.SetValue(parentObject.Instance, value);
+ if (ValueOnInstanceChanged != null)
+ ValueOnInstanceChanged(this, EventArgs.Empty);
+ }
+ }
+
+ ///
+ /// Gets if this property is considered "advanced" and should be hidden by default in a property grid.
+ ///
+ public bool IsAdvanced {
+ get { return propertyInfo.IsAdvanced; }
+ }
+
+ ///
+ /// Gets the dependency property.
+ ///
+ public DependencyProperty DependencyProperty {
+ get {
+ return propertyInfo.DependencyProperty;
+ }
+ }
+
+ void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue)
+ {
+ if (ParentObject.RuntimeNameProperty != null && PropertyName == ParentObject.RuntimeNameProperty) {
+
+ if (!String.IsNullOrEmpty(ParentObject.GetXamlAttribute("Name"))) {
+ throw new XamlLoadException("The property 'Name' is set more than once.");
+ }
+
+ string oldName = null;
+ string newName = null;
+
+ var oldTextValue = oldValue as XamlTextValue;
+ if (oldTextValue != null) oldName = oldTextValue.Text;
+
+ var newTextValue = newValue as XamlTextValue;
+ if (newTextValue != null) newName = newTextValue.Text;
+
+ NameScopeHelper.NameChanged(ParentObject, oldName, newName);
+ }
+ }
+
+ /*public bool IsAttributeSyntax {
+ get {
+ return attribute != null;
+ }
+ }
+
+ public bool IsElementSyntax {
+ get {
+ return element != null;
+ }
+ }
+
+ public bool IsImplicitDefaultProperty {
+ get {
+ return attribute == null && element == null;
+ }
+ }*/
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs
index 0abcbd0afd..87092af3f7 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs
@@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Markup;
+using System.Xaml;
+using XamlReader = System.Windows.Markup.XamlReader;
namespace ICSharpCode.WpfDesign.XamlDom
{
@@ -43,10 +45,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
sealed class XamlNamespace
{
+ internal readonly string XmlNamespacePrefix;
internal readonly string XmlNamespace;
- internal XamlNamespace(string xmlNamespace)
+ internal XamlNamespace(string xmlNamespacePrefix, string xmlNamespace)
{
+ this.XmlNamespacePrefix = xmlNamespacePrefix;
this.XmlNamespace = xmlNamespace;
}
@@ -54,7 +58,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal XamlNamespace Clone()
{
- XamlNamespace copy = new XamlNamespace(this.XmlNamespace);
+ XamlNamespace copy = new XamlNamespace(this.XmlNamespacePrefix, this.XmlNamespace);
// AssemblyNamespaceMapping is immutable
copy.ClrNamespaces.AddRange(this.ClrNamespaces);
return copy;
@@ -108,6 +112,21 @@ namespace ICSharpCode.WpfDesign.XamlDom
return "clr-namespace:" + mapping.Namespace + ";assembly=" + mapping.Assembly.GetName().Name;
}
}
+
+ ///
+ /// Gets the prefix to use for the specified XML namespace,
+ /// or null if no suitable prefix could be found.
+ ///
+ public string GetPrefixForXmlNamespace(string xmlNamespace)
+ {
+ XamlNamespace ns;
+
+ if (namespaces.TryGetValue(xmlNamespace, out ns)) {
+ return ns.XmlNamespacePrefix;
+ } else {
+ return null;
+ }
+ }
XamlNamespace ParseNamespace(string xmlNamespace)
{
@@ -127,7 +146,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
assembly = name.Substring("assembly=".Length);
}
- XamlNamespace ns = new XamlNamespace(xmlNamespace);
+ XamlNamespace ns = new XamlNamespace(null, xmlNamespace);
Assembly asm = LoadAssembly(assembly);
if (asm != null) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName));
@@ -155,10 +174,18 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
if (assembly == null)
throw new ArgumentNullException("assembly");
+
+ Dictionary namespacePrefixes = new Dictionary();
+ foreach (XmlnsPrefixAttribute xmlnsPrefix in assembly.GetCustomAttributes(typeof(XmlnsPrefixAttribute), true)) {
+ namespacePrefixes.Add(xmlnsPrefix.XmlNamespace, xmlnsPrefix.Prefix);
+ }
+
foreach (XmlnsDefinitionAttribute xmlnsDef in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), true)) {
XamlNamespace ns;
if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) {
- ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(xmlnsDef.XmlNamespace);
+ string prefix;
+ namespacePrefixes.TryGetValue(xmlnsDef.XmlNamespace, out prefix);
+ ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(prefix, xmlnsDef.XmlNamespace);
}
if (string.IsNullOrEmpty(xmlnsDef.AssemblyName)) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace));
@@ -171,6 +198,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
+ ///
+ /// Register the Namspaces not found in any Assembly, but used by VS and Expression Blend
+ ///
+ public void RegisterFixNamespaces()
+ {
+ var ns = namespaces[XamlConstants.DesignTimeNamespace] = new XamlNamespace("d", XamlConstants.DesignTimeNamespace);
+ AddMappingToNamespace(ns, new AssemblyNamespaceMapping(typeof(DesignTimeProperties).Assembly, typeof(DesignTimeProperties).Namespace));
+ ns = namespaces[XamlConstants.MarkupCompatibilityNamespace] = new XamlNamespace("mc", XamlConstants.MarkupCompatibilityNamespace);
+ AddMappingToNamespace(ns, new AssemblyNamespaceMapping(typeof(MarkupCompatibilityProperties).Assembly, typeof(MarkupCompatibilityProperties).Namespace));
+ }
+
///
/// Load the assembly with the specified name.
/// You can override this method to implement custom assembly lookup.
@@ -228,9 +266,11 @@ namespace ICSharpCode.WpfDesign.XamlDom
static WpfTypeFinder()
{
Instance = new XamlTypeFinder();
+ Instance.RegisterFixNamespaces();
Instance.RegisterAssembly(typeof(MarkupExtension).Assembly); // WindowsBase
Instance.RegisterAssembly(typeof(IAddChild).Assembly); // PresentationCore
Instance.RegisterAssembly(typeof(XamlReader).Assembly); // PresentationFramework
+ Instance.RegisterAssembly(typeof(XamlType).Assembly); // System.Xaml
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
index f4a1b86145..5bdf7ae47d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
@@ -29,16 +29,32 @@ namespace ICSharpCode.WpfDesign.XamlDom
XmlElement ContainingElement{
get { return containingObject.XmlElement; }
}
+
+ private string GetNamespaceOfPrefix(string prefix)
+ {
+ var ns = ContainingElement.GetNamespaceOfPrefix(prefix);
+ if (!string.IsNullOrEmpty(ns))
+ return ns;
+ var obj = containingObject;
+ while (obj != null)
+ {
+ ns = obj.XmlElement.GetNamespaceOfPrefix(prefix);
+ if (!string.IsNullOrEmpty(ns))
+ return ns;
+ obj = obj.ParentObject;
+ }
+ return null;
+ }
public Type Resolve(string typeName)
{
string typeNamespaceUri;
string typeLocalName;
if (typeName.Contains(":")) {
- typeNamespaceUri = ContainingElement.GetNamespaceOfPrefix(typeName.Substring(0, typeName.IndexOf(':')));
+ typeNamespaceUri = GetNamespaceOfPrefix(typeName.Substring(0, typeName.IndexOf(':')));
typeLocalName = typeName.Substring(typeName.IndexOf(':') + 1);
} else {
- typeNamespaceUri = ContainingElement.GetNamespaceOfPrefix("");
+ typeNamespaceUri = GetNamespaceOfPrefix("");
typeLocalName = typeName;
}
if (string.IsNullOrEmpty(typeNamespaceUri))
@@ -96,5 +112,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
return null;
}
+
+ public object FindLocalResource(object key)
+ {
+ FrameworkElement el = containingObject.Instance as FrameworkElement;
+ if (el != null) {
+ return el.Resources[key];
+ }
+ return null;
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
index 626d353d9b..60d77c956d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
@@ -34,6 +34,16 @@ namespace ICSharpCode.WpfDesign.Adorners
return (AdornerPlacement)adorner.GetValue(PlacementProperty);
}
+ public Vector AbsoluteToRelative(Vector absolute)
+ {
+ return new Vector(absolute.X / ((FrameworkElement) this._adornedElement).ActualWidth, absolute.Y / ((FrameworkElement) this._adornedElement).ActualHeight);
+ }
+
+ public Vector RelativeToAbsolute(Vector relative)
+ {
+ return new Vector(relative.X * ((FrameworkElement) this._adornedElement).ActualWidth, relative.Y * ((FrameworkElement) this._adornedElement).ActualHeight);
+ }
+
///
/// Sets the placement of the specified adorner.
///
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
index ee93c82920..7ab86de912 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
@@ -64,6 +64,11 @@ namespace ICSharpCode.WpfDesign
///
public abstract string Name { get; set; }
+ ///
+ /// Gets/Sets the value of the "x:Key" attribute on the design item.
+ ///
+ public abstract string Key { get; set; }
+
///
/// Is raised when the name of the design item changes.
///
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs
index 69f9a54dfd..bd9df3670c 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs
@@ -1,7 +1,8 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.ComponentModel;
using System.Windows;
namespace ICSharpCode.WpfDesign
@@ -22,6 +23,52 @@ namespace ICSharpCode.WpfDesign
Math.Round(rect.Width, PlacementInformation.BoundsPrecision),
Math.Round(rect.Height, PlacementInformation.BoundsPrecision)
);
+ }
+
+ ///
+ /// Gets the design item property for the specified member descriptor.
+ ///
+ public static DesignItemProperty GetProperty(this DesignItemPropertyCollection properties, MemberDescriptor md)
+ {
+ DesignItemProperty prop = null;
+
+ var pd = md as PropertyDescriptor;
+ if (pd != null)
+ {
+ var dpd = DependencyPropertyDescriptor.FromProperty(pd);
+ if (dpd != null)
+ {
+ if (dpd.IsAttached)
+ {
+ prop = properties.GetAttachedProperty(dpd.DependencyProperty);
+ }
+ else
+ {
+ prop = properties.GetProperty(dpd.DependencyProperty);
+ }
+ }
+ }
+
+ if (prop == null)
+ {
+ prop = properties[md.Name];
+ }
+
+ return prop;
+ }
+
+ ///
+ /// Gets if the specified design item property represents an attached dependency property.
+ ///
+ public static bool IsAttachedDependencyProperty(this DesignItemProperty property)
+ {
+ if (property.DependencyProperty != null)
+ {
+ var dpd = DependencyPropertyDescriptor.FromProperty(property.DependencyProperty, property.DesignItem.ComponentType);
+ return dpd.IsAttached;
+ }
+
+ return false;
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs
index 17caabc7df..b81f6facc3 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs
@@ -298,7 +298,7 @@ namespace ICSharpCode.WpfDesign
/// Gets the default size for new controls of the specified type,
/// or new Size(double.NaN, double.NaN) if no default size was registered.
///
- public static Size GetDefaultSize(Type t)
+ public static Size GetDefaultSize(Type t, bool checkBasetype = true)
{
Size s;
lock (defaultSizes) {
@@ -306,7 +306,7 @@ namespace ICSharpCode.WpfDesign
if (defaultSizes.TryGetValue(t, out s)) {
return s;
}
- t = t.BaseType;
+ t = checkBasetype ? t.BaseType : null;
}
}
return new Size(double.NaN, double.NaN);
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs
index efe5821223..1d4b27208d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs
@@ -57,7 +57,7 @@ namespace ICSharpCode.WpfDesign
///
/// Gets if entering this container is allowed for the specified operation.
///
- bool CanEnterContainer(PlacementOperation operation);
+ bool CanEnterContainer(PlacementOperation operation, bool shouldAlwaysEnter);
///
/// Let the placed children enter this container.
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs
index 8f69db39ba..4157f741ac 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs
@@ -13,9 +13,9 @@ namespace ICSharpCode.WpfDesign
{
///
/// The designer rounds bounds to this number of digits to avoid floating point errors.
- /// Value: 8
+ /// Value: 1
///
- public const int BoundsPrecision = 8;
+ public const int BoundsPrecision = 1;
Rect originalBounds, bounds;
readonly DesignItem item;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs
index a63a2b9d01..068e337975 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs
@@ -246,7 +246,7 @@ namespace ICSharpCode.WpfDesign
}
op.currentContainer = container;
op.currentContainerBehavior = container.GetBehavior();
- if (op.currentContainerBehavior == null || !op.currentContainerBehavior.CanEnterContainer(op)) {
+ if (op.currentContainerBehavior == null || !op.currentContainerBehavior.CanEnterContainer(op, true)) {
op.changeGroup.Abort();
return null;
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs
index 79b0563bf5..2c47cd9fa9 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs
@@ -35,6 +35,12 @@ namespace ICSharpCode.WpfDesign
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType Delete = Register("Delete");
+ ///
+ /// Inserting from Cliboard
+ ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
+ public static readonly PlacementType PasteItem = Register("PasteItem");
+
readonly string name;
private PlacementType(string name)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/Editors/ComboBoxEditor.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/Editors/ComboBoxEditor.xaml
index 037a1ad28e..88e8dab911 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/Editors/ComboBoxEditor.xaml
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/Editors/ComboBoxEditor.xaml
@@ -7,4 +7,9 @@
Background="{x:Null}"
Focusable="False"
>
+
+
+
+
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs
index d212ead152..dd1efb0a43 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs
@@ -1,403 +1,420 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel;
-using System.Windows;
-using System.Windows.Controls;
-using System.Collections.ObjectModel;
-using System.Windows.Data;
-using System.Windows.Media;
-using System.Windows.Markup;
-
-namespace ICSharpCode.WpfDesign.PropertyGrid
-{
- ///
- /// View-Model class for the property grid.
- ///
- public class PropertyNode : INotifyPropertyChanged
- {
- static object Unset = new object();
-
- ///
- /// Gets the properties that are presented by this node.
- /// This might be multiple properties if multiple controls are selected.
- ///
- public ReadOnlyCollection Properties { get; private set; }
-
- bool raiseEvents = true;
- bool hasStringConverter;
-
- ///
- /// Gets the name of the property.
- ///
- public string Name { get { return FirstProperty.Name; } }
-
- ///
- /// Gets if this property node represents an event.
- ///
- public bool IsEvent { get { return FirstProperty.IsEvent; } }
-
- ///
- /// Gets the design context associated with this set of properties.
- ///
- public DesignContext Context { get { return FirstProperty.DesignItem.Context; } }
-
- ///
- /// Gets the service container associated with this set of properties.
- ///
- public ServiceContainer Services { get { return FirstProperty.DesignItem.Services; } }
-
- ///
- /// Gets the editor control that edits this property.
- ///
- public FrameworkElement Editor { get; private set; }
-
- ///
- /// Gets the first property (equivalent to Properties[0])
- ///
- public DesignItemProperty FirstProperty { get { return Properties[0]; } }
-
- ///
- /// For nested property nodes, gets the parent node.
- ///
- public PropertyNode Parent { get; private set; }
-
- ///
- /// For nested property nodes, gets the level of this node.
- ///
- public int Level { get; private set; }
-
- ///
- /// Gets the category of this node.
- ///
- public Category Category { get; set; }
-
- ///
- /// Gets the list of child nodes.
- ///
- public ObservableCollection Children { get; private set; }
-
- ///
- /// Gets the list of advanced child nodes (not visible by default).
- ///
- public ObservableCollection MoreChildren { get; private set; }
-
- bool isExpanded;
-
- ///
- /// Gets whether this property node is currently expanded.
- ///
- public bool IsExpanded {
- get {
- return isExpanded;
- }
- set {
- isExpanded = value;
- UpdateChildren();
- RaisePropertyChanged("IsExpanded");
- }
- }
-
- ///
- /// Gets whether this property node has children.
- ///
- public bool HasChildren {
- get { return Children.Count > 0 || MoreChildren.Count > 0; }
- }
-
- ///
- /// Gets the description object using the IPropertyDescriptionService.
- ///
- public object Description {
- get {
- IPropertyDescriptionService s = Services.GetService();
- if (s != null) {
- return s.GetDescription(FirstProperty);
- }
- return null;
- }
- }
-
- ///
- /// Gets/Sets the value of this property.
- ///
- public object Value {
- get {
- if (IsAmbiguous) return null;
- var result = FirstProperty.ValueOnInstance;
- if (result == DependencyProperty.UnsetValue) return null;
- return result;
- }
- set {
- SetValueCore(value);
- }
- }
-
- ///
- /// Gets/Sets the value of this property in string form
- ///
- public string ValueString {
- get {
- if (ValueItem == null || ValueItem.Component is MarkupExtension) {
- if (Value == null) return null;
- if (hasStringConverter) {
- return FirstProperty.TypeConverter.ConvertToInvariantString(Value);
- }
- return "(" + Value.GetType().Name + ")";
- }
- return "(" + ValueItem.ComponentType.Name + ")";
- }
- set {
- // make sure we only catch specific exceptions
- // and/or show the error message to the user
- //try {
- Value = FirstProperty.TypeConverter.ConvertFromInvariantString(value);
- //} catch {
- // OnValueOnInstanceChanged();
- //}
- }
- }
-
- ///
- /// Gets whether the property node is enabled for editing.
- ///
- public bool IsEnabled {
- get {
- return ValueItem == null && hasStringConverter;
- }
- }
-
- ///
- /// Gets whether this property was set locally.
- ///
- public bool IsSet {
- get {
- foreach (var p in Properties) {
- if (p.IsSet) return true;
- }
- return false;
- }
- }
-
- ///
- /// Gets the color of the name.
- /// Depends on the type of the value (binding/resource/etc.)
- ///
- public Brush NameForeground {
- get {
- if (ValueItem != null) {
- object component = ValueItem.Component;
- if (component is BindingBase)
- return Brushes.DarkGoldenrod;
- if (component is StaticResourceExtension || component is DynamicResourceExtension)
- return Brushes.DarkGreen;
- }
- return SystemColors.WindowTextBrush;
- }
- }
-
- ///
- /// Returns the DesignItem that owns the property (= the DesignItem that is currently selected).
- /// Returns null if multiple DesignItems are selected.
- ///
- public DesignItem ValueItem {
- get {
- if (Properties.Count == 1) {
- return FirstProperty.Value;
- }
- return null;
- }
- }
-
- ///
- /// Gets whether the property value is ambiguous (multiple controls having different values are selected).
- ///
- public bool IsAmbiguous {
- get {
- foreach (var p in Properties) {
- if (!object.Equals(p.ValueOnInstance, FirstProperty.ValueOnInstance)) {
- return true;
- }
- }
- return false;
- }
- }
-
- bool isVisible;
-
- ///
- /// Gets/Sets whether the property is visible.
- ///
- public bool IsVisible {
- get {
- return isVisible;
- }
- set {
- isVisible = value;
- RaisePropertyChanged("IsVisible");
- }
- }
-
- ///
- /// Gets whether resetting the property is possible.
- ///
- public bool CanReset {
- get { return IsSet; }
- }
-
- ///
- /// Resets the property.
- ///
- public void Reset()
- {
- SetValueCore(Unset);
- }
-
- ///
- /// Replaces the value of this node with a new binding.
- ///
- public void CreateBinding()
- {
- Value = new Binding();
- IsExpanded = true;
- }
-
- void SetValueCore(object value)
- {
- raiseEvents = false;
- if (value == Unset) {
- foreach (var p in Properties) {
- p.Reset();
- }
- } else {
- foreach (var p in Properties) {
- p.SetValue(value);
- }
- }
- raiseEvents = true;
- OnValueChanged();
- }
-
- void OnValueChanged()
- {
- RaisePropertyChanged("IsSet");
- RaisePropertyChanged("Value");
- RaisePropertyChanged("ValueString");
- RaisePropertyChanged("IsAmbiguous");
- RaisePropertyChanged("FontWeight");
- RaisePropertyChanged("IsEnabled");
- RaisePropertyChanged("NameForeground");
-
- UpdateChildren();
- }
-
- void OnValueOnInstanceChanged()
- {
- RaisePropertyChanged("Value");
- RaisePropertyChanged("ValueString");
- }
-
- ///
- /// Creates a new PropertyNode instance.
- ///
- public PropertyNode()
- {
- Children = new ObservableCollection();
- MoreChildren = new ObservableCollection();
- }
-
- PropertyNode(DesignItemProperty[] properties, PropertyNode parent) : this()
- {
- this.Parent = parent;
- this.Level = parent == null ? 0 : parent.Level + 1;
- Load(properties);
- }
-
- ///
- /// Initializes this property node with the specified properties.
- ///
- public void Load(DesignItemProperty[] properties)
- {
- if (this.Properties != null) {
- // detach events from old properties
- foreach (var property in this.Properties) {
- property.ValueChanged -= new EventHandler(property_ValueChanged);
- property.ValueOnInstanceChanged -= new EventHandler(property_ValueOnInstanceChanged);
- }
- }
-
- this.Properties = new ReadOnlyCollection(properties);
-
- if (Editor == null)
- Editor = EditorManager.CreateEditor(FirstProperty);
-
- foreach (var property in properties) {
- property.ValueChanged += new EventHandler(property_ValueChanged);
- property.ValueOnInstanceChanged += new EventHandler(property_ValueOnInstanceChanged);
- }
-
- hasStringConverter =
- FirstProperty.TypeConverter.CanConvertFrom(typeof(string)) &&
- FirstProperty.TypeConverter.CanConvertTo(typeof(string));
-
- OnValueChanged();
- }
-
- void property_ValueOnInstanceChanged(object sender, EventArgs e)
- {
- if (raiseEvents) OnValueOnInstanceChanged();
- }
-
- void property_ValueChanged(object sender, EventArgs e)
- {
- if (raiseEvents) OnValueChanged();
- }
-
- void UpdateChildren()
- {
- Children.Clear();
- MoreChildren.Clear();
-
- if (Parent == null || Parent.IsExpanded) {
- if (ValueItem != null) {
- var list = TypeHelper.GetAvailableProperties(ValueItem.Component)
- .OrderBy(d => d.Name)
- .Select(d => new PropertyNode(new[] { ValueItem.Properties[d.Name] }, this));
-
- foreach (var node in list) {
- if (Metadata.IsBrowsable(node.FirstProperty)) {
- node.IsVisible = true;
- if (Metadata.IsPopularProperty(node.FirstProperty)) {
- Children.Add(node);
- } else {
- MoreChildren.Add(node);
- }
- }
- }
- }
- }
-
- RaisePropertyChanged("HasChildren");
- }
-
- #region INotifyPropertyChanged Members
-
- ///
- /// Occurs when a property has changed. Used to support WPF data binding.
- ///
- public event PropertyChangedEventHandler PropertyChanged;
-
- void RaisePropertyChanged(string name)
- {
- if (PropertyChanged != null) {
- PropertyChanged(this, new PropertyChangedEventArgs(name));
- }
- }
-
- #endregion
- }
-}
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Collections.ObjectModel;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Markup;
+
+namespace ICSharpCode.WpfDesign.PropertyGrid
+{
+ ///
+ /// View-Model class for the property grid.
+ ///
+ public class PropertyNode : INotifyPropertyChanged
+ {
+ static object Unset = new object();
+
+ ///
+ /// Gets the properties that are presented by this node.
+ /// This might be multiple properties if multiple controls are selected.
+ ///
+ public ReadOnlyCollection Properties { get; private set; }
+
+ bool raiseEvents = true;
+ bool hasStringConverter;
+
+ ///
+ /// Gets the name of the property.
+ ///
+ public string Name
+ {
+ get
+ {
+ var dp = FirstProperty.DependencyProperty;
+ if (dp != null)
+ {
+ var dpd = DependencyPropertyDescriptor.FromProperty(dp, FirstProperty.DesignItem.ComponentType);
+ if (dpd.IsAttached)
+ {
+ // Will return the attached property name in the form of .
+ return dpd.Name;
+ }
+ }
+
+ return FirstProperty.Name;
+ }
+ }
+
+ ///
+ /// Gets if this property node represents an event.
+ ///
+ public bool IsEvent { get { return FirstProperty.IsEvent; } }
+
+ ///
+ /// Gets the design context associated with this set of properties.
+ ///
+ public DesignContext Context { get { return FirstProperty.DesignItem.Context; } }
+
+ ///
+ /// Gets the service container associated with this set of properties.
+ ///
+ public ServiceContainer Services { get { return FirstProperty.DesignItem.Services; } }
+
+ ///
+ /// Gets the editor control that edits this property.
+ ///
+ public FrameworkElement Editor { get; private set; }
+
+ ///
+ /// Gets the first property (equivalent to Properties[0])
+ ///
+ public DesignItemProperty FirstProperty { get { return Properties[0]; } }
+
+ ///
+ /// For nested property nodes, gets the parent node.
+ ///
+ public PropertyNode Parent { get; private set; }
+
+ ///
+ /// For nested property nodes, gets the level of this node.
+ ///
+ public int Level { get; private set; }
+
+ ///
+ /// Gets the category of this node.
+ ///
+ public Category Category { get; set; }
+
+ ///
+ /// Gets the list of child nodes.
+ ///
+ public ObservableCollection Children { get; private set; }
+
+ ///
+ /// Gets the list of advanced child nodes (not visible by default).
+ ///
+ public ObservableCollection MoreChildren { get; private set; }
+
+ bool isExpanded;
+
+ ///
+ /// Gets whether this property node is currently expanded.
+ ///
+ public bool IsExpanded {
+ get {
+ return isExpanded;
+ }
+ set {
+ isExpanded = value;
+ UpdateChildren();
+ RaisePropertyChanged("IsExpanded");
+ }
+ }
+
+ ///
+ /// Gets whether this property node has children.
+ ///
+ public bool HasChildren {
+ get { return Children.Count > 0 || MoreChildren.Count > 0; }
+ }
+
+ ///
+ /// Gets the description object using the IPropertyDescriptionService.
+ ///
+ public object Description {
+ get {
+ IPropertyDescriptionService s = Services.GetService();
+ if (s != null) {
+ return s.GetDescription(FirstProperty);
+ }
+ return null;
+ }
+ }
+
+ ///
+ /// Gets/Sets the value of this property.
+ ///
+ public object Value {
+ get {
+ if (IsAmbiguous) return null;
+ var result = FirstProperty.ValueOnInstance;
+ if (result == DependencyProperty.UnsetValue) return null;
+ return result;
+ }
+ set {
+ SetValueCore(value);
+ }
+ }
+
+ ///
+ /// Gets/Sets the value of this property in string form
+ ///
+ public string ValueString {
+ get {
+ if (ValueItem == null || ValueItem.Component is MarkupExtension) {
+ if (Value == null) return null;
+ if (hasStringConverter) {
+ return FirstProperty.TypeConverter.ConvertToInvariantString(Value);
+ }
+ return "(" + Value.GetType().Name + ")";
+ }
+ return "(" + ValueItem.ComponentType.Name + ")";
+ }
+ set {
+ // make sure we only catch specific exceptions
+ // and/or show the error message to the user
+ //try {
+ Value = FirstProperty.TypeConverter.ConvertFromInvariantString(value);
+ //} catch {
+ // OnValueOnInstanceChanged();
+ //}
+ }
+ }
+
+ ///
+ /// Gets whether the property node is enabled for editing.
+ ///
+ public bool IsEnabled {
+ get {
+ return ValueItem == null && hasStringConverter;
+ }
+ }
+
+ ///
+ /// Gets whether this property was set locally.
+ ///
+ public bool IsSet {
+ get {
+ foreach (var p in Properties) {
+ if (p.IsSet) return true;
+ }
+ return false;
+ }
+ }
+
+ ///
+ /// Gets the color of the name.
+ /// Depends on the type of the value (binding/resource/etc.)
+ ///
+ public Brush NameForeground {
+ get {
+ if (ValueItem != null) {
+ object component = ValueItem.Component;
+ if (component is BindingBase)
+ return Brushes.DarkGoldenrod;
+ if (component is StaticResourceExtension || component is DynamicResourceExtension)
+ return Brushes.DarkGreen;
+ }
+ return SystemColors.WindowTextBrush;
+ }
+ }
+
+ ///
+ /// Returns the DesignItem that owns the property (= the DesignItem that is currently selected).
+ /// Returns null if multiple DesignItems are selected.
+ ///
+ public DesignItem ValueItem {
+ get {
+ if (Properties.Count == 1) {
+ return FirstProperty.Value;
+ }
+ return null;
+ }
+ }
+
+ ///
+ /// Gets whether the property value is ambiguous (multiple controls having different values are selected).
+ ///
+ public bool IsAmbiguous {
+ get {
+ foreach (var p in Properties) {
+ if (!object.Equals(p.ValueOnInstance, FirstProperty.ValueOnInstance)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ bool isVisible;
+
+ ///
+ /// Gets/Sets whether the property is visible.
+ ///
+ public bool IsVisible {
+ get {
+ return isVisible;
+ }
+ set {
+ isVisible = value;
+ RaisePropertyChanged("IsVisible");
+ }
+ }
+
+ ///
+ /// Gets whether resetting the property is possible.
+ ///
+ public bool CanReset {
+ get { return IsSet; }
+ }
+
+ ///
+ /// Resets the property.
+ ///
+ public void Reset()
+ {
+ SetValueCore(Unset);
+ }
+
+ ///
+ /// Replaces the value of this node with a new binding.
+ ///
+ public void CreateBinding()
+ {
+ Value = new Binding();
+ IsExpanded = true;
+ }
+
+ void SetValueCore(object value)
+ {
+ raiseEvents = false;
+ if (value == Unset) {
+ foreach (var p in Properties) {
+ p.Reset();
+ }
+ } else {
+ foreach (var p in Properties) {
+ p.SetValue(value);
+ }
+ }
+ raiseEvents = true;
+ OnValueChanged();
+ }
+
+ void OnValueChanged()
+ {
+ RaisePropertyChanged("IsSet");
+ RaisePropertyChanged("Value");
+ RaisePropertyChanged("ValueString");
+ RaisePropertyChanged("IsAmbiguous");
+ RaisePropertyChanged("FontWeight");
+ RaisePropertyChanged("IsEnabled");
+ RaisePropertyChanged("NameForeground");
+
+ UpdateChildren();
+ }
+
+ void OnValueOnInstanceChanged()
+ {
+ RaisePropertyChanged("Value");
+ RaisePropertyChanged("ValueString");
+ }
+
+ ///
+ /// Creates a new PropertyNode instance.
+ ///
+ public PropertyNode()
+ {
+ Children = new ObservableCollection();
+ MoreChildren = new ObservableCollection();
+ }
+
+ PropertyNode(DesignItemProperty[] properties, PropertyNode parent) : this()
+ {
+ this.Parent = parent;
+ this.Level = parent == null ? 0 : parent.Level + 1;
+ Load(properties);
+ }
+
+ ///
+ /// Initializes this property node with the specified properties.
+ ///
+ public void Load(DesignItemProperty[] properties)
+ {
+ if (this.Properties != null) {
+ // detach events from old properties
+ foreach (var property in this.Properties) {
+ property.ValueChanged -= new EventHandler(property_ValueChanged);
+ property.ValueOnInstanceChanged -= new EventHandler(property_ValueOnInstanceChanged);
+ }
+ }
+
+ this.Properties = new ReadOnlyCollection(properties);
+
+ if (Editor == null)
+ Editor = EditorManager.CreateEditor(FirstProperty);
+
+ foreach (var property in properties) {
+ property.ValueChanged += new EventHandler(property_ValueChanged);
+ property.ValueOnInstanceChanged += new EventHandler(property_ValueOnInstanceChanged);
+ }
+
+ hasStringConverter =
+ FirstProperty.TypeConverter.CanConvertFrom(typeof(string)) &&
+ FirstProperty.TypeConverter.CanConvertTo(typeof(string));
+
+ OnValueChanged();
+ }
+
+ void property_ValueOnInstanceChanged(object sender, EventArgs e)
+ {
+ if (raiseEvents) OnValueOnInstanceChanged();
+ }
+
+ void property_ValueChanged(object sender, EventArgs e)
+ {
+ if (raiseEvents) OnValueChanged();
+ }
+
+ void UpdateChildren()
+ {
+ Children.Clear();
+ MoreChildren.Clear();
+
+ if (Parent == null || Parent.IsExpanded) {
+ if (ValueItem != null) {
+ var list = TypeHelper.GetAvailableProperties(ValueItem.Component)
+ .OrderBy(d => d.Name)
+ .Select(d => new PropertyNode(new[] { ValueItem.Properties.GetProperty(d) }, this));
+
+ foreach (var node in list) {
+ if (Metadata.IsBrowsable(node.FirstProperty)) {
+ node.IsVisible = true;
+ if (Metadata.IsPopularProperty(node.FirstProperty)) {
+ Children.Add(node);
+ } else {
+ MoreChildren.Add(node);
+ }
+ }
+ }
+ }
+ }
+
+ RaisePropertyChanged("HasChildren");
+ }
+
+ #region INotifyPropertyChanged Members
+
+ ///
+ /// Occurs when a property has changed. Used to support WPF data binding.
+ ///
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ void RaisePropertyChanged(string name)
+ {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(name));
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/TypeHelper.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/TypeHelper.cs
index 6434f1558d..f87920ac3e 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/TypeHelper.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/TypeHelper.cs
@@ -66,16 +66,32 @@ namespace ICSharpCode.WpfDesign.PropertyGrid
}
}
+ private static string[] hiddenPropertiesOnWindow = new[] {"ClipToBounds"};
+
///
/// Gets available properties for an object, includes attached properties also.
- ///
+ ///
public static IEnumerable GetAvailableProperties(object element)
{
- foreach(PropertyDescriptor p in TypeDescriptor.GetProperties(element)){
- if (!p.IsBrowsable) continue;
- if (p.IsReadOnly) continue;
- if (p.Attributes.OfType().Count()!=0) continue;
- yield return p;
+ if (element.GetType().FullName == "ICSharpCode.WpfDesign.Designer.Controls.WindowClone")
+ {
+ foreach (PropertyDescriptor p in TypeDescriptor.GetProperties(element))
+ {
+ if (!p.IsBrowsable) continue;
+ if (p.IsReadOnly) continue;
+ if (hiddenPropertiesOnWindow.Contains(p.Name)) continue;
+ if (p.Attributes.OfType().Count() != 0) continue;
+ yield return p;
+ }
+ }
+ else
+ {
+ foreach(PropertyDescriptor p in TypeDescriptor.GetProperties(element)){
+ if (!p.IsBrowsable) continue;
+ if (p.IsReadOnly) continue;
+ if (p.Attributes.OfType().Count()!=0) continue;
+ yield return p;
+ }
}
}
@@ -98,11 +114,11 @@ namespace ICSharpCode.WpfDesign.PropertyGrid
/* Check if it is attached property.*/
if(pd1.Name.Contains(".") && pd2.Name.Contains(".")){
- if(pd1.Name==pd2.Name){
- typeOk=true;
- break;
- }
- }
+ if(pd1.Name==pd2.Name){
+ typeOk=true;
+ break;
+ }
+ }
}
if (!typeOk) {
propertyOk = false;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/UIHelpers.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/UIHelpers.cs
new file mode 100644
index 0000000000..28a9111826
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/UIHelpers.cs
@@ -0,0 +1,106 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ICSharpCode.WpfDesign
+{
+ public static class UIHelpers
+ {
+ public static DependencyObject GetParentObject(this DependencyObject child)
+ {
+ if (child == null) return null;
+
+ var contentElement = child as ContentElement;
+ if (contentElement != null)
+ {
+ DependencyObject parent = ContentOperations.GetParent(contentElement);
+ if (parent != null) return parent;
+
+ var fce = contentElement as FrameworkContentElement;
+ return fce != null ? fce.Parent : null;
+ }
+
+ var frameworkElement = child as FrameworkElement;
+ if (frameworkElement != null)
+ {
+ DependencyObject parent = frameworkElement.Parent;
+ if (parent != null) return parent;
+ }
+
+ return VisualTreeHelper.GetParent(child);
+ }
+
+ public static T TryFindParent(this DependencyObject child) where T : DependencyObject
+ {
+ DependencyObject parentObject = GetParentObject(child);
+
+ if (parentObject == null) return null;
+
+ T parent = parentObject as T;
+ if (parent != null)
+ {
+ return parent;
+ }
+
+ return TryFindParent(parentObject);
+ }
+
+ public static T TryFindChild(this DependencyObject parent) where T : DependencyObject
+ {
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
+ {
+ DependencyObject child = VisualTreeHelper.GetChild(parent, i);
+
+ if (child is T)
+ {
+ return (T)child;
+ }
+ child = TryFindChild(child);
+ if (child != null)
+ {
+ return (T)child;
+ }
+ }
+ return null;
+ }
+
+ public static T TryFindChild(DependencyObject parent, string childName) where T : DependencyObject
+ {
+ if (parent == null) return null;
+ T foundChild = null;
+ var childrenCount = VisualTreeHelper.GetChildrenCount(parent);
+ for (var i = 0; i < childrenCount; i++)
+ {
+ var child = VisualTreeHelper.GetChild(parent, i);
+
+ var childType = child as T;
+ if (childType == null)
+ {
+ foundChild = TryFindChild(child, childName);
+ if (foundChild != null) break;
+ }
+ else if (!string.IsNullOrEmpty(childName))
+ {
+ var frameworkElement = child as FrameworkElement;
+ if (frameworkElement != null && frameworkElement.Name == childName)
+ {
+ foundChild = (T)child;
+ break;
+ }
+ }
+ else
+ {
+ foundChild = (T)child;
+ break;
+ }
+ }
+ return foundChild;
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
index d868d6287a..9b77acd0c0 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
@@ -117,6 +117,7 @@
+
diff --git a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs
index d890bc36d3..767bf322a0 100644
--- a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs
+++ b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs
@@ -44,6 +44,15 @@ namespace ICSharpCode.PackageManagement.Cmdlets
[Parameter(ParameterSetName = "Updated")]
public SwitchParameter Updates { get; set; }
+ [Parameter(ParameterSetName = "Available")]
+ [Parameter(ParameterSetName = "Updated")]
+ [Alias("Prerelease")]
+ public SwitchParameter IncludePrerelease { get; set; }
+
+ [Parameter(ParameterSetName = "Available")]
+ [Parameter(ParameterSetName = "Updated")]
+ public SwitchParameter AllVersions { get; set; }
+
[Parameter(Position = 0)]
public string Filter { get; set; }
@@ -54,9 +63,6 @@ namespace ICSharpCode.PackageManagement.Cmdlets
[Parameter(ParameterSetName = "Updated")]
public string Source { get; set; }
- [Parameter(ParameterSetName = "Recent")]
- public SwitchParameter Recent { get; set; }
-
[Parameter]
[ValidateRange(0, Int32.MaxValue)]
public int Skip {
@@ -75,11 +81,24 @@ namespace ICSharpCode.PackageManagement.Cmdlets
protected override void ProcessRecord()
{
ValidateParameters();
-
+ IEnumerable packages = GetPackagesForDisplay();
+ WritePackagesToOutputPipeline(packages);
+ }
+
+ IEnumerable GetPackagesForDisplay()
+ {
IQueryable packages = GetPackages();
packages = OrderPackages(packages);
- packages = SelectPackageRange(packages);
- WritePackagesToOutputPipeline(packages);
+ IEnumerable distinctPackages = DistinctPackagesById(packages);
+ return SelectPackageRange(distinctPackages);
+ }
+
+ IEnumerable DistinctPackagesById(IQueryable packages)
+ {
+ if (ListAvailable && !AllVersions) {
+ return packages.DistinctLast(PackageEqualityComparer.Id);
+ }
+ return packages;
}
void ValidateParameters()
@@ -91,7 +110,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets
bool ParametersRequireProject()
{
- if (ListAvailable.IsPresent || Recent.IsPresent) {
+ if (ListAvailable) {
return false;
}
return true;
@@ -104,12 +123,10 @@ namespace ICSharpCode.PackageManagement.Cmdlets
IQueryable GetPackages()
{
- if (ListAvailable.IsPresent) {
+ if (ListAvailable) {
return GetAvailablePackages();
- } else if (Updates.IsPresent) {
+ } else if (Updates) {
return GetUpdatedPackages();
- } else if (Recent.IsPresent) {
- return GetRecentPackages();
}
return GetInstalledPackages();
}
@@ -119,7 +136,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets
return packages.OrderBy(package => package.Id);
}
- IQueryable SelectPackageRange(IQueryable packages)
+ IEnumerable SelectPackageRange(IEnumerable packages)
{
if (skip.HasValue) {
packages = packages.Skip(skip.Value);
@@ -145,24 +162,30 @@ namespace ICSharpCode.PackageManagement.Cmdlets
IQueryable FilterPackages(IQueryable packages)
{
- return packages.Find(Filter);
+ IQueryable filteredPackages = packages.Find(Filter);
+ if (IncludePrerelease || AllVersions) {
+ return filteredPackages;
+ }
+ return filteredPackages.Where(package => package.IsLatestVersion);
}
IQueryable GetUpdatedPackages()
{
- IPackageRepository aggregateRepository = registeredPackageRepositories.CreateAggregateRepository();
- UpdatedPackages updatedPackages = CreateUpdatedPackages(aggregateRepository);
+ IPackageRepository repository = CreatePackageRepositoryForActivePackageSource();
+ UpdatedPackages updatedPackages = CreateUpdatedPackages(repository);
updatedPackages.SearchTerms = Filter;
- return updatedPackages.GetUpdatedPackages().AsQueryable();
+ return updatedPackages
+ .GetUpdatedPackages(IncludePrerelease)
+ .AsQueryable();
}
- UpdatedPackages CreateUpdatedPackages(IPackageRepository aggregateRepository)
+ UpdatedPackages CreateUpdatedPackages(IPackageRepository repository)
{
- IPackageManagementProject project = GetSelectedProject(aggregateRepository);
+ IPackageManagementProject project = GetSelectedProject(repository);
if (project != null) {
- return new UpdatedPackages(project, aggregateRepository);
+ return new UpdatedPackages(project, repository);
}
- return new UpdatedPackages(GetSolutionPackages(), aggregateRepository);
+ return new UpdatedPackages(GetSolutionPackages(), repository);
}
IQueryable GetSolutionPackages()
@@ -183,12 +206,6 @@ namespace ICSharpCode.PackageManagement.Cmdlets
return ProjectName != null;
}
- IQueryable GetRecentPackages()
- {
- IQueryable packages = registeredPackageRepositories.RecentPackageRepository.GetPackages();
- return FilterPackages(packages);
- }
-
IQueryable GetInstalledPackages()
{
IQueryable packages = GetPackagesFromSelectedProjectOrSolution();
@@ -212,7 +229,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets
return null;
}
- void WritePackagesToOutputPipeline(IQueryable packages)
+ void WritePackagesToOutputPipeline(IEnumerable packages)
{
foreach (IPackage package in packages) {
WriteObject(package);
diff --git a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/InstallPackageCmdlet.cs b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/InstallPackageCmdlet.cs
index a94074fcc4..b505ef2eca 100644
--- a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/InstallPackageCmdlet.cs
+++ b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/InstallPackageCmdlet.cs
@@ -63,8 +63,10 @@ namespace ICSharpCode.PackageManagement.Cmdlets
void InstallPackage()
{
IPackageManagementProject project = GetProject();
- InstallPackageAction action = CreateInstallPackageTask(project);
- action.Execute();
+ using (project.SourceRepository.StartInstallOperation(Id)) {
+ InstallPackageAction action = CreateInstallPackageTask(project);
+ action.Execute();
+ }
}
IPackageManagementProject GetProject()
diff --git a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/UpdatePackageCmdlet.cs b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/UpdatePackageCmdlet.cs
index f86a11bc60..ae4167a5a1 100644
--- a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/UpdatePackageCmdlet.cs
+++ b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/UpdatePackageCmdlet.cs
@@ -129,7 +129,14 @@ namespace ICSharpCode.PackageManagement.Cmdlets
{
IPackageManagementProject project = GetProject();
UpdatePackageAction action = CreateUpdatePackageAction(project);
- action.Execute();
+ using (IDisposable operation = StartUpdateOperation(action)) {
+ action.Execute();
+ }
+ }
+
+ IDisposable StartUpdateOperation(UpdatePackageAction action)
+ {
+ return action.Project.SourceRepository.StartUpdateOperation(action.PackageId);
}
IPackageManagementProject GetProject()
@@ -163,7 +170,9 @@ namespace ICSharpCode.PackageManagement.Cmdlets
updateActions.PackageScriptRunner = this;
foreach (UpdatePackageAction action in updateActions.CreateActions()) {
- action.Execute();
+ using (IDisposable operation = StartUpdateOperation(action)) {
+ action.Execute();
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Cmdlets/Test/Src/GetPackageCmdletTests.cs b/src/AddIns/Misc/PackageManagement/Cmdlets/Test/Src/GetPackageCmdletTests.cs
index 48ebdc6863..db8eed2e1d 100644
--- a/src/AddIns/Misc/PackageManagement/Cmdlets/Test/Src/GetPackageCmdletTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Cmdlets/Test/Src/GetPackageCmdletTests.cs
@@ -50,6 +50,16 @@ namespace PackageManagement.Cmdlets.Tests
cmdlet.Updates = new SwitchParameter(true);
}
+ void EnablePrereleaseParameter()
+ {
+ cmdlet.IncludePrerelease = new SwitchParameter(true);
+ }
+
+ void EnableAllVersionsParameter()
+ {
+ cmdlet.AllVersions = new SwitchParameter(true);
+ }
+
FakePackage AddPackageToSpecifiedProjectManagerLocalRepository(string id, string version)
{
FakePackage package = FakePackage.CreatePackageWithVersion(id, version);
@@ -57,14 +67,14 @@ namespace PackageManagement.Cmdlets.Tests
return package;
}
- FakePackage AddPackageToAggregateRepository(string version)
+ FakePackage AddPackageToSelectedRepositoryInConsoleHost(string id)
{
- return AddPackageToAggregateRepository("Test", version);
+ return AddPackageToSelectedRepositoryInConsoleHost(id, "1.0");
}
- FakePackage AddPackageToAggregateRepository(string id, string version)
+ FakePackage AddPackageToSelectedRepositoryInConsoleHost(string id, string version)
{
- return fakeRegisteredPackageRepositories.AddFakePackageWithVersionToAggregrateRepository(id, version);
+ return fakeRegisteredPackageRepositories.FakePackageRepository.AddFakePackageWithVersion(id, version);
}
void SetFilterParameter(string filter)
@@ -77,11 +87,6 @@ namespace PackageManagement.Cmdlets.Tests
cmdlet.Source = source;
}
- void EnableRecentParameter()
- {
- cmdlet.Recent = new SwitchParameter(true);
- }
-
void SetSkipParameter(int skip)
{
cmdlet.Skip = skip;
@@ -92,9 +97,9 @@ namespace PackageManagement.Cmdlets.Tests
cmdlet.First = first;
}
- void AddPackageWithVersionToSolution(string version)
+ void AddPackageToSolution(string id, string version)
{
- fakeSolution.AddPackageToSharedLocalRepository("Test", version);
+ fakeSolution.AddPackageToSharedLocalRepository(id, version);
}
[Test]
@@ -227,10 +232,10 @@ namespace PackageManagement.Cmdlets.Tests
public void ProcessRecord_UpdatedPackagesRequestedAndNoProjectName_ReturnsUpdatedPackagesForSolution()
{
CreateCmdlet();
- AddPackageWithVersionToSolution("1.0.0.0");
- FakePackage updatedPackage = AddPackageToAggregateRepository("1.1.0.0");
-
+ AddPackageToSolution("Test", "1.0.0.0");
+ FakePackage updatedPackage = AddPackageToSelectedRepositoryInConsoleHost("Test", "1.1.0.0");
EnableUpdatesParameter();
+
RunCmdlet();
List
+
@@ -226,8 +227,11 @@
+
+
+
@@ -244,9 +248,11 @@
+
+
diff --git a/src/AddIns/Misc/PackageManagement/Project/Scripts/Package.Format.ps1xml b/src/AddIns/Misc/PackageManagement/Project/Scripts/Package.Format.ps1xml
index 82338ab9d7..211c3947e1 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Scripts/Package.Format.ps1xml
+++ b/src/AddIns/Misc/PackageManagement/Project/Scripts/Package.Format.ps1xml
@@ -7,6 +7,7 @@
NuGet.ZipPackage
NuGet.DataServicePackage
NuGet.UnzippedPackage
+ NuGet.OptimizedZipPackage
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs
index 51b7f690dd..4ecd5cef35 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackage.cs
@@ -53,7 +53,7 @@ namespace ICSharpCode.PackageManagement.Design
public string Id { get; set; }
public SemanticVersion Version { get; set; }
- public string Title { get; set; }
+ public string Title { get; set; }
public Uri IconUrl { get; set; }
public Uri LicenseUrl { get; set; }
public Uri ProjectUrl { get; set; }
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
index f2832c660e..c8df3e0357 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
@@ -40,7 +40,7 @@ namespace ICSharpCode.PackageManagement.Design
}
}
- public readonly SimpleModelCollection> ProjectCollections = new SimpleModelCollection>();
+ public readonly IMutableModelCollection> ProjectCollections = new NullSafeSimpleModelCollection>();
IModelCollection allProjects;
public IModelCollection AllProjects {
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs
index 14b1d30627..345af84b7a 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageRepository.cs
@@ -46,6 +46,7 @@ namespace ICSharpCode.PackageManagement.Design
public FakePackage AddFakePackageWithVersion(string packageId, string version)
{
var package = FakePackage.CreatePackageWithVersion(packageId, version);
+ package.IsLatestVersion = package.IsReleaseVersion();
FakePackages.Add(package);
return package;
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeUpdatePackageAction.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeUpdatePackageAction.cs
index b750b78d2e..224274649f 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeUpdatePackageAction.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeUpdatePackageAction.cs
@@ -10,6 +10,8 @@ namespace ICSharpCode.PackageManagement.Design
{
public bool IsExecuted;
+ public FakePackageManagementProject FakeProject;
+
public FakeUpdatePackageAction()
: this(new FakePackageManagementProject())
{
@@ -18,6 +20,7 @@ namespace ICSharpCode.PackageManagement.Design
public FakeUpdatePackageAction(IPackageManagementProject project)
: base(project, null)
{
+ FakeProject = project as FakePackageManagementProject;
}
protected override void ExecuteCore()
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageFromRepositoryExtensions.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageFromRepositoryExtensions.cs
new file mode 100644
index 0000000000..fa48451b4a
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageFromRepositoryExtensions.cs
@@ -0,0 +1,20 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.PackageManagement
+{
+ public static class IPackageFromRepositoryExtensions
+ {
+ public static IDisposable StartInstallOperation(this IPackageFromRepository package)
+ {
+ return package.Repository.StartInstallOperation(package.Id);
+ }
+
+ public static IDisposable StartUpdateOperation(this IPackageFromRepository package)
+ {
+ return package.Repository.StartUpdateOperation(package.Id);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryExtensions.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryExtensions.cs
new file mode 100644
index 0000000000..bd3577e50c
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryExtensions.cs
@@ -0,0 +1,21 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public static class IPackageRepositoryExtensions
+ {
+ public static IDisposable StartInstallOperation(this IPackageRepository repository, string mainPackageId = null)
+ {
+ return repository.StartOperation(RepositoryOperationNames.Install, mainPackageId);
+ }
+
+ public static IDisposable StartUpdateOperation(this IPackageRepository repository, string mainPackageId = null)
+ {
+ return repository.StartOperation(RepositoryOperationNames.Update, mainPackageId);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs
new file mode 100644
index 0000000000..e882a6f151
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs
@@ -0,0 +1,12 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.PackageManagement
+{
+ public interface IPackageRepositoryFactoryEvents
+ {
+ event EventHandler RepositoryCreated;
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
index 106bfc0b4e..5e9051d65e 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
@@ -24,11 +24,13 @@ namespace ICSharpCode.PackageManagement
static readonly IPackageRepositoryCache projectTemplatePackageRepositoryCache;
static readonly RegisteredProjectTemplatePackageSources projectTemplatePackageSources;
static readonly PackageRepositoryCache packageRepositoryCache;
+ static readonly UserAgentGeneratorForRepositoryRequests userAgentGenerator;
static PackageManagementServices()
{
options = new PackageManagementOptions();
packageRepositoryCache = new PackageRepositoryCache(options.PackageSources, options.RecentPackages);
+ userAgentGenerator = new UserAgentGeneratorForRepositoryRequests(packageRepositoryCache);
registeredPackageRepositories = new RegisteredPackageRepositories(packageRepositoryCache, options);
projectTemplatePackageSources = new RegisteredProjectTemplatePackageSources();
projectTemplatePackageRepositoryCache = new ProjectTemplatePackageRepositoryCache(packageRepositoryCache, projectTemplatePackageSources);
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs
index d3332ae8de..f3581478f9 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs
@@ -49,7 +49,7 @@ namespace ICSharpCode.PackageManagement
public R SafeThreadFunction(Func method)
{
- return WorkbenchSingleton.SafeThreadFunction(method);
+ return SD.MainThread.InvokeIfRequired(method);
}
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
index aa05822a7e..c9d75ebc40 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
@@ -8,7 +8,7 @@ using NuGet;
namespace ICSharpCode.PackageManagement
{
- public class PackageRepositoryCache : IPackageRepositoryCache
+ public class PackageRepositoryCache : IPackageRepositoryCache, IPackageRepositoryFactoryEvents
{
ISharpDevelopPackageRepositoryFactory factory;
RegisteredPackageSources registeredPackageSources;
@@ -37,6 +37,8 @@ namespace ICSharpCode.PackageManagement
{
}
+ public event EventHandler RepositoryCreated;
+
public IPackageRepository CreateRepository(string packageSource)
{
IPackageRepository repository = GetExistingRepository(packageSource);
@@ -59,9 +61,19 @@ namespace ICSharpCode.PackageManagement
{
IPackageRepository repository = factory.CreateRepository(packageSource);
repositories.TryAdd(packageSource, repository);
+
+ OnPackageRepositoryCreated(repository);
+
return repository;
}
+ void OnPackageRepositoryCreated(IPackageRepository repository)
+ {
+ if (RepositoryCreated != null) {
+ RepositoryCreated(this, new PackageRepositoryFactoryEventArgs(repository));
+ }
+ }
+
public ISharedPackageRepository CreateSharedRepository(IPackagePathResolver pathResolver, IFileSystem fileSystem, IFileSystem configSettingsFileSystem)
{
return factory.CreateSharedRepository(pathResolver, fileSystem, configSettingsFileSystem);
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs
new file mode 100644
index 0000000000..851c4b8d45
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class PackageRepositoryFactoryEventArgs : EventArgs
+ {
+ public PackageRepositoryFactoryEventArgs(IPackageRepository repository)
+ {
+ this.Repository = repository;
+ }
+
+ public IPackageRepository Repository { get; private set; }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageViewModel.cs
index 7c4816fd65..25bb93339f 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageViewModel.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageViewModel.cs
@@ -181,10 +181,19 @@ namespace ICSharpCode.PackageManagement
{
ClearReportedMessages();
logger.LogAddingPackage();
- TryInstallingPackage();
+
+ using (IDisposable operation = StartInstallOperation(package)) {
+ TryInstallingPackage();
+ }
+
logger.LogAfterPackageOperationCompletes();
}
+ protected virtual IDisposable StartInstallOperation(IPackageFromRepository package)
+ {
+ return package.StartInstallOperation();
+ }
+
void ClearReportedMessages()
{
packageManagementEvents.OnPackageOperationsStarting();
@@ -344,7 +353,11 @@ namespace ICSharpCode.PackageManagement
{
ClearReportedMessages();
logger.LogManagingPackage();
- TryInstallingPackagesForSelectedProjects(projects);
+
+ using (IDisposable operation = StartInstallOperation(package)) {
+ TryInstallingPackagesForSelectedProjects(projects);
+ }
+
logger.LogAfterPackageOperationCompletes();
OnPropertyChanged(model => model.IsAdded);
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs
index e8d67c070b..a3c40c5233 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs
@@ -3,7 +3,7 @@
using System;
using System.Windows;
-using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop;
namespace ICSharpCode.PackageManagement
{
@@ -14,7 +14,7 @@ namespace ICSharpCode.PackageManagement
public Window Owner {
get {
if (owner == null) {
- owner = WorkbenchSingleton.MainWindow;
+ owner = SD.Workbench.MainWindow;
}
return owner;
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs
new file mode 100644
index 0000000000..885b9393fb
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs
@@ -0,0 +1,37 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class SharpDevelopHttpUserAgent
+ {
+ public SharpDevelopHttpUserAgent()
+ {
+ CreateUserAgent();
+ }
+
+ public string Client { get; private set; }
+ public string Host { get; private set; }
+ public string UserAgent { get; private set; }
+
+ void CreateUserAgent()
+ {
+ Client = "SharpDevelop";
+ Host = GetHost();
+ UserAgent = HttpUtility.CreateUserAgentString(Client, Host);
+ }
+
+ string GetHost()
+ {
+ return String.Format("SharpDevelop/{0}", RevisionClass.FullVersion);
+ }
+
+ public override string ToString()
+ {
+ return UserAgent;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackageViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackageViewModel.cs
index f90ea9c6a7..62ef4572e3 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackageViewModel.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackageViewModel.cs
@@ -24,5 +24,10 @@ namespace ICSharpCode.PackageManagement
{
return project.CreateUpdatePackageAction();
}
+
+ protected override IDisposable StartInstallOperation(IPackageFromRepository package)
+ {
+ return package.StartUpdateOperation();
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs
index e805833608..3633be0270 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs
@@ -84,9 +84,17 @@ namespace ICSharpCode.PackageManagement
protected override void TryUpdatingAllPackages()
{
- var factory = new UpdatePackagesActionFactory(logger, packageManagementEvents);
- IUpdatePackagesAction action = factory.CreateAction(selectedProjects, GetPackagesFromViewModels());
- ActionRunner.Run(action);
+ List packages = GetPackagesFromViewModels().ToList();
+ using (IDisposable operation = StartUpdateOperation(packages.First())) {
+ var factory = new UpdatePackagesActionFactory(logger, packageManagementEvents);
+ IUpdatePackagesAction action = factory.CreateAction(selectedProjects, packages);
+ ActionRunner.Run(action);
+ }
+ }
+
+ IDisposable StartUpdateOperation(IPackageFromRepository package)
+ {
+ return package.Repository.StartUpdateOperation();
}
IEnumerable GetPackagesFromViewModels()
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs
new file mode 100644
index 0000000000..72ce47e58c
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs
@@ -0,0 +1,35 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class UserAgentGeneratorForRepositoryRequests
+ {
+ SharpDevelopHttpUserAgent userAgent = new SharpDevelopHttpUserAgent();
+
+ public UserAgentGeneratorForRepositoryRequests(IPackageRepositoryFactoryEvents repositoryFactoryEvents)
+ {
+ repositoryFactoryEvents.RepositoryCreated += RepositoryCreated;
+ }
+
+ void RepositoryCreated(object sender, PackageRepositoryFactoryEventArgs e)
+ {
+ RegisterHttpClient(e.Repository as IHttpClientEvents);
+ }
+
+ void RegisterHttpClient(IHttpClientEvents clientEvents)
+ {
+ if (clientEvents != null) {
+ clientEvents.SendingRequest += SendingRequest;
+ }
+ }
+
+ void SendingRequest(object sender, WebRequestEventArgs e)
+ {
+ HttpUtility.SetUserAgent(e.Request, userAgent.ToString());
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
index c4f5f1b42f..fe8331f44e 100644
--- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
+++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
@@ -118,6 +118,7 @@
+
@@ -211,6 +212,7 @@
+
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeOperationAwarePackageRepository.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeOperationAwarePackageRepository.cs
new file mode 100644
index 0000000000..8b1bd2a5ef
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeOperationAwarePackageRepository.cs
@@ -0,0 +1,38 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.PackageManagement.Design;
+using NuGet;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace PackageManagement.Tests.Helpers
+{
+ public class FakeOperationAwarePackageRepository : FakePackageRepository, IOperationAwareRepository
+ {
+ public string OperationStarted;
+ public string MainPackageIdForOperationStarted;
+
+ IDisposable Operation = MockRepository.GenerateStub();
+
+ public IDisposable StartOperation(string operationName, string mainPackageId)
+ {
+ OperationStarted = operationName;
+ MainPackageIdForOperationStarted = mainPackageId;
+ return Operation;
+ }
+
+ public void AssertOperationWasStartedAndDisposed(string expectedOperationName, string expectedMainPackageId)
+ {
+ Assert.AreEqual(expectedOperationName, OperationStarted);
+ Assert.AreEqual(expectedMainPackageId, MainPackageIdForOperationStarted);
+ AssertOperationIsDisposed();
+ }
+
+ void AssertOperationIsDisposed()
+ {
+ Operation.AssertWasCalled(o => o.Dispose());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs
index 5fefaf46f7..8ed0ba0fe5 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs
@@ -18,7 +18,7 @@ namespace PackageManagement.Tests.Helpers
SD.InitializeForUnitTests();
ISolution solution = MockRepository.GenerateStrictMock();
solution.Stub(s => s.MSBuildProjectCollection).Return(new Microsoft.Build.Evaluation.ProjectCollection());
- solution.Stub(s => s.Projects).Return(new SimpleModelCollection());
+ solution.Stub(s => s.Projects).Return(new NullSafeSimpleModelCollection());
solution.Stub(s => s.ActiveConfiguration).Return(new ConfigurationAndPlatform("Debug", "Any CPU"));
//solution.Stub(s => s.FileName).Return(FileName.Create(@"d:\projects\Test\TestSolution.sln"));
return solution;
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
index 5bdbabacab..1c4ee897fb 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
@@ -355,5 +355,30 @@ namespace PackageManagement.Tests
Assert.IsNull(fakePackageRepositoryFactory.AggregateRepositoryPassedToCreateRecentPackageRepository);
}
+
+ [Test]
+ public void CreateRepository_NewRepositoryCreated_RepositoryCreatedEventFired()
+ {
+ CreateCache();
+ PackageRepositoryFactoryEventArgs eventArgs = null;
+ cache.RepositoryCreated += (sender, e) => eventArgs = e;
+
+ IPackageRepository repository = cache.CreateRepository(nuGetPackageSource.Source);
+
+ Assert.AreEqual(fakePackageRepositoryFactory.FakePackageRepository, eventArgs.Repository);
+ }
+
+ [Test]
+ public void CreateRepository_RepositoryCreatedTwice_RepositoryCreatedEventIsNotFiredOnSecondCallToCreateRepository()
+ {
+ CreateCache();
+ cache.CreateRepository(nuGetPackageSource.Source);
+ PackageRepositoryFactoryEventArgs eventArgs = null;
+ cache.RepositoryCreated += (sender, e) => eventArgs = e;
+
+ cache.CreateRepository(nuGetPackageSource.Source);
+
+ Assert.IsNull(eventArgs);
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageViewModelTests.cs
index 6bd1810502..591c6aa873 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageViewModelTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageViewModelTests.cs
@@ -912,7 +912,7 @@ namespace PackageManagement.Tests
string expectedMessage = String.Empty;
string actualMessage = fakeLogger.LastFormattedMessageLogged;
-
+
Assert.AreEqual(expectedMessage, actualMessage);
}
@@ -1449,5 +1449,62 @@ namespace PackageManagement.Tests
Assert.IsTrue(result);
}
+
+ [Test]
+ public void AddPackage_PackageRepositoryIsOperationAwareAndPackageAddedSuccessfully_InstallOperationStartedForPackage()
+ {
+ CreateViewModel();
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ fakePackage.FakePackageRepository = operationAwareRepository;
+ fakePackage.Id = "MyPackage";
+
+ viewModel.AddPackage();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Install, "MyPackage");
+ }
+
+ [Test]
+ public void AddPackage_PackageRepositoryIsOperationAwareAndExceptionThrownWhenCreatingInstallPackageAction_InstallOperationStartedForPackageBeforeInstallPackageActionCreatedAndPackageOperationsRequested()
+ {
+ CreateViewModelWithExceptionThrowingProject();
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ fakePackage.FakePackageRepository = operationAwareRepository;
+ fakePackage.Id = "MyPackage";
+ Exception ex = new Exception("Test");
+ exceptionThrowingProject.ExceptionToThrowWhenCreateInstallPackageActionCalled = ex;
+
+ viewModel.AddPackage();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Install, "MyPackage");
+ }
+
+ [Test]
+ public void ManagePackage_TwoProjectsAndFirstSelectedAndUserAcceptsSelectedProjectsAndSourceRepositoryIsOperationAware_InstallOperationStartedForPackage()
+ {
+ CreateViewModelWithTwoProjectsSelected("Project A", "Project B");
+ UserAcceptsProjectSelection();
+ fakePackageManagementEvents.ProjectsToSelect.Add("Project A");
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ fakePackage.FakePackageRepository = operationAwareRepository;
+ fakePackage.Id = "MyPackage";
+
+ viewModel.ManagePackage();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Install, "MyPackage");
+ }
+
+ [Test]
+ public void ManagePackage_TwoProjectsNeitherSelectedAndSourceRepositoryIsOperationAware_InstallOperationStarted()
+ {
+ CreateViewModelWithTwoProjectsSelected("Project A", "Project B");
+ UserAcceptsProjectSelection();
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ fakePackage.FakePackageRepository = operationAwareRepository;
+ fakePackage.Id = "MyPackage";
+
+ viewModel.ManagePackage();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Install, "MyPackage");
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackageViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackageViewModelTests.cs
index 5c08ef3f77..f5b540e2d0 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackageViewModelTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackageViewModelTests.cs
@@ -128,5 +128,19 @@ namespace PackageManagement.Tests
Assert.AreEqual(expectedPackage, actualPackage);
}
+
+ [Test]
+ public void AddPackage_PackageRepositoryIsOperationAwareAndPackageAddedSuccessfully_UpdateOperationStartedForPackage()
+ {
+ CreateViewModel();
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ FakePackage fakePackage = viewModel.FakePackage;
+ fakePackage.FakePackageRepository = operationAwareRepository;
+ fakePackage.Id = "MyPackage";
+
+ viewModel.AddPackage();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Update, "MyPackage");
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs
index 28e783189f..c2796591b5 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs
@@ -753,5 +753,22 @@ namespace PackageManagement.Tests
IPackageViewModelParent parent = childViewModel.GetParent();
Assert.AreEqual(viewModel, parent);
}
+
+ [Test]
+ public void UpdateAllPackagesCommand_SourceRepositoryIsOperationAware_UpdateOperationStartedAndDisposed()
+ {
+ CreateViewModel();
+ var operationAwareRepository = new FakeOperationAwarePackageRepository();
+ registeredPackageRepositories.FakeActiveRepository = operationAwareRepository;
+ AddPackageToLocalRepository("Test", "1.0.0.0");
+ AddPackageToActiveRepository("Test", "1.0.0.0");
+ FakePackage newerPackage = AddPackageToActiveRepository("Test", "1.1.0.0");
+ viewModel.ReadPackages();
+ CompleteReadPackagesTask();
+
+ RunUpdateAllPackagesCommand();
+
+ operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Update, null);
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs
new file mode 100644
index 0000000000..1feb8c196a
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs
@@ -0,0 +1,90 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Net;
+using ICSharpCode.PackageManagement;
+using NuGet;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace PackageManagement.Tests
+{
+ [TestFixture]
+ public class UserAgentGeneratorForRepositoryRequestsTests
+ {
+ UserAgentGeneratorForRepositoryRequests generator;
+ IPackageRepositoryFactoryEvents repositoryFactoryEvents;
+
+ void CreateGenerator()
+ {
+ repositoryFactoryEvents = MockRepository.GenerateStub();
+ generator = new UserAgentGeneratorForRepositoryRequests(repositoryFactoryEvents);
+ }
+
+ IPackageRepository CreatePackageRepository()
+ {
+ return MockRepository.GenerateStub();
+ }
+
+ IHttpClientEvents CreatePackageRepositoryThatImplementsIHttpClientEvents()
+ {
+ return MockRepository.GenerateMock();
+ }
+
+ void FireRepositoryCreatedEvent(IHttpClientEvents clientEvents)
+ {
+ FireRepositoryCreatedEvent(clientEvents as IPackageRepository);
+ }
+
+ void FireRepositoryCreatedEvent(IPackageRepository repository)
+ {
+ var eventArgs = new PackageRepositoryFactoryEventArgs(repository);
+ repositoryFactoryEvents.Raise(
+ events => events.RepositoryCreated += null,
+ repositoryFactoryEvents,
+ eventArgs);
+ }
+
+ WebRequest FireSendingRequestEvent(IHttpClientEvents clientEvents)
+ {
+ WebRequest request = CreateWebRequest();
+ request.Headers = new WebHeaderCollection();
+
+ var eventArgs = new WebRequestEventArgs(request);
+ clientEvents.Raise(
+ events => events.SendingRequest += null,
+ clientEvents,
+ eventArgs);
+
+ return request;
+ }
+
+ WebRequest CreateWebRequest()
+ {
+ return MockRepository.GenerateStub();
+ }
+
+ [Test]
+ public void SendingRequest_UserAgentGeneration_UserAgentSetOnRequest()
+ {
+ CreateGenerator();
+ IHttpClientEvents clientEvents = CreatePackageRepositoryThatImplementsIHttpClientEvents();
+ FireRepositoryCreatedEvent(clientEvents);
+
+ WebRequest request = FireSendingRequestEvent(clientEvents);
+
+ string userAgent = request.Headers[HttpRequestHeader.UserAgent];
+ Assert.IsTrue(userAgent.StartsWith("SharpDevelop"), userAgent);
+ }
+
+ [Test]
+ public void RepositoryCreated_RepositoryDoesNotImplementIHttpClientEvents_NullReferenceExceptionNotThrown()
+ {
+ CreateGenerator();
+ IPackageRepository repository = CreatePackageRepository();
+
+ FireRepositoryCreatedEvent(repository);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs
index aa977a3561..c929485a48 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs
@@ -67,7 +67,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run()
{
- IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
+ IWorkbenchWindow window = SD.Workbench.ActiveWorkbenchWindow;
if (window == null) {
return;
}
@@ -89,7 +89,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run()
{
- PadDescriptor padContent = WorkbenchSingleton.Workbench.GetPad(typeof(ICSharpCode.SharpDevelop.Gui.PropertyPad));
+ PadDescriptor padContent = SD.Workbench.GetPad(typeof(ICSharpCode.SharpDevelop.Gui.PropertyPad));
if (padContent != null) {
padContent.BringPadToFront();
}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs
index 51e51f8016..da1f52f733 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs
@@ -4,6 +4,7 @@
using System;
using ICSharpCode.Core;
using ICSharpCode.Reports.Core;
+using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Reports.Addin.Commands
@@ -66,7 +67,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run()
{
base.Run();
- WorkbenchSingleton.StatusBar.SetMessage("Connect...");
+ SD.StatusBar.SetMessage("Connect...");
base.ReportViewer.RunReport(base.Model,(ReportParameters)null);
}
}
@@ -84,7 +85,7 @@ namespace ICSharpCode.Reports.Addin.Commands
DataSetFromXsdCommand cmd = new DataSetFromXsdCommand();
cmd.Run();
System.Data.DataSet ds = cmd.DataSet;
- WorkbenchSingleton.StatusBar.SetMessage("Connect...");
+ SD.StatusBar.SetMessage("Connect...");
base.ReportViewer.RunReport(base.Model,ds.Tables[0],null);
}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs
index 3ebf7f5298..ae544d24e9 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs
@@ -8,6 +8,7 @@ using System.Windows.Forms;
using ICSharpCode.Core.WinForms;
using ICSharpCode.Reports.Core;
+using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench;
@@ -29,8 +30,8 @@ namespace ICSharpCode.Reports.Addin
public ReportExplorerPad():base()
{
- WorkbenchSingleton.Workbench.ActiveViewContentChanged += ActiveViewContentChanged;
- WorkbenchSingleton.Workbench.ViewClosed += ActiveViewClosed;
+ SD.Workbench.ActiveViewContentChanged += ActiveViewContentChanged;
+ SD.Workbench.ViewClosed += ActiveViewClosed;
this.explorerTree = new ExplorerTree();
this.explorerTree.MouseDown += new MouseEventHandler(ReportExplorer_MouseDown);
this.explorerTree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ReportExplorerPad_PropertyChanged);
@@ -63,7 +64,7 @@ namespace ICSharpCode.Reports.Addin
void ActiveViewContentChanged(object source, EventArgs e)
{
- ReportDesignerView vv = WorkbenchSingleton.Workbench.ActiveViewContent as ReportDesignerView;
+ ReportDesignerView vv = SD.Workbench.ActiveViewContent as ReportDesignerView;
if (vv != null) {
Console.WriteLine("Explorerpad:ActiveViewContentChanged {0}",vv.TitleName);
}
@@ -184,7 +185,7 @@ namespace ICSharpCode.Reports.Addin
///
public override void Dispose()
{
- WorkbenchSingleton.Workbench.ActiveViewContentChanged -= ActiveViewContentChanged;
+ SD.Workbench.ActiveViewContentChanged -= ActiveViewContentChanged;
this.explorerTree.Dispose();
}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs
index 92d2a39f29..bcb8349889 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs
@@ -224,15 +224,12 @@ namespace ICSharpCode.Reports.Addin.ReportWizard{
private void OnSelectFolder(object sender, System.EventArgs e)
{
- using (FolderBrowserDialog fd = FileService.CreateFolderBrowserDialog("")) {
- if (fd.ShowDialog() == DialogResult.OK) {
- if (!String.IsNullOrEmpty(fd.SelectedPath)) {
- if (!fd.SelectedPath.EndsWith(@"\",StringComparison.OrdinalIgnoreCase)){
- this.txtPath.Text = fd.SelectedPath + @"\";
- } else {
- this.txtPath.Text = fd.SelectedPath;
- }
- }
+ string selectedPath = SD.FileService.BrowseForFolder("");
+ if (!String.IsNullOrEmpty(selectedPath)) {
+ if (!selectedPath.EndsWith(@"\",StringComparison.OrdinalIgnoreCase)){
+ this.txtPath.Text = selectedPath + @"\";
+ } else {
+ this.txtPath.Text = selectedPath;
}
}
}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs
index 6166be82b0..504936bc9d 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs
@@ -196,20 +196,16 @@ namespace ICSharpCode.Reports.Addin.ReportWizard
startLocation = FileUtility.GetAbsolutePath(startLocation, text);
}
- using (FolderBrowserDialog fdiag = FileService.CreateFolderBrowserDialog(description, startLocation)) {
- if (fdiag.ShowDialog() == DialogResult.OK) {
- string path = fdiag.SelectedPath;
- if (panel.baseDirectory != null) {
- path = FileUtility.GetRelativePath(panel.baseDirectory, path);
- }
- if (!path.EndsWith("\\") && !path.EndsWith("/"))
- path += "\\";
- if (textBoxEditMode == TextBoxEditMode.EditEvaluatedProperty) {
- panel.ControlDictionary[target].Text = path;
- } else {
- panel.ControlDictionary[target].Text = MSBuildInternals.Escape(path);
- }
- }
+ string path = SD.FileService.BrowseForFolder(description, startLocation);
+ if (panel.baseDirectory != null) {
+ path = FileUtility.GetRelativePath(panel.baseDirectory, path);
+ }
+ if (!path.EndsWith("\\", StringComparison.Ordinal) && !path.EndsWith("/", StringComparison.Ordinal))
+ path += "\\";
+ if (textBoxEditMode == TextBoxEditMode.EditEvaluatedProperty) {
+ panel.ControlDictionary[target].Text = path;
+ } else {
+ panel.ControlDictionary[target].Text = MSBuildInternals.Escape(path);
}
}
}
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs
index cf29ee426e..a33ea8d83c 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs
@@ -8,11 +8,12 @@ using System.Windows.Forms;
using System.Windows.Forms.Design;
using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Reports.Addin
{
- public class UIService : IUIService
+ public class UIService : System.Windows.Forms.Design.IUIService
{
IDictionary styles = new Hashtable();
@@ -48,7 +49,7 @@ namespace ICSharpCode.Reports.Addin
#region Dialog functions
public IWin32Window GetDialogOwnerWindow()
{
- return WorkbenchSingleton.MainWin32Window;
+ return SD.WinForms.MainWin32Window;
}
public DialogResult ShowDialog(Form form)
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs
index db75192f6b..f5e07acb38 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs
@@ -149,7 +149,7 @@ namespace ICSharpCode.Reports.Addin
public static SharpDevelopSideBar ReportingSideBar {
get {
- Debug.Assert(WorkbenchSingleton.InvokeRequired == false);
+ SD.MainThread.VerifyAccess();
if (reportingSideBar == null) {
reportingSideBar = new SharpDevelopSideBar();
reportingSideBar.Tabs.Add(standardSideTab);
diff --git a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Core/Project/Exporter/ExportColumns/ExportText.cs b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Core/Project/Exporter/ExportColumns/ExportText.cs
index d35d9bc1ce..babef46db4 100644
--- a/src/AddIns/Misc/Reports/ICSharpCode.Reports.Core/Project/Exporter/ExportColumns/ExportText.cs
+++ b/src/AddIns/Misc/Reports/ICSharpCode.Reports.Core/Project/Exporter/ExportColumns/ExportText.cs
@@ -36,23 +36,22 @@ namespace ICSharpCode.Reports.Core.Exporter {
throw new ArgumentNullException("converter");
}
base.DrawItem(pdfWriter,converter);
-
base.Decorate();
PdfContentByte contentByte = base.PdfWriter.DirectContent;
- iTextSharp.text.Font font = CreateFontFromFactory(this.StyleDecorator);
- CalculatePdfFormat pdfFormat = new CalculatePdfFormat(this.StyleDecorator,font);
+ var font = CreateFontFromFactory(this.StyleDecorator);
- ColumnText columnText = new ColumnText(contentByte);
+ var columnText = new ColumnText(contentByte);
if (StyleDecorator.RightToLeft.ToString() == "Yes") {
columnText.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
}
- iTextSharp.text.Rectangle r = base.ConvertToPdfRectangle();
- columnText.SetSimpleColumn(r.Left, r.Top , r.Left + r.Width,r.Top - r.Height,pdfFormat.Leading,pdfFormat.Alignment);
-
+ var pdfRectangle = base.ConvertToPdfRectangle();
+
+ columnText.SetSimpleColumn(pdfRectangle.Left, pdfRectangle.Top , pdfRectangle.Left + pdfRectangle.Width,pdfRectangle.Top - pdfRectangle.Height);
+
string formatedText = this.Text;
if (!String.IsNullOrEmpty(StyleDecorator.FormatString)) {
@@ -63,7 +62,7 @@ namespace ICSharpCode.Reports.Core.Exporter {
Chunk chunk = new Chunk(formatedText,font);
columnText.AddText(chunk);
-
+ columnText.Alignment = CalculatePdfFormat.PdfAlignment(this.StyleDecorator);
columnText.Go();
}
@@ -124,68 +123,48 @@ namespace ICSharpCode.Reports.Core.Exporter {
}
}
+
internal class CalculatePdfFormat {
- TextStyleDecorator textDecorator;
-
- public CalculatePdfFormat (TextStyleDecorator textDecorator,iTextSharp.text.Font font)
- {
- if (textDecorator == null) {
- throw new ArgumentNullException ("textDecorator");
- }
- if (font == null) {
- throw new ArgumentNullException("font");
- }
- this.textDecorator = textDecorator;
- this.Leading = font.Size;
- this.CalculateFormat();
- }
-
-
- private void CalculateFormat()
+ public static int PdfAlignment(TextStyleDecorator textDecorator)
{
-
- this.Alignment = PdfContentByte.ALIGN_LEFT;
+ int retVal = 0;
switch (textDecorator.ContentAlignment) {
//Top
case ContentAlignment.TopLeft:
- this.Alignment = PdfContentByte.ALIGN_LEFT;
+ retVal = PdfContentByte.ALIGN_LEFT;
break;
case ContentAlignment.TopCenter:
- this.Alignment = PdfContentByte.ALIGN_CENTER;
+ retVal = PdfContentByte.ALIGN_CENTER;
break;
case ContentAlignment.TopRight:
- this.Alignment = PdfContentByte.ALIGN_RIGHT;
+ retVal = PdfContentByte.ALIGN_RIGHT;
break;
// Middle
case ContentAlignment.MiddleLeft:
- this.Alignment = PdfContentByte.ALIGN_LEFT;
+ retVal = PdfContentByte.ALIGN_LEFT;
break;
case ContentAlignment.MiddleCenter:
- this.Alignment = PdfContentByte.ALIGN_CENTER;
+ retVal = PdfContentByte.ALIGN_CENTER;
break;
case ContentAlignment.MiddleRight:
- this.Alignment = PdfContentByte.ALIGN_RIGHT;
+ retVal = PdfContentByte.ALIGN_RIGHT;
break;
//Bottom
case ContentAlignment.BottomLeft:
- this.Alignment = PdfContentByte.ALIGN_LEFT;
+ retVal = PdfContentByte.ALIGN_LEFT;
break;
case ContentAlignment.BottomCenter:
- this.Alignment = PdfContentByte.ALIGN_CENTER;
+ retVal = PdfContentByte.ALIGN_CENTER;
break;
case ContentAlignment.BottomRight:
- this.Alignment = PdfContentByte.ALIGN_RIGHT;
+ retVal = PdfContentByte.ALIGN_RIGHT;
break;
}
+ return retVal;
}
-
- public float Leading {get;private set;}
-
- public int Alignment {get;private set;}
-
}
}
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs
index c03923549a..a343dbfaaa 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs
@@ -49,13 +49,12 @@ namespace SearchAndReplace
SD.MainThread.VerifyAccess();
if (resultsTreeViewInstance == null)
resultsTreeViewInstance = new ResultsTreeView();
- rootNode.GroupResultsByFile(ResultsTreeView.GroupResultsByFile);
+ rootNode.GroupResultsBy(ResultsTreeView.GroupingKind);
resultsTreeViewInstance.ItemsSource = new object[] { rootNode };
return resultsTreeViewInstance;
}
static IList toolbarItems;
- static MenuItem flatItem, perFileItem;
public virtual IList GetToolbarItems()
{
@@ -71,17 +70,43 @@ namespace SearchAndReplace
perFileDropDown.Content = new Image { Height = 16, Source = PresentationResourceService.GetBitmapSource("Icons.16x16.FindIcon") };
perFileDropDown.SetValueToExtension(DropDownButton.ToolTipProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.SelectViewMode.ToolTip"));
- flatItem = new MenuItem();
+ MenuItem flatItem = new MenuItem();
+ flatItem.IsCheckable = true;
flatItem.SetValueToExtension(MenuItem.HeaderProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.Flat"));
- flatItem.Click += delegate { SetPerFile(false); };
+ flatItem.Click += delegate {
+ SetResultGrouping();
+ SetCheckedItem(flatItem, perFileDropDown.DropDownMenu);
+ };
- perFileItem = new MenuItem();
+ MenuItem perFileItem = new MenuItem();
+ perFileItem.IsCheckable = true;
perFileItem.SetValueToExtension(MenuItem.HeaderProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.PerFile"));
- perFileItem.Click += delegate { SetPerFile(true); };
+ perFileItem.Click += delegate {
+ SetResultGrouping(SearchResultGroupingKind.PerFile);
+ SetCheckedItem(perFileItem, perFileDropDown.DropDownMenu);
+ };
+
+ MenuItem perProjectItem = new MenuItem();
+ perProjectItem.IsCheckable = true;
+ perProjectItem.SetValueToExtension(MenuItem.HeaderProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.PerProject"));
+ perProjectItem.Click += delegate {
+ SetResultGrouping(SearchResultGroupingKind.PerProject);
+ SetCheckedItem(perProjectItem, perFileDropDown.DropDownMenu);
+ };
+
+ MenuItem perProjectAndFileItem = new MenuItem();
+ perProjectAndFileItem.IsCheckable = true;
+ perProjectAndFileItem.SetValueToExtension(MenuItem.HeaderProperty, new LocalizeExtension("MainWindow.Windows.SearchResultPanel.PerProjectAndFile"));
+ perProjectAndFileItem.Click += delegate {
+ SetResultGrouping(SearchResultGroupingKind.PerProjectAndFile);
+ SetCheckedItem(perProjectAndFileItem, perFileDropDown.DropDownMenu);
+ };
perFileDropDown.DropDownMenu = new ContextMenu();
perFileDropDown.DropDownMenu.Items.Add(flatItem);
perFileDropDown.DropDownMenu.Items.Add(perFileItem);
+ perFileDropDown.DropDownMenu.Items.Add(perProjectItem);
+ perFileDropDown.DropDownMenu.Items.Add(perProjectAndFileItem);
toolbarItems.Add(perFileDropDown);
toolbarItems.Add(new Separator());
@@ -100,6 +125,14 @@ namespace SearchAndReplace
return toolbarItems;
}
+ static void SetCheckedItem(MenuItem newTarget, ContextMenu menu)
+ {
+ foreach (var item in menu.Items.OfType()) {
+ item.IsChecked = false;
+ }
+ newTarget.IsChecked = true;
+ }
+
static void ExpandCollapseAll(bool newIsExpanded)
{
if (resultsTreeViewInstance != null) {
@@ -109,17 +142,25 @@ namespace SearchAndReplace
}
}
- static void SetPerFile(bool perFile)
+ static void SetResultGrouping(SearchResultGroupingKind grouping = SearchResultGroupingKind.Flat)
{
- ResultsTreeView.GroupResultsByFile = perFile;
+ ResultsTreeView.GroupingKind = grouping;
if (resultsTreeViewInstance != null) {
foreach (SearchRootNode node in resultsTreeViewInstance.ItemsSource.OfType()) {
- node.GroupResultsByFile(perFile);
+ node.GroupResultsBy(grouping);
}
}
}
}
+ public enum SearchResultGroupingKind
+ {
+ Flat,
+ PerFile,
+ PerProject,
+ PerProjectAndFile
+ }
+
public class DefaultSearchResultFactory : ISearchResultFactory
{
public ISearchResult CreateSearchResult(string title, IEnumerable matches)
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/ObserverSearchResult.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/ObserverSearchResult.cs
index 3ba7213a69..88cb072d66 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/ObserverSearchResult.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/ObserverSearchResult.cs
@@ -32,7 +32,7 @@ namespace SearchAndReplace
SD.MainThread.VerifyAccess();
if (resultsTreeViewInstance == null)
resultsTreeViewInstance = new ResultsTreeView();
- rootNode.GroupResultsByFile(ResultsTreeView.GroupResultsByFile);
+ rootNode.GroupResultsBy(ResultsTreeView.GroupingKind);
resultsTreeViewInstance.ItemsSource = new object[] { rootNode };
return resultsTreeViewInstance;
}
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/ResultsTreeView.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/ResultsTreeView.cs
index 24162166f4..52d6c9a8d9 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/ResultsTreeView.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/ResultsTreeView.cs
@@ -38,13 +38,9 @@ namespace SearchAndReplace
e.Handled = true;
}
- public static bool GroupResultsByFile {
- get {
- return PropertyService.Get("SearchAndReplace.GroupResultsByFile", false);
- }
- set {
- PropertyService.Set("SearchAndReplace.GroupResultsByFile", value);
- }
+ public static SearchResultGroupingKind GroupingKind {
+ get { return PropertyService.Get("SearchAndReplace.GroupResults", SearchResultGroupingKind.Flat); }
+ set { PropertyService.Set("SearchAndReplace.GroupResults", value); }
}
}
}
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchFileNode.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchFileNode.cs
index 56e59f5f5a..b0a1a851ad 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchFileNode.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchFileNode.cs
@@ -2,13 +2,14 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.Collections.Generic;
using System.IO;
using System.Windows.Controls;
using System.Windows.Documents;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Editor.Search;
+using ICSharpCode.SharpDevelop.Project;
namespace SearchAndReplace
{
@@ -16,7 +17,7 @@ namespace SearchAndReplace
{
public FileName FileName { get; private set; }
- public SearchFileNode(FileName fileName, System.Collections.Generic.List resultNodes)
+ public SearchFileNode(FileName fileName, IList resultNodes)
{
this.FileName = fileName;
this.Children = resultNodes;
@@ -38,4 +39,42 @@ namespace SearchAndReplace
FileService.OpenFile(FileName);
}
}
+
+ public class SearchProjectNode : SearchNode
+ {
+ public IProject Project { get; private set; }
+
+ public SearchProjectNode(IProject project, IList resultNodes)
+ {
+ this.Project = project;
+ this.Children = resultNodes;
+ this.IsExpanded = true;
+ }
+
+ protected override object CreateText()
+ {
+ string fileName = SD.ResourceService.GetString("MainWindow.Windows.SearchResultPanel.NoProject");
+ string directory = null;
+
+ if (Project != null) {
+ fileName = Path.GetFileNameWithoutExtension(Project.FileName);
+ directory = Path.GetDirectoryName(Project.FileName);
+ }
+
+ if (directory != null) {
+ return new TextBlock {
+ Inlines = {
+ new Bold(new Run(fileName)),
+ new Run(StringParser.Parse(" (${res:MainWindow.Windows.SearchResultPanel.In} ") + directory + ")")
+ }
+ };
+ }
+
+ return new TextBlock { Inlines = { new Bold(new Run(fileName)) } };
+ }
+
+ public override void ActivateItem()
+ {
+ }
+ }
}
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
index 9351947c43..60315ee17e 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
@@ -66,17 +66,15 @@ namespace SearchAndReplace
textBlock.Inlines.Add("(" + location.Line + ", " + location.Column + ")\t");
- string displayText = result.DisplayText;
+ RichText displayText = result.DisplayText;
if (displayText != null) {
- textBlock.Inlines.Add(displayText);
- } else if (result.Builder != null) {
- HighlightedInlineBuilder builder = result.Builder;
if (IsSelected) {
- builder = builder.Clone();
- builder.SetForeground(0, builder.Text.Length, null);
- builder.SetBackground(0, builder.Text.Length, null);
+ RichTextModel model = displayText.ToRichTextModel();
+ model.SetForeground(0, displayText.Length, null);
+ model.SetBackground(0, displayText.Length, null);
+ displayText = new RichText(displayText.Text, model);
}
- textBlock.Inlines.AddRange(builder.CreateRuns());
+ textBlock.Inlines.AddRange(displayText.CreateRuns());
}
if (showFileName) {
diff --git a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs
index 875f978a84..d11f2b6fba 100644
--- a/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs
+++ b/src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs
@@ -4,12 +4,9 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Globalization;
using System.Linq;
-using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
-using System.Windows.Media;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Search;
@@ -20,6 +17,8 @@ namespace SearchAndReplace
{
ObservableCollection resultNodes;
ObservableCollection fileNodes;
+ ObservableCollection projectNodes;
+ ObservableCollection projectAndFileNodes;
public string Title { get; private set; }
public bool WasCancelled { get; set; }
@@ -28,7 +27,18 @@ namespace SearchAndReplace
{
this.Title = title;
this.resultNodes = new ObservableCollection(results.Select(r => new SearchResultNode(r)));
- this.fileNodes = new ObservableCollection(resultNodes.GroupBy(r => r.FileName).Select(g => new SearchFileNode(g.Key, g.ToList())));
+ this.fileNodes = new ObservableCollection(
+ resultNodes.GroupBy(r => r.FileName)
+ .Select(g => new SearchFileNode(g.Key, g.ToList()))
+ );
+ this.projectNodes = new ObservableCollection(
+ resultNodes.GroupBy(r => SD.ProjectService.FindProjectContainingFile(r.FileName))
+ .Select(g => new SearchProjectNode(g.Key, g.OfType().ToList()))
+ );
+ this.projectAndFileNodes = new ObservableCollection(
+ resultNodes.GroupBy(r => SD.ProjectService.FindProjectContainingFile(r.FileName))
+ .Select(g => new SearchProjectNode(g.Key, g.GroupBy(r => r.FileName).Select(g2 => new SearchFileNode(g2.Key, g2.ToList())).OfType().ToList()))
+ );
this.IsExpanded = true;
}
@@ -37,15 +47,54 @@ namespace SearchAndReplace
var results = searchedFile.Matches.Select(m => new SearchResultNode(m)).ToList();
resultNodes.AddRange(results);
this.fileNodes.Add(new SearchFileNode(searchedFile.FileName, results));
+ foreach (var g in results.GroupBy(r => SD.ProjectService.FindProjectContainingFile(r.FileName))) {
+ var p = projectNodes.FirstOrDefault(n => n.Project == g.Key);
+ var p2 = projectAndFileNodes.FirstOrDefault(n => n.Project == g.Key);
+ if (p == null) {
+ projectNodes.Add(new SearchProjectNode(g.Key, g.OfType().ToList()));
+ } else {
+ p.Children = new List(p.Children.Concat(g.AsEnumerable()));
+ }
+ if (p2 == null) {
+ projectAndFileNodes.Add(new SearchProjectNode(g.Key, g.GroupBy(r => r.FileName).Select(g2 => new SearchFileNode(g2.Key, g2.ToList())).OfType().ToList()));
+ } else {
+ var f = p2.Children.OfType().FirstOrDefault(n => n.FileName == searchedFile.FileName);
+ if (f == null) {
+ var list = new List(p2.Children);
+ list.Add(new SearchFileNode(searchedFile.FileName, g.ToList()));
+ p2.Children = list;
+ } else {
+ f.Children = new List(f.Children.Concat(g.AsEnumerable()));
+ }
+ }
+ }
InvalidateText();
}
- public void GroupResultsByFile(bool perFile)
+ public void GroupResultsBy(SearchResultGroupingKind kind)
{
- if (perFile)
- this.Children = fileNodes;
- else
- this.Children = resultNodes;
+ bool perFile = false;
+ switch (kind) {
+ case SearchResultGroupingKind.Flat:
+ this.Children = resultNodes;
+ perFile = false;
+ break;
+ case SearchResultGroupingKind.PerFile:
+ this.Children = fileNodes;
+ perFile = true;
+ break;
+ case SearchResultGroupingKind.PerProject:
+ this.Children = projectNodes;
+ perFile = false;
+ break;
+ case SearchResultGroupingKind.PerProjectAndFile:
+ this.Children = projectAndFileNodes;
+ perFile = true;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
foreach (SearchResultNode node in resultNodes) {
node.ShowFileName = !perFile;
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Highlighting/HtmlClipboardTests.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Highlighting/HtmlClipboardTests.cs
index e0c4566bc2..6f3786061b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Highlighting/HtmlClipboardTests.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Highlighting/HtmlClipboardTests.cs
@@ -25,9 +25,9 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
var segment = new TextSegment { StartOffset = 0, Length = document.TextLength };
string html = HtmlClipboard.CreateHtmlFragment(document, highlighter, segment, new HtmlOptions());
- Assert.AreEqual("using System.Text;
" + Environment.NewLine +
- " string " +
- "text = SomeMethod();", html);
+ Assert.AreEqual("using System.Text;
" + Environment.NewLine +
+ " string " +
+ "text = SomeMethod();", html);
}
[Test]
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CompressingTreeListTests.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CompressingTreeListTests.cs
index afb78027b0..f60b9ce822 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CompressingTreeListTests.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Utils/CompressingTreeListTests.cs
@@ -30,12 +30,7 @@ namespace ICSharpCode.AvalonEdit.Utils
list.InsertRange(0, billion, "A");
list.InsertRange(1, billion, "B");
Assert.AreEqual(2 * billion, list.Count);
- try {
- list.InsertRange(2, billion, "C");
- Assert.Fail("Expected OverflowException");
- } catch (OverflowException) {
- // expected
- }
+ Assert.Throws(delegate { list.InsertRange(2, billion, "C"); });
}
[Test]
@@ -103,5 +98,34 @@ namespace ICSharpCode.AvalonEdit.Utils
list.RemoveRange(0, 3);
Assert.AreEqual(new[] { 2, 3, 3 }, list.ToArray());
}
+
+ [Test]
+ public void Transform()
+ {
+ CompressingTreeList list = new CompressingTreeList((a, b) => a == b);
+ list.AddRange(new[] { 0, 1, 1, 0 });
+ int calls = 0;
+ list.Transform(i => { calls++; return i + 1; });
+ Assert.AreEqual(3, calls);
+ Assert.AreEqual(new[] { 1, 2, 2, 1 }, list.ToArray());
+ }
+
+ [Test]
+ public void TransformToZero()
+ {
+ CompressingTreeList list = new CompressingTreeList((a, b) => a == b);
+ list.AddRange(new[] { 0, 1, 1, 0 });
+ list.Transform(i => 0);
+ Assert.AreEqual(new[] { 0, 0, 0, 0 }, list.ToArray());
+ }
+
+ [Test]
+ public void TransformRange()
+ {
+ CompressingTreeList list = new CompressingTreeList((a, b) => a == b);
+ list.AddRange(new[] { 0, 1, 1, 1, 0, 0 });
+ list.TransformRange(2, 3, i => 0);
+ Assert.AreEqual(new[] { 0, 1, 0, 0, 0, 0 }, list.ToArray());
+ }
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/DocumentTextWriter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/DocumentTextWriter.cs
new file mode 100644
index 0000000000..be907a2792
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/DocumentTextWriter.cs
@@ -0,0 +1,69 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Text;
+using ICSharpCode.NRefactory.Editor;
+
+namespace ICSharpCode.AvalonEdit.Document
+{
+ ///
+ /// A TextWriter implementation that directly inserts into a document.
+ ///
+ public class DocumentTextWriter : TextWriter
+ {
+ readonly IDocument document;
+ int insertionOffset;
+
+ ///
+ /// Creates a new DocumentTextWriter that inserts into document, starting at insertionOffset.
+ ///
+ public DocumentTextWriter(IDocument document, int insertionOffset)
+ {
+ this.insertionOffset = insertionOffset;
+ if (document == null)
+ throw new ArgumentNullException("document");
+ this.document = document;
+ var line = document.GetLineByOffset(insertionOffset);
+ if (line.DelimiterLength == 0)
+ line = line.PreviousLine;
+ if (line != null)
+ this.NewLine = document.GetText(line.EndOffset, line.DelimiterLength);
+ }
+
+ ///
+ /// Gets/Sets the current insertion offset.
+ ///
+ public int InsertionOffset {
+ get { return insertionOffset; }
+ set { insertionOffset = value; }
+ }
+
+ ///
+ public override void Write(char value)
+ {
+ document.Insert(insertionOffset, value.ToString());
+ insertionOffset++;
+ }
+
+ ///
+ public override void Write(char[] buffer, int index, int count)
+ {
+ document.Insert(insertionOffset, new string(buffer, index, count));
+ insertionOffset += count;
+ }
+
+ ///
+ public override void Write(string value)
+ {
+ document.Insert(insertionOffset, value);
+ insertionOffset += value.Length;
+ }
+
+ ///
+ public override Encoding Encoding {
+ get { return Encoding.UTF8; }
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/NewLineFinder.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/NewLineFinder.cs
index c26f112995..69abb830a9 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/NewLineFinder.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/NewLineFinder.cs
@@ -117,9 +117,9 @@ namespace ICSharpCode.AvalonEdit.Document
///
/// Gets the newline sequence used in the document at the specified line.
///
- public static string GetNewLineFromDocument(TextDocument document, int lineNumber)
+ public static string GetNewLineFromDocument(IDocument document, int lineNumber)
{
- DocumentLine line = document.GetLineByNumber(lineNumber);
+ IDocumentLine line = document.GetLineByNumber(lineNumber);
if (line.DelimiterLength == 0) {
// at the end of the document, there's no line delimiter, so use the delimiter
// from the previous line
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs
index 42d1e673eb..8612957a5b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs
@@ -108,7 +108,7 @@ namespace ICSharpCode.AvalonEdit.Document
///
/// Gets the new offset where the specified offset moves after this document change.
///
- public int GetNewOffset(int offset, AnchorMovementType movementType)
+ public int GetNewOffset(int offset, AnchorMovementType movementType = AnchorMovementType.Default)
{
IList items = this.Items;
int count = items.Count;
@@ -255,7 +255,7 @@ namespace ICSharpCode.AvalonEdit.Document
///
/// Gets the new offset where the specified offset moves after this document change.
///
- public int GetNewOffset(int oldOffset, AnchorMovementType movementType)
+ public int GetNewOffset(int oldOffset, AnchorMovementType movementType = AnchorMovementType.Default)
{
int insertionLength = this.InsertionLength;
int removalLength = this.RemovalLength;
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocumentWeakEventManager.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocumentWeakEventManager.cs
index ba71084cbc..e4ad83fb08 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocumentWeakEventManager.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocumentWeakEventManager.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.NRefactory.Editor;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Document
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs
index f4184ca215..cf4eaab2e1 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs
@@ -29,8 +29,8 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea;
- Typeface typeface;
- double emSize;
+ protected Typeface typeface;
+ protected double emSize;
///
protected override Size MeasureOverride(Size availableSize)
@@ -114,7 +114,7 @@ namespace ICSharpCode.AvalonEdit.Editing
return ReceiveWeakEvent(managerType, sender, e);
}
- int maxLineNumberLength = 1;
+ protected int maxLineNumberLength = 1;
void OnDocumentLineCountChanged()
{
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
index a799649d15..9e488d7c22 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
@@ -965,14 +965,14 @@ namespace ICSharpCode.AvalonEdit.Editing
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
- TextView.InvalidateCursor();
+ TextView.InvalidateCursorIfMouseWithinTextView();
}
///
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
- TextView.InvalidateCursor();
+ TextView.InvalidateCursorIfMouseWithinTextView();
}
#endregion
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs
index 2d324173fa..734c053969 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs
@@ -5,9 +5,11 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Text;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.AvalonEdit.Highlighting
{
@@ -20,31 +22,21 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// into a TextBlock.
/// In SharpDevelop, we use it to provide syntax highlighting inside the search results pad.
///
+ [Obsolete("Use RichText / RichTextModel instead")]
public sealed class HighlightedInlineBuilder
{
- sealed class HighlightingState
+ static HighlightingBrush MakeBrush(Brush b)
{
- internal Brush Foreground;
- internal Brush Background;
- internal FontFamily Family;
- internal FontWeight? Weight;
- internal FontStyle? Style;
-
- public HighlightingState Clone()
- {
- return new HighlightingState {
- Foreground = this.Foreground,
- Background = this.Background,
- Family = this.Family,
- Weight = this.Weight,
- Style = this.Style
- };
- }
+ SolidColorBrush scb = b as SolidColorBrush;
+ if (scb != null)
+ return new SimpleHighlightingBrush(scb);
+ else
+ return null;
}
readonly string text;
List stateChangeOffsets = new List();
- List stateChanges = new List();
+ List stateChanges = new List();
int GetIndexForOffset(int offset)
{
@@ -70,14 +62,26 @@ namespace ICSharpCode.AvalonEdit.Highlighting
throw new ArgumentNullException("text");
this.text = text;
stateChangeOffsets.Add(0);
- stateChanges.Add(new HighlightingState());
+ stateChanges.Add(new HighlightingColor());
+ }
+
+ ///
+ /// Creates a new HighlightedInlineBuilder instance.
+ ///
+ public HighlightedInlineBuilder(RichText text)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+ this.text = text.Text;
+ stateChangeOffsets.AddRange(text.stateChangeOffsets);
+ stateChanges.AddRange(text.stateChanges);
}
- HighlightedInlineBuilder(string text, int[] offsets, HighlightingState[] states)
+ HighlightedInlineBuilder(string text, List offsets, List states)
{
this.text = text;
- stateChangeOffsets.AddRange(offsets);
- stateChanges.AddRange(states);
+ stateChangeOffsets = offsets;
+ stateChanges = states;
}
///
@@ -103,15 +107,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) {
- HighlightingState state = stateChanges[i];
- if (color.Foreground != null)
- state.Foreground = color.Foreground.GetBrush(null);
- if (color.Background != null)
- state.Background = color.Background.GetBrush(null);
- if (color.FontStyle != null)
- state.Style = color.FontStyle;
- if (color.FontWeight != null)
- state.Weight = color.FontWeight;
+ stateChanges[i].MergeWith(color);
}
}
@@ -122,8 +118,9 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length);
+ var hbrush = MakeBrush(brush);
for (int i = startIndex; i < endIndex; i++) {
- stateChanges[i].Foreground = brush;
+ stateChanges[i].Foreground = hbrush;
}
}
@@ -134,8 +131,9 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length);
+ var hbrush = MakeBrush(brush);
for (int i = startIndex; i < endIndex; i++) {
- stateChanges[i].Background = brush;
+ stateChanges[i].Background = hbrush;
}
}
@@ -147,7 +145,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) {
- stateChanges[i].Weight = weight;
+ stateChanges[i].FontWeight = weight;
}
}
@@ -159,46 +157,24 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) {
- stateChanges[i].Style = style;
+ stateChanges[i].FontStyle = style;
}
}
///
- /// Sets the font family on the specified text segment.
+ /// Creates WPF Run instances that can be used for TextBlock.Inlines.
///
- public void SetFontFamily(int offset, int length, FontFamily family)
+ public Run[] CreateRuns()
{
- int startIndex = GetIndexForOffset(offset);
- int endIndex = GetIndexForOffset(offset + length);
- for (int i = startIndex; i < endIndex; i++) {
- stateChanges[i].Family = family;
- }
+ return ToRichText().CreateRuns();
}
///
- /// Creates WPF Run instances that can be used for TextBlock.Inlines.
+ /// Creates a RichText instance.
///
- public Run[] CreateRuns()
+ public RichText ToRichText()
{
- Run[] runs = new Run[stateChanges.Count];
- for (int i = 0; i < runs.Length; i++) {
- int startOffset = stateChangeOffsets[i];
- int endOffset = i + 1 < stateChangeOffsets.Count ? stateChangeOffsets[i + 1] : text.Length;
- Run r = new Run(text.Substring(startOffset, endOffset - startOffset));
- HighlightingState state = stateChanges[i];
- if (state.Foreground != null)
- r.Foreground = state.Foreground;
- if (state.Background != null)
- r.Background = state.Background;
- if (state.Weight != null)
- r.FontWeight = state.Weight.Value;
- if (state.Family != null)
- r.FontFamily = state.Family;
- if (state.Style != null)
- r.FontStyle = state.Style.Value;
- runs[i] = r;
- }
- return runs;
+ return new RichText(text, stateChangeOffsets.ToArray(), stateChanges.Select(FreezableHelper.GetFrozenClone).ToArray());
}
///
@@ -207,8 +183,8 @@ namespace ICSharpCode.AvalonEdit.Highlighting
public HighlightedInlineBuilder Clone()
{
return new HighlightedInlineBuilder(this.text,
- stateChangeOffsets.ToArray(),
- stateChanges.Select(sc => sc.Clone()).ToArray());
+ stateChangeOffsets.ToList(),
+ stateChanges.Select(sc => sc.Clone()).ToList());
}
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs
index 35768891a7..23bfe74583 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs
@@ -167,7 +167,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
}
#endregion
- #region ToHtml
+ #region WriteTo / ToHtml
sealed class HtmlElement : IComparable
{
internal readonly int Offset;
@@ -203,21 +203,21 @@ namespace ICSharpCode.AvalonEdit.Highlighting
}
///
- /// Produces HTML code for the line, with <span class="colorName"> tags.
+ /// Writes the highlighted line to the RichTextWriter.
///
- public string ToHtml(HtmlOptions options)
+ internal void WriteTo(RichTextWriter writer)
{
int startOffset = this.DocumentLine.Offset;
- return ToHtml(startOffset, startOffset + this.DocumentLine.Length, options);
+ WriteTo(writer, startOffset, startOffset + this.DocumentLine.Length);
}
///
- /// Produces HTML code for a section of the line, with <span class="colorName"> tags.
+ /// Writes a part of the highlighted line to the RichTextWriter.
///
- public string ToHtml(int startOffset, int endOffset, HtmlOptions options)
+ internal void WriteTo(RichTextWriter writer, int startOffset, int endOffset)
{
- if (options == null)
- throw new ArgumentNullException("options");
+ if (writer == null)
+ throw new ArgumentNullException("writer");
int documentLineStartOffset = this.DocumentLine.Offset;
int documentLineEndOffset = documentLineStartOffset + this.DocumentLine.Length;
if (startOffset < documentLineStartOffset || startOffset > documentLineEndOffset)
@@ -237,47 +237,85 @@ namespace ICSharpCode.AvalonEdit.Highlighting
elements.Sort();
IDocument document = this.Document;
- StringWriter w = new StringWriter(CultureInfo.InvariantCulture);
int textOffset = startOffset;
foreach (HtmlElement e in elements) {
int newOffset = Math.Min(e.Offset, endOffset);
if (newOffset > startOffset) {
- HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, newOffset - textOffset), options);
+ document.WriteTextTo(writer, textOffset, newOffset - textOffset);
}
textOffset = Math.Max(textOffset, newOffset);
- if (options.ColorNeedsSpanForStyling(e.Color)) {
- if (e.IsEnd) {
- w.Write("");
- } else {
- w.Write("');
- }
- }
+ if (e.IsEnd)
+ writer.EndSpan();
+ else
+ writer.BeginSpan(e.Color);
}
- HtmlClipboard.EscapeHtml(w, document.GetText(textOffset, endOffset - textOffset), options);
- return w.ToString();
+ document.WriteTextTo(writer, textOffset, endOffset - textOffset);
+ }
+
+ ///
+ /// Produces HTML code for the line, with <span class="colorName"> tags.
+ ///
+ public string ToHtml(HtmlOptions options = null)
+ {
+ StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
+ using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
+ WriteTo(htmlWriter);
+ }
+ return stringWriter.ToString();
+ }
+
+ ///
+ /// Produces HTML code for a section of the line, with <span class="colorName"> tags.
+ ///
+ public string ToHtml(int startOffset, int endOffset, HtmlOptions options = null)
+ {
+ StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
+ using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
+ WriteTo(htmlWriter, startOffset, endOffset);
+ }
+ return stringWriter.ToString();
}
///
public override string ToString()
{
- return "[" + GetType().Name + " " + ToHtml(new HtmlOptions()) + "]";
+ return "[" + GetType().Name + " " + ToHtml() + "]";
}
#endregion
///
/// Creates a that stores the text and highlighting of this line.
///
+ [Obsolete("Use ToRichText() instead")]
public HighlightedInlineBuilder ToInlineBuilder()
{
HighlightedInlineBuilder builder = new HighlightedInlineBuilder(Document.GetText(DocumentLine));
int startOffset = DocumentLine.Offset;
- // copy only the foreground and background colors
foreach (HighlightedSection section in Sections) {
builder.SetHighlighting(section.Offset - startOffset, section.Length, section.Color);
}
return builder;
}
+
+ ///
+ /// Creates a that stores the highlighting of this line.
+ ///
+ public RichTextModel ToRichTextModel()
+ {
+ var builder = new RichTextModel();
+ int startOffset = DocumentLine.Offset;
+ foreach (HighlightedSection section in Sections) {
+ builder.ApplyHighlighting(section.Offset - startOffset, section.Length, section.Color);
+ }
+ return builder;
+ }
+
+ ///
+ /// Creates a that stores the text and highlighting of this line.
+ ///
+ public RichText ToRichText()
+ {
+ return new RichText(Document.GetText(DocumentLine), ToRichTextModel());
+ }
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingBrush.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingBrush.cs
index 2542062387..919de53dce 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingBrush.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingBrush.cs
@@ -75,6 +75,19 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
info.AddValue("color", brush.Color.ToString(CultureInfo.InvariantCulture));
}
+
+ public override bool Equals(object obj)
+ {
+ SimpleHighlightingBrush other = obj as SimpleHighlightingBrush;
+ if (other == null)
+ return false;
+ return this.brush.Color.Equals(other.brush.Color);
+ }
+
+ public override int GetHashCode()
+ {
+ return brush.Color.GetHashCode();
+ }
}
///
@@ -113,5 +126,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{
info.AddValue("propertyName", property.Name);
}
+
+ public override bool Equals(object obj)
+ {
+ SystemColorHighlightingBrush other = obj as SystemColorHighlightingBrush;
+ if (other == null)
+ return false;
+ return object.Equals(this.property, other.property);
+ }
+
+ public override int GetHashCode()
+ {
+ return property.GetHashCode();
+ }
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs
index 66cbb2869c..d518b962b9 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs
@@ -8,6 +8,8 @@ using System.Security.Permissions;
using System.Text;
using System.Windows;
using System.Windows.Media;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.AvalonEdit.Highlighting
{
@@ -15,8 +17,10 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// A highlighting color is a set of font properties and foreground and background color.
///
[Serializable]
- public class HighlightingColor : ISerializable
+ public class HighlightingColor : ISerializable, IFreezable, ICloneable, IEquatable
{
+ internal static readonly HighlightingColor Empty = FreezableHelper.FreezeAndReturn(new HighlightingColor());
+
string name;
FontWeight? fontWeight;
FontStyle? fontStyle;
@@ -175,7 +179,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
///
/// Prevent further changes to this highlighting color.
///
- public void Freeze()
+ public virtual void Freeze()
{
frozen = true;
}
@@ -186,5 +190,75 @@ namespace ICSharpCode.AvalonEdit.Highlighting
public bool IsFrozen {
get { return frozen; }
}
+
+ ///
+ /// Clones this highlighting color.
+ /// If this color is frozen, the clone will be unfrozen.
+ ///
+ public virtual HighlightingColor Clone()
+ {
+ HighlightingColor c = (HighlightingColor)MemberwiseClone();
+ c.frozen = false;
+ return c;
+ }
+
+ object ICloneable.Clone()
+ {
+ return Clone();
+ }
+
+ ///
+ public override sealed bool Equals(object obj)
+ {
+ return Equals(obj as HighlightingColor);
+ }
+
+ ///
+ public virtual bool Equals(HighlightingColor other)
+ {
+ if (other == null)
+ return false;
+ return this.name == other.name && this.fontWeight == other.fontWeight && this.fontStyle == other.fontStyle && object.Equals(this.foreground, other.foreground) && object.Equals(this.background, other.background);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ int hashCode = 0;
+ unchecked {
+ if (name != null)
+ hashCode += 1000000007 * name.GetHashCode();
+ hashCode += 1000000009 * fontWeight.GetHashCode();
+ hashCode += 1000000021 * fontStyle.GetHashCode();
+ if (foreground != null)
+ hashCode += 1000000033 * foreground.GetHashCode();
+ if (background != null)
+ hashCode += 1000000087 * background.GetHashCode();
+ }
+ return hashCode;
+ }
+
+ ///
+ /// Overwrites the properties in this HighlightingColor with those from the given color;
+ /// but maintains the current values where the properties of the given color return null.
+ ///
+ public void MergeWith(HighlightingColor color)
+ {
+ FreezableHelper.ThrowIfFrozen(this);
+ if (color.fontWeight != null)
+ this.fontWeight = color.fontWeight;
+ if (color.fontStyle != null)
+ this.fontStyle = color.fontStyle;
+ if (color.foreground != null)
+ this.foreground = color.foreground;
+ if (color.background != null)
+ this.background = color.background;
+ }
+
+ internal bool IsEmptyForMerge {
+ get {
+ return fontWeight == null && fontStyle == null && foreground == null && background == null;
+ }
+ }
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
index ebc9e24f36..938108bb06 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
@@ -211,7 +211,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// Gets whether the color is empty (has no effect on a VisualLineTextElement).
/// For example, the C# "Punctuation" is an empty color.
///
- bool IsEmptyColor(HighlightingColor color)
+ internal static bool IsEmptyColor(HighlightingColor color)
{
if (color == null)
return true;
@@ -223,14 +223,19 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// Applies a highlighting color to a visual line element.
///
protected virtual void ApplyColorToElement(VisualLineElement element, HighlightingColor color)
+ {
+ ApplyColorToElement(element, color, CurrentContext);
+ }
+
+ internal static void ApplyColorToElement(VisualLineElement element, HighlightingColor color, ITextRunConstructionContext context)
{
if (color.Foreground != null) {
- Brush b = color.Foreground.GetBrush(CurrentContext);
+ Brush b = color.Foreground.GetBrush(context);
if (b != null)
element.TextRunProperties.SetForegroundBrush(b);
}
if (color.Background != null) {
- Brush b = color.Background.GetBrush(CurrentContext);
+ Brush b = color.Background.GetBrush(context);
if (b != null)
element.BackgroundBrush = b;
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs
index f8bc3e924d..4a5717c960 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlClipboard.cs
@@ -94,108 +94,5 @@ namespace ICSharpCode.AvalonEdit.Highlighting
}
return html.ToString();
}
-
- ///
- /// Escapes text and writes the result to the StringBuilder.
- ///
- internal static void EscapeHtml(StringWriter w, string text, HtmlOptions options)
- {
- int spaceCount = -1;
- foreach (char c in text) {
- if (c == ' ') {
- if (spaceCount < 0)
- w.Write(" ");
- else
- spaceCount++;
- } else if (c == '\t') {
- if (spaceCount < 0)
- spaceCount = 0;
- spaceCount += options.TabSize;
- } else {
- if (spaceCount == 1) {
- w.Write(' ');
- } else if (spaceCount >= 1) {
- for (int i = 0; i < spaceCount; i++) {
- w.Write(" ");
- }
- }
- spaceCount = 0;
- switch (c) {
- case '<':
- w.Write("<");
- break;
- case '>':
- w.Write(">");
- break;
- case '&':
- w.Write("&");
- break;
- case '"':
- w.Write(""");
- break;
- default:
- w.Write(c);
- break;
- }
- }
- }
- for (int i = 0; i < spaceCount; i++) {
- w.Write(" ");
- }
- }
- }
-
- ///
- /// Holds options for converting text to HTML.
- ///
- public class HtmlOptions
- {
- ///
- /// Creates a default HtmlOptions instance.
- ///
- public HtmlOptions()
- {
- this.TabSize = 4;
- }
-
- ///
- /// Creates a new HtmlOptions instance that copies applicable options from the .
- ///
- public HtmlOptions(TextEditorOptions options)
- : this()
- {
- if (options == null)
- throw new ArgumentNullException("options");
- this.TabSize = options.IndentationSize;
- }
-
- ///
- /// The amount of spaces a tab gets converted to.
- ///
- public int TabSize { get; set; }
-
- ///
- /// Writes the HTML attribute for the style to the text writer.
- ///
- public virtual void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color)
- {
- if (writer == null)
- throw new ArgumentNullException("writer");
- if (color == null)
- throw new ArgumentNullException("color");
- writer.Write(" style=\"");
- writer.Write(color.ToCss());
- writer.Write("\"");
- }
-
- ///
- /// Gets whether the color needs to be written out to HTML.
- ///
- public virtual bool ColorNeedsSpanForStyling(HighlightingColor color)
- {
- if (color == null)
- throw new ArgumentNullException("color");
- return !string.IsNullOrEmpty(color.ToCss());
- }
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlOptions.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlOptions.cs
new file mode 100644
index 0000000000..a0fc28bc24
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlOptions.cs
@@ -0,0 +1,62 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Net;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// Holds options for converting text to HTML.
+ ///
+ public class HtmlOptions
+ {
+ ///
+ /// Creates a default HtmlOptions instance.
+ ///
+ public HtmlOptions()
+ {
+ this.TabSize = 4;
+ }
+
+ ///
+ /// Creates a new HtmlOptions instance that copies applicable options from the .
+ ///
+ public HtmlOptions(TextEditorOptions options) : this()
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+ this.TabSize = options.IndentationSize;
+ }
+
+ ///
+ /// The amount of spaces a tab gets converted to.
+ ///
+ public int TabSize { get; set; }
+
+ ///
+ /// Writes the HTML attribute for the style to the text writer.
+ ///
+ public virtual void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color)
+ {
+ if (writer == null)
+ throw new ArgumentNullException("writer");
+ if (color == null)
+ throw new ArgumentNullException("color");
+ writer.Write(" style=\"");
+ WebUtility.HtmlEncode(color.ToCss(), writer);
+ writer.Write('"');
+ }
+
+ ///
+ /// Gets whether the color needs to be written out to HTML.
+ ///
+ public virtual bool ColorNeedsSpanForStyling(HighlightingColor color)
+ {
+ if (color == null)
+ throw new ArgumentNullException("color");
+ return !string.IsNullOrEmpty(color.ToCss());
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlRichTextWriter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlRichTextWriter.cs
new file mode 100644
index 0000000000..1fa54f81d5
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HtmlRichTextWriter.cs
@@ -0,0 +1,236 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Windows;
+using System.Windows.Media;
+using ICSharpCode.AvalonEdit.Utils;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// RichTextWriter implementation that produces HTML.
+ ///
+ class HtmlRichTextWriter : RichTextWriter
+ {
+ readonly TextWriter htmlWriter;
+ readonly HtmlOptions options;
+ Stack endTagStack = new Stack();
+ bool spaceNeedsEscaping = true;
+ bool hasSpace;
+ bool needIndentation = true;
+ int indentationLevel;
+
+ ///
+ /// Creates a new HtmlRichTextWriter instance.
+ ///
+ ///
+ /// The text writer where the raw HTML is written to.
+ /// The HtmlRichTextWriter does not take ownership of the htmlWriter;
+ /// disposing the HtmlRichTextWriter will not dispose the underlying htmlWriter!
+ ///
+ /// Options that control the HTML output.
+ public HtmlRichTextWriter(TextWriter htmlWriter, HtmlOptions options = null)
+ {
+ if (htmlWriter == null)
+ throw new ArgumentNullException("htmlWriter");
+ this.htmlWriter = htmlWriter;
+ this.options = options ?? new HtmlOptions();
+ }
+
+ ///
+ public override Encoding Encoding {
+ get { return htmlWriter.Encoding; }
+ }
+
+ ///
+ public override void Flush()
+ {
+ FlushSpace(true); // next char potentially might be whitespace
+ htmlWriter.Flush();
+ }
+
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ FlushSpace(true);
+ }
+ base.Dispose(disposing);
+ }
+
+ void FlushSpace(bool nextIsWhitespace)
+ {
+ if (hasSpace) {
+ if (spaceNeedsEscaping || nextIsWhitespace)
+ htmlWriter.Write(" ");
+ else
+ htmlWriter.Write(' ');
+ hasSpace = false;
+ spaceNeedsEscaping = true;
+ }
+ }
+
+ void WriteIndentation()
+ {
+ if (needIndentation) {
+ for (int i = 0; i < indentationLevel; i++) {
+ WriteChar('\t');
+ }
+ needIndentation = false;
+ }
+ }
+
+ ///
+ public override void Write(char value)
+ {
+ WriteIndentation();
+ WriteChar(value);
+ }
+
+ static readonly char[] specialChars = { ' ', '\t', '\r', '\n' };
+
+ void WriteChar(char c)
+ {
+ bool isWhitespace = char.IsWhiteSpace(c);
+ FlushSpace(isWhitespace);
+ switch (c) {
+ case ' ':
+ if (spaceNeedsEscaping)
+ htmlWriter.Write(" ");
+ else
+ hasSpace = true;
+ break;
+ case '\t':
+ for (int i = 0; i < options.TabSize; i++) {
+ htmlWriter.Write(" ");
+ }
+ break;
+ case '\r':
+ break; // ignore; we'll write the
with the following \n
+ case '\n':
+ htmlWriter.Write("
");
+ needIndentation = true;
+ break;
+ default:
+ WebUtility.HtmlEncode(c.ToString(), htmlWriter);
+ break;
+ }
+ // If we just handled a space by setting hasSpace = true,
+ // we mustn't set spaceNeedsEscaping as doing so would affect our own space,
+ // not just the following spaces.
+ if (c != ' ') {
+ // Following spaces must be escaped if c was a newline/tab;
+ // and they don't need escaping if c was a normal character.
+ spaceNeedsEscaping = isWhitespace;
+ }
+ }
+
+ ///
+ public override void Write(string value)
+ {
+ int pos = 0;
+ do {
+ int endPos = value.IndexOfAny(specialChars, pos);
+ if (endPos < 0) {
+ WriteSimpleString(value.Substring(pos));
+ return; // reached end of string
+ }
+ if (endPos > pos)
+ WriteSimpleString(value.Substring(pos, endPos - pos));
+ WriteChar(value[pos]);
+ pos = endPos + 1;
+ } while (pos < value.Length);
+ }
+
+ void WriteIndentationAndSpace()
+ {
+ WriteIndentation();
+ FlushSpace(false);
+ }
+
+ void WriteSimpleString(string value)
+ {
+ if (value.Length == 0)
+ return;
+ WriteIndentationAndSpace();
+ WebUtility.HtmlEncode(value, htmlWriter);
+ }
+
+ ///
+ public override void Indent()
+ {
+ indentationLevel++;
+ }
+
+ ///
+ public override void Unindent()
+ {
+ if (indentationLevel == 0)
+ throw new NotSupportedException();
+ indentationLevel--;
+ }
+
+ ///
+ protected override void BeginUnhandledSpan()
+ {
+ endTagStack.Push(null);
+ }
+
+ ///
+ public override void EndSpan()
+ {
+ htmlWriter.Write(endTagStack.Pop());
+ }
+
+ ///
+ public override void BeginSpan(Color foregroundColor)
+ {
+ BeginSpan(new HighlightingColor { Foreground = new SimpleHighlightingBrush(foregroundColor) });
+ }
+
+ ///
+ public override void BeginSpan(FontFamily fontFamily)
+ {
+ BeginUnhandledSpan(); // TODO
+ }
+
+ ///
+ public override void BeginSpan(FontStyle fontStyle)
+ {
+ BeginSpan(new HighlightingColor { FontStyle = fontStyle });
+ }
+
+ ///
+ public override void BeginSpan(FontWeight fontWeight)
+ {
+ BeginSpan(new HighlightingColor { FontWeight = fontWeight });
+ }
+
+ ///
+ public override void BeginSpan(HighlightingColor highlightingColor)
+ {
+ WriteIndentationAndSpace();
+ if (options.ColorNeedsSpanForStyling(highlightingColor)) {
+ htmlWriter.Write("');
+ endTagStack.Push("");
+ } else {
+ endTagStack.Push(null);
+ }
+ }
+
+ ///
+ public override void BeginHyperlinkSpan(Uri uri)
+ {
+ WriteIndentationAndSpace();
+ htmlWriter.Write("");
+ endTagStack.Push("");
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/CSS-Mode.xshd b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/CSS-Mode.xshd
index 3ef562f0da..198f6e124b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/CSS-Mode.xshd
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/CSS-Mode.xshd
@@ -1,13 +1,12 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
/\*
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/JavaScript-Mode.xshd b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/JavaScript-Mode.xshd
index 97775dce5b..f30543c97b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/JavaScript-Mode.xshd
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Resources/JavaScript-Mode.xshd
@@ -2,15 +2,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
break
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs
new file mode 100644
index 0000000000..597bfe5015
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs
@@ -0,0 +1,252 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Windows.Documents;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Utils;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// Represents a immutable piece text with highlighting information.
+ ///
+ public class RichText
+ {
+ ///
+ /// The empty string without any formatting information.
+ ///
+ public static readonly RichText Empty = new RichText(string.Empty);
+
+ readonly string text;
+ internal readonly int[] stateChangeOffsets;
+ internal readonly HighlightingColor[] stateChanges;
+
+ ///
+ /// Creates a RichText instance with the given text and RichTextModel.
+ ///
+ ///
+ /// The text to use in this RichText instance.
+ ///
+ ///
+ /// The model that contains the formatting to use for this RichText instance.
+ /// model.DocumentLength should correspond to text.Length.
+ /// This parameter may be null, in which case the RichText instance just holds plain text.
+ ///
+ public RichText(string text, RichTextModel model = null)
+ {
+ if (text == null)
+ throw new ArgumentNullException("text");
+ this.text = text;
+ if (model != null) {
+ var sections = model.GetHighlightedSections(0, text.Length).ToArray();
+ stateChangeOffsets = new int[sections.Length];
+ stateChanges = new HighlightingColor[sections.Length];
+ for (int i = 0; i < sections.Length; i++) {
+ stateChangeOffsets[i] = sections[i].Offset;
+ stateChanges[i] = sections[i].Color;
+ }
+ } else {
+ stateChangeOffsets = new int[] { 0 };
+ stateChanges = new HighlightingColor[] { HighlightingColor.Empty };
+ }
+ }
+
+ internal RichText(string text, int[] offsets, HighlightingColor[] states)
+ {
+ this.text = text;
+ Debug.Assert(offsets[0] == 0);
+ Debug.Assert(offsets.Last() <= text.Length);
+ this.stateChangeOffsets = offsets;
+ this.stateChanges = states;
+ }
+
+ ///
+ /// Gets the text.
+ ///
+ public string Text {
+ get { return text; }
+ }
+
+ ///
+ /// Gets the text length.
+ ///
+ public int Length {
+ get { return text.Length; }
+ }
+
+ int GetIndexForOffset(int offset)
+ {
+ if (offset < 0 || offset > text.Length)
+ throw new ArgumentOutOfRangeException("offset");
+ int index = Array.BinarySearch(stateChangeOffsets, offset);
+ if (index < 0) {
+ // If no color change exists directly at offset,
+ // return the index of the color segment that contains offset.
+ index = ~index - 1;
+ }
+ return index;
+ }
+
+ int GetEnd(int index)
+ {
+ // Gets the end of the color segment no. index.
+ if (index + 1 < stateChangeOffsets.Length)
+ return stateChangeOffsets[index + 1];
+ else
+ return text.Length;
+ }
+
+ ///
+ /// Gets the HighlightingColor for the specified offset.
+ ///
+ public HighlightingColor GetHighlightingAt(int offset)
+ {
+ return stateChanges[GetIndexForOffset(offset)];
+ }
+
+ ///
+ /// Retrieves the highlighted sections in the specified range.
+ /// The highlighted sections will be sorted by offset, and there will not be any nested or overlapping sections.
+ ///
+ public IEnumerable GetHighlightedSections(int offset, int length)
+ {
+ int index = GetIndexForOffset(offset);
+ int pos = offset;
+ int endOffset = offset + length;
+ while (pos < endOffset) {
+ int endPos = Math.Min(endOffset, GetEnd(index));
+ yield return new HighlightedSection {
+ Offset = pos,
+ Length = endPos - pos,
+ Color = stateChanges[index]
+ };
+ pos = endPos;
+ index++;
+ }
+ }
+
+ ///
+ /// Creates a new RichTextModel with the formatting from this RichText.
+ ///
+ public RichTextModel ToRichTextModel()
+ {
+ return new RichTextModel(stateChangeOffsets, stateChanges);
+ }
+
+ ///
+ /// Gets the text.
+ ///
+ public override string ToString()
+ {
+ return text;
+ }
+
+ ///
+ /// Creates WPF Run instances that can be used for TextBlock.Inlines.
+ ///
+ public Run[] CreateRuns()
+ {
+ Run[] runs = new Run[stateChanges.Length];
+ for (int i = 0; i < runs.Length; i++) {
+ int startOffset = stateChangeOffsets[i];
+ int endOffset = i + 1 < stateChangeOffsets.Length ? stateChangeOffsets[i + 1] : text.Length;
+ Run r = new Run(text.Substring(startOffset, endOffset - startOffset));
+ HighlightingColor state = stateChanges[i];
+ if (state.Foreground != null)
+ r.Foreground = state.Foreground.GetBrush(null);
+ if (state.Background != null)
+ r.Background = state.Background.GetBrush(null);
+ if (state.FontWeight != null)
+ r.FontWeight = state.FontWeight.Value;
+ if (state.FontStyle != null)
+ r.FontStyle = state.FontStyle.Value;
+ runs[i] = r;
+ }
+ return runs;
+ }
+
+ ///
+ /// Produces HTML code for the line, with <span style="..."> tags.
+ ///
+ public string ToHtml(HtmlOptions options = null)
+ {
+ StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
+ using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
+ htmlWriter.Write(this);
+ }
+ return stringWriter.ToString();
+ }
+
+ ///
+ /// Produces HTML code for a section of the line, with <span style="..."> tags.
+ ///
+ public string ToHtml(int offset, int length, HtmlOptions options = null)
+ {
+ StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
+ using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
+ htmlWriter.Write(this, offset, length);
+ }
+ return stringWriter.ToString();
+ }
+
+ ///
+ /// Creates a substring of this rich text.
+ ///
+ public RichText Substring(int offset, int length)
+ {
+ if (offset == 0 && length == this.Length)
+ return this;
+ string newText = text.Substring(offset, length);
+ RichTextModel model = ToRichTextModel();
+ OffsetChangeMap map = new OffsetChangeMap(2);
+ map.Add(new OffsetChangeMapEntry(offset + length, text.Length - offset - length, 0));
+ map.Add(new OffsetChangeMapEntry(0, offset, 0));
+ model.UpdateOffsets(map);
+ return new RichText(newText, model);
+ }
+
+ ///
+ /// Concatenates the specified rich texts.
+ ///
+ public static RichText Concat(params RichText[] texts)
+ {
+ if (texts == null || texts.Length == 0)
+ return Empty;
+ else if (texts.Length == 1)
+ return texts[0];
+ string newText = string.Concat(texts.Select(txt => txt.text));
+ RichTextModel model = texts[0].ToRichTextModel();
+ int offset = texts[0].Length;
+ for (int i = 1; i < texts.Length; i++) {
+ model.Append(offset, texts[i].stateChangeOffsets, texts[i].stateChanges);
+ offset += texts[i].Length;
+ }
+ return new RichText(newText, model);
+ }
+
+ ///
+ /// Concatenates the specified rich texts.
+ ///
+ public static RichText operator +(RichText a, RichText b)
+ {
+ return RichText.Concat(a, b);
+ }
+
+ ///
+ /// Implicit conversion from string to RichText.
+ ///
+ public static implicit operator RichText(string text)
+ {
+ if (text != null)
+ return new RichText(text);
+ else
+ return null;
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextColorizer.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextColorizer.cs
new file mode 100644
index 0000000000..1ffa7b24ec
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextColorizer.cs
@@ -0,0 +1,39 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Rendering;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// A colorizer that applies the highlighting from a to the editor.
+ ///
+ public class RichTextColorizer : DocumentColorizingTransformer
+ {
+ readonly RichTextModel richTextModel;
+
+ ///
+ /// Creates a new RichTextColorizer instance.
+ ///
+ public RichTextColorizer(RichTextModel richTextModel)
+ {
+ if (richTextModel == null)
+ throw new ArgumentNullException("richTextModel");
+ this.richTextModel = richTextModel;
+ }
+
+ ///
+ protected override void ColorizeLine(DocumentLine line)
+ {
+ var sections = richTextModel.GetHighlightedSections(line.Offset, line.Length);
+ foreach (HighlightedSection section in sections) {
+ if (HighlightingColorizer.IsEmptyColor(section.Color))
+ continue;
+ ChangeLinePart(section.Offset, section.Offset + section.Length,
+ visualLineElement => HighlightingColorizer.ApplyColorToElement(visualLineElement, section.Color, CurrentContext));
+ }
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs
new file mode 100644
index 0000000000..7a5f604a27
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs
@@ -0,0 +1,268 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Utils;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// Stores rich-text formatting.
+ ///
+ public sealed class RichTextModel : AbstractFreezable
+ {
+ List stateChangeOffsets = new List();
+ List stateChanges = new List();
+
+ int GetIndexForOffset(int offset)
+ {
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException("offset");
+ int index = stateChangeOffsets.BinarySearch(offset);
+ if (index < 0) {
+ // If no color change exists directly at offset,
+ // create a new one.
+ index = ~index;
+ stateChanges.Insert(index, stateChanges[index - 1].Clone());
+ stateChangeOffsets.Insert(index, offset);
+ }
+ return index;
+ }
+
+ int GetIndexForOffsetUseExistingSegment(int offset)
+ {
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException("offset");
+ int index = stateChangeOffsets.BinarySearch(offset);
+ if (index < 0) {
+ // If no color change exists directly at offset,
+ // return the index of the color segment that contains offset.
+ index = ~index - 1;
+ }
+ return index;
+ }
+
+ int GetEnd(int index)
+ {
+ // Gets the end of the color segment no. index.
+ if (index + 1 < stateChangeOffsets.Count)
+ return stateChangeOffsets[index + 1];
+ else
+ return int.MaxValue;
+ }
+
+ ///
+ /// Creates a new RichTextModel.
+ ///
+ public RichTextModel()
+ {
+ stateChangeOffsets.Add(0);
+ stateChanges.Add(new HighlightingColor());
+ }
+
+ ///
+ /// Creates a RichTextModel from a CONTIGUOUS list of HighlightedSections.
+ ///
+ internal RichTextModel(int[] stateChangeOffsets, HighlightingColor[] stateChanges)
+ {
+ Debug.Assert(stateChangeOffsets[0] == 0);
+ this.stateChangeOffsets.AddRange(stateChangeOffsets);
+ this.stateChanges.AddRange(stateChanges);
+ }
+
+ #region UpdateOffsets
+ ///
+ /// Updates the start and end offsets of all segments stored in this collection.
+ ///
+ /// TextChangeEventArgs instance describing the change to the document.
+ public void UpdateOffsets(TextChangeEventArgs e)
+ {
+ if (e == null)
+ throw new ArgumentNullException("e");
+ UpdateOffsets(e.GetNewOffset);
+ }
+
+ ///
+ /// Updates the start and end offsets of all segments stored in this collection.
+ ///
+ /// OffsetChangeMap instance describing the change to the document.
+ public void UpdateOffsets(OffsetChangeMap change)
+ {
+ if (change == null)
+ throw new ArgumentNullException("change");
+ UpdateOffsets(change.GetNewOffset);
+ }
+
+ ///
+ /// Updates the start and end offsets of all segments stored in this collection.
+ ///
+ /// OffsetChangeMapEntry instance describing the change to the document.
+ public void UpdateOffsets(OffsetChangeMapEntry change)
+ {
+ UpdateOffsets(change.GetNewOffset);
+ }
+
+ void UpdateOffsets(Func updateOffset)
+ {
+ int readPos = 1;
+ int writePos = 1;
+ while (readPos < stateChangeOffsets.Count) {
+ Debug.Assert(writePos <= readPos);
+ int newOffset = updateOffset(stateChangeOffsets[readPos], AnchorMovementType.Default);
+ if (newOffset == stateChangeOffsets[writePos - 1]) {
+ // offset moved to same position as previous offset
+ // -> previous segment has length 0 and gets overwritten with this segment
+ stateChanges[writePos - 1] = stateChanges[readPos];
+ } else {
+ stateChangeOffsets[writePos] = newOffset;
+ stateChanges[writePos] = stateChanges[readPos];
+ writePos++;
+ }
+ readPos++;
+ }
+ // Delete all entries that were not written to
+ stateChangeOffsets.RemoveRange(writePos, stateChangeOffsets.Count - writePos);
+ stateChanges.RemoveRange(writePos, stateChanges.Count - writePos);
+ }
+ #endregion
+
+ ///
+ /// Appends another RichTextModel after this one.
+ ///
+ internal void Append(int offset, int[] newOffsets, HighlightingColor[] newColors)
+ {
+ Debug.Assert(newOffsets.Length == newColors.Length);
+ Debug.Assert(newOffsets[0] == 0);
+ // remove everything before offset:
+ while (stateChangeOffsets.Count > 0 && stateChangeOffsets.Last() <= offset) {
+ stateChangeOffsets.RemoveAt(stateChangeOffsets.Count - 1);
+ stateChanges.RemoveAt(stateChanges.Count - 1);
+ }
+ // Append the new segments
+ for (int i = 0; i < newOffsets.Length; i++) {
+ stateChangeOffsets.Add(offset + newOffsets[i]);
+ stateChanges.Add(newColors[i]);
+ }
+ }
+
+ ///
+ /// Gets a copy of the HighlightingColor for the specified offset.
+ ///
+ public HighlightingColor GetHighlightingAt(int offset)
+ {
+ return stateChanges[GetIndexForOffsetUseExistingSegment(offset)].Clone();
+ }
+
+ ///
+ /// Applies the HighlightingColor to the specified range of text.
+ /// If the color specifies null for some properties, existing highlighting is preserved.
+ ///
+ public void ApplyHighlighting(int offset, int length, HighlightingColor color)
+ {
+ if (color == null || color.IsEmptyForMerge) {
+ // Optimization: don't split the HighlightingState when we're not changing
+ // any property. For example, the "Punctuation" color in C# is
+ // empty by default.
+ return;
+ }
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ for (int i = startIndex; i < endIndex; i++) {
+ stateChanges[i].MergeWith(color);
+ }
+ }
+
+ ///
+ /// Sets the HighlightingColor for the specified range of text,
+ /// completely replacing the existing highlighting in that area.
+ ///
+ public void SetHighlighting(int offset, int length, HighlightingColor color)
+ {
+ if (length <= 0)
+ return;
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ stateChanges[startIndex] = color != null ? color.Clone() : new HighlightingColor();
+ stateChanges.RemoveRange(startIndex + 1, endIndex - (startIndex + 1));
+ stateChangeOffsets.RemoveRange(startIndex + 1, endIndex - (startIndex + 1));
+ }
+
+ ///
+ /// Sets the foreground brush on the specified text segment.
+ ///
+ public void SetForeground(int offset, int length, HighlightingBrush brush)
+ {
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ for (int i = startIndex; i < endIndex; i++) {
+ stateChanges[i].Foreground = brush;
+ }
+ }
+
+ ///
+ /// Sets the background brush on the specified text segment.
+ ///
+ public void SetBackground(int offset, int length, HighlightingBrush brush)
+ {
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ for (int i = startIndex; i < endIndex; i++) {
+ stateChanges[i].Background = brush;
+ }
+ }
+
+ ///
+ /// Sets the font weight on the specified text segment.
+ ///
+ public void SetFontWeight(int offset, int length, FontWeight weight)
+ {
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ for (int i = startIndex; i < endIndex; i++) {
+ stateChanges[i].FontWeight = weight;
+ }
+ }
+
+ ///
+ /// Sets the font style on the specified text segment.
+ ///
+ public void SetFontStyle(int offset, int length, FontStyle style)
+ {
+ int startIndex = GetIndexForOffset(offset);
+ int endIndex = GetIndexForOffset(offset + length);
+ for (int i = startIndex; i < endIndex; i++) {
+ stateChanges[i].FontStyle = style;
+ }
+ }
+
+ ///
+ /// Retrieves the highlighted sections in the specified range.
+ /// The highlighted sections will be sorted by offset, and there will not be any nested or overlapping sections.
+ ///
+ public IEnumerable GetHighlightedSections(int offset, int length)
+ {
+ int index = GetIndexForOffsetUseExistingSegment(offset);
+ int pos = offset;
+ int endOffset = offset + length;
+ while (pos < endOffset) {
+ int endPos = Math.Min(endOffset, GetEnd(index));
+ yield return new HighlightedSection {
+ Offset = pos,
+ Length = endPos - pos,
+ Color = stateChanges[index].Clone()
+ };
+ pos = endPos;
+ index++;
+ }
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModelWriter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModelWriter.cs
new file mode 100644
index 0000000000..fc12a8f56a
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModelWriter.cs
@@ -0,0 +1,115 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Windows;
+using System.Windows.Media;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Utils;
+
+namespace ICSharpCode.AvalonEdit.Highlighting
+{
+ ///
+ /// A RichTextWriter that writes into a document and RichTextModel.
+ ///
+ class RichTextModelWriter : PlainRichTextWriter
+ {
+ readonly RichTextModel richTextModel;
+ readonly DocumentTextWriter documentTextWriter;
+ readonly Stack colorStack = new Stack();
+ HighlightingColor currentColor;
+ int currentColorBegin = -1;
+
+ ///
+ /// Creates a new RichTextModelWriter that inserts into document, starting at insertionOffset.
+ ///
+ public RichTextModelWriter(RichTextModel richTextModel, IDocument document, int insertionOffset)
+ : base(new DocumentTextWriter(document, insertionOffset))
+ {
+ if (richTextModel == null)
+ throw new ArgumentNullException("richTextModel");
+ this.richTextModel = richTextModel;
+ this.documentTextWriter = (DocumentTextWriter)base.textWriter;
+ currentColor = richTextModel.GetHighlightingAt(Math.Max(0, insertionOffset - 1));
+ }
+
+ ///
+ /// Gets/Sets the current insertion offset.
+ ///
+ public int InsertionOffset {
+ get { return documentTextWriter.InsertionOffset; }
+ set { documentTextWriter.InsertionOffset = value; }
+ }
+
+
+ ///
+ protected override void BeginUnhandledSpan()
+ {
+ colorStack.Push(currentColor);
+ }
+
+ void BeginColorSpan()
+ {
+ WriteIndentationIfNecessary();
+ colorStack.Push(currentColor);
+ currentColor = currentColor.Clone();
+ currentColorBegin = documentTextWriter.InsertionOffset;
+ }
+
+ ///
+ public override void EndSpan()
+ {
+ currentColor = colorStack.Pop();
+ currentColorBegin = documentTextWriter.InsertionOffset;
+ }
+
+ ///
+ protected override void AfterWrite()
+ {
+ base.AfterWrite();
+ richTextModel.SetHighlighting(currentColorBegin, documentTextWriter.InsertionOffset - currentColorBegin, currentColor);
+ }
+
+ ///
+ public override void BeginSpan(Color foregroundColor)
+ {
+ BeginColorSpan();
+ currentColor.Foreground = new SimpleHighlightingBrush(foregroundColor);
+ currentColor.Freeze();
+ }
+
+ ///
+ public override void BeginSpan(FontFamily fontFamily)
+ {
+ BeginUnhandledSpan(); // TODO
+ }
+
+ ///
+ public override void BeginSpan(FontStyle fontStyle)
+ {
+ BeginColorSpan();
+ currentColor.FontStyle = fontStyle;
+ currentColor.Freeze();
+ }
+
+ ///
+ public override void BeginSpan(FontWeight fontWeight)
+ {
+ BeginColorSpan();
+ currentColor.FontWeight = fontWeight;
+ currentColor.Freeze();
+ }
+
+ ///
+ public override void BeginSpan(HighlightingColor highlightingColor)
+ {
+ BeginColorSpan();
+ currentColor.MergeWith(highlightingColor);
+ currentColor.Freeze();
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
index e95c47b1ae..87e26cfbe4 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
@@ -102,6 +102,7 @@
UndoStack.cs
+
@@ -196,6 +197,8 @@
+
+
@@ -204,6 +207,10 @@
+
+
+
+
@@ -354,7 +361,9 @@
+
+
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
index 3b9abcf2b9..72012a58ff 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
@@ -1166,7 +1166,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
}
}
}
- InvalidateCursor();
+ InvalidateCursorIfMouseWithinTextView();
return finalSize;
}
@@ -1637,6 +1637,15 @@ namespace ICSharpCode.AvalonEdit.Rendering
}
}
+ internal void InvalidateCursorIfMouseWithinTextView()
+ {
+ // Don't unnecessarily call Mouse.UpdateCursor() if the mouse is outside the text view.
+ // Unnecessary updates may cause the mouse pointer to flicker
+ // (e.g. if it is over a window border, it blinks between Resize and Normal)
+ if (this.IsMouseOver)
+ InvalidateCursor();
+ }
+
///
protected override void OnQueryCursor(QueryCursorEventArgs e)
{
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs
index 98ab0b42d2..c25057eeac 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs
@@ -198,6 +198,7 @@ namespace ICSharpCode.AvalonEdit.Search
{
if (textArea == null)
throw new ArgumentNullException("textArea");
+ #pragma warning disable 618
SearchPanel panel = new SearchPanel();
panel.AttachInternal(textArea);
panel.handler = new SearchInputHandler(textArea, panel);
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs
index 0ba831cc0a..0c9b77de09 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/CompressingTreeList.cs
@@ -1,6 +1,6 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
+#define DATACONSISTENCYTEST
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -411,8 +411,26 @@ namespace ICSharpCode.AvalonEdit.Utils
}
prevNode = n;
}
+ CheckProperties();
+ }
+
+ ///
+ /// Applies the conversion function to the elements in the specified range.
+ ///
+ public void TransformRange(int index, int length, Func converter)
+ {
+ if (root == null)
+ return;
+ int endIndex = index + length;
+ int pos = index;
+ while (pos < endIndex) {
+ int endPos = Math.Min(endIndex, GetEndOfRun(pos));
+ T oldValue = this[pos];
+ T newValue = converter(oldValue);
+ SetRange(pos, endPos - pos, newValue);
+ pos = endPos;
+ }
}
-
///
/// Inserts the specified at
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/PlainRichTextWriter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/PlainRichTextWriter.cs
new file mode 100644
index 0000000000..610f005a09
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/PlainRichTextWriter.cs
@@ -0,0 +1,125 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace ICSharpCode.AvalonEdit.Utils
+{
+ ///
+ /// RichTextWriter implementation that writes plain text only
+ /// and ignores all formatted spans.
+ ///
+ class PlainRichTextWriter : RichTextWriter
+ {
+ ///
+ /// The text writer that was passed to the PlainRichTextWriter constructor.
+ ///
+ protected readonly TextWriter textWriter;
+ string indentationString = "\t";
+ int indentationLevel;
+ char prevChar;
+
+ ///
+ /// Creates a new PlainRichTextWriter instance that writes the text to the specified text writer.
+ ///
+ public PlainRichTextWriter(TextWriter textWriter)
+ {
+ if (textWriter == null)
+ throw new ArgumentNullException("textWriter");
+ this.textWriter = textWriter;
+ }
+
+ ///
+ /// Gets/Sets the string used to indent by one level.
+ ///
+ public string IndentationString {
+ get {
+ return indentationString;
+ }
+ set {
+ indentationString = value;
+ }
+ }
+
+ ///
+ protected override void BeginUnhandledSpan()
+ {
+ }
+
+ ///
+ public override void EndSpan()
+ {
+ }
+
+ void WriteIndentation()
+ {
+ for (int i = 0; i < indentationLevel; i++) {
+ textWriter.Write(indentationString);
+ }
+ }
+
+ ///
+ /// Writes the indentation, if necessary.
+ ///
+ protected void WriteIndentationIfNecessary()
+ {
+ if (prevChar == '\n') {
+ WriteIndentation();
+ prevChar = '\0';
+ }
+ }
+
+ ///
+ /// Is called after a write operation.
+ ///
+ protected virtual void AfterWrite()
+ {
+ }
+
+ ///
+ public override void Write(char value)
+ {
+ if (prevChar == '\n')
+ WriteIndentation();
+ textWriter.Write(value);
+ prevChar = value;
+ AfterWrite();
+ }
+
+ ///
+ public override void Indent()
+ {
+ indentationLevel++;
+ }
+
+ ///
+ public override void Unindent()
+ {
+ if (indentationLevel == 0)
+ throw new NotSupportedException();
+ indentationLevel--;
+ }
+
+ ///
+ public override Encoding Encoding {
+ get { return textWriter.Encoding; }
+ }
+
+ ///
+ public override IFormatProvider FormatProvider {
+ get { return textWriter.FormatProvider; }
+ }
+
+ ///
+ public override string NewLine {
+ get {
+ return textWriter.NewLine;
+ }
+ set {
+ textWriter.NewLine = value;
+ }
+ }
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs
new file mode 100644
index 0000000000..49b884d1c0
--- /dev/null
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs
@@ -0,0 +1,106 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Windows;
+using System.Windows.Media;
+using ICSharpCode.AvalonEdit.Highlighting;
+
+namespace ICSharpCode.AvalonEdit.Utils
+{
+ ///
+ /// A text writer that supports creating spans of highlighted text.
+ ///
+ abstract class RichTextWriter : TextWriter
+ {
+ ///
+ /// Gets called by the RichTextWriter base class when a BeginSpan() method
+ /// that is not overwritten gets called.
+ ///
+ protected abstract void BeginUnhandledSpan();
+
+ ///
+ /// Writes the RichText instance.
+ ///
+ public void Write(RichText richText)
+ {
+ Write(richText, 0, richText.Length);
+ }
+
+ ///
+ /// Writes the RichText instance.
+ ///
+ public virtual void Write(RichText richText, int offset, int length)
+ {
+ foreach (var section in richText.GetHighlightedSections(offset, length)) {
+ BeginSpan(section.Color);
+ Write(richText.Text.Substring(section.Offset, section.Length));
+ EndSpan();
+ }
+ }
+
+ ///
+ /// Begin a colored span.
+ ///
+ public virtual void BeginSpan(Color foregroundColor)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Begin a span with modified font weight.
+ ///
+ public virtual void BeginSpan(FontWeight fontWeight)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Begin a span with modified font style.
+ ///
+ public virtual void BeginSpan(FontStyle fontStyle)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Begin a span with modified font family.
+ ///
+ public virtual void BeginSpan(FontFamily fontFamily)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Begin a highlighted span.
+ ///
+ public virtual void BeginSpan(Highlighting.HighlightingColor highlightingColor)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Begin a span that links to the specified URI.
+ ///
+ public virtual void BeginHyperlinkSpan(Uri uri)
+ {
+ BeginUnhandledSpan();
+ }
+
+ ///
+ /// Marks the end of the current span.
+ ///
+ public abstract void EndSpan();
+
+ ///
+ /// Increases the indentation level.
+ ///
+ public abstract void Indent();
+
+ ///
+ /// Decreases the indentation level.
+ ///
+ public abstract void Unindent();
+ }
+}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs
deleted file mode 100644
index 6b5fd36b67..0000000000
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using ICSharpCode.AvalonEdit.Utils;
-using ICSharpCode.NRefactory.Utils;
-
-namespace ICSharpCode.AvalonEdit.Xml
-{
- class TagMatchingHeuristics
- {
- const int maxConfigurationCount = 10;
-
- AXmlParser parser;
- TrackedSegmentCollection trackedSegments;
- string input;
- List tags;
-
- public TagMatchingHeuristics(AXmlParser parser, string input, List tags)
- {
- this.parser = parser;
- this.trackedSegments = parser.TrackedSegments;
- this.input = input;
- this.tags = tags;
- }
-
- public AXmlDocument ReadDocument()
- {
- AXmlDocument doc = new AXmlDocument() { Parser = parser };
-
- // AXmlParser.Log("Flat stream: {0}", PrintObjects(tags));
- List valid = MatchTags(tags);
- // AXmlParser.Log("Fixed stream: {0}", PrintObjects(valid));
- IEnumerator validStream = valid.GetEnumerator();
- validStream.MoveNext(); // Move to first
- while(true) {
- // End of stream?
- try {
- if (validStream.Current == null) break;
- } catch (InvalidCastException) {
- break;
- }
- doc.AddChild(ReadTextOrElement(validStream));
- }
-
- if (doc.Children.Count > 0) {
- doc.StartOffset = doc.FirstChild.StartOffset;
- doc.EndOffset = doc.LastChild.EndOffset;
- }
-
- // Check well formed
- foreach(AXmlTag xmlDeclaration in doc.Children.OfType().Where(t => t.IsProcessingInstruction && string.Equals(t.Name, "xml", StringComparison.OrdinalIgnoreCase))) {
- if (xmlDeclaration.StartOffset != 0)
- TagReader.OnSyntaxError(doc, xmlDeclaration.StartOffset, xmlDeclaration.StartOffset + 5,
- "XML declaration must be at the start of document");
- }
- int elemCount = doc.Children.OfType().Count();
- if (elemCount == 0)
- TagReader.OnSyntaxError(doc, doc.EndOffset, doc.EndOffset,
- "Root element is missing");
- if (elemCount > 1) {
- AXmlElement next = doc.Children.OfType().Skip(1).First();
- TagReader.OnSyntaxError(doc, next.StartOffset, next.StartOffset,
- "Only one root element is allowed");
- }
- foreach(AXmlTag tag in doc.Children.OfType()) {
- if (tag.IsCData)
- TagReader.OnSyntaxError(doc, tag.StartOffset, tag.EndOffset,
- "CDATA not allowed in document root");
- }
- foreach(AXmlText text in doc.Children.OfType()) {
- if (!text.ContainsOnlyWhitespace)
- TagReader.OnSyntaxError(doc, text.StartOffset, text.EndOffset,
- "Only whitespace is allowed in document root");
- }
-
-
- AXmlParser.Log("Constructed {0}", doc);
- trackedSegments.AddParsedObject(doc, null);
- return doc;
- }
-
- static AXmlObject ReadSingleObject(IEnumerator objStream)
- {
- AXmlObject obj = objStream.Current;
- objStream.MoveNext();
- return obj;
- }
-
- AXmlObject ReadTextOrElement(IEnumerator objStream)
- {
- AXmlObject curr = objStream.Current;
- if (curr is AXmlText || curr is AXmlElement) {
- return ReadSingleObject(objStream);
- } else {
- AXmlTag currTag = (AXmlTag)curr;
- if (currTag == StartTagPlaceholder) {
- return ReadElement(objStream);
- } else if (currTag.IsStartOrEmptyTag) {
- return ReadElement(objStream);
- } else {
- return ReadSingleObject(objStream);
- }
- }
- }
-
- AXmlElement ReadElement(IEnumerator objStream)
- {
- AXmlElement element = new AXmlElement();
- element.IsProperlyNested = true;
-
- // Read start tag
- AXmlTag startTag = ReadSingleObject(objStream) as AXmlTag;
- AXmlParser.DebugAssert(startTag != null, "Start tag expected");
- AXmlParser.DebugAssert(startTag.IsStartOrEmptyTag || startTag == StartTagPlaceholder, "Start tag expected");
- if (startTag == StartTagPlaceholder) {
- element.HasStartOrEmptyTag = false;
- element.IsProperlyNested = false;
- TagReader.OnSyntaxError(element, objStream.Current.StartOffset, objStream.Current.EndOffset,
- "Matching openning tag was not found");
- } else {
- element.HasStartOrEmptyTag = true;
- element.AddChild(startTag);
- }
-
- // Read content and end tag
- if (startTag == StartTagPlaceholder || // Check first in case the start tag is null
- element.StartTag.IsStartTag)
- {
- while(true) {
- AXmlTag currTag = objStream.Current as AXmlTag; // Peek
- if (currTag == EndTagPlaceholder) {
- TagReader.OnSyntaxError(element, element.LastChild.EndOffset, element.LastChild.EndOffset,
- "Expected '{0}>'", element.StartTag.Name);
- ReadSingleObject(objStream);
- element.HasEndTag = false;
- element.IsProperlyNested = false;
- break;
- } else if (currTag != null && currTag.IsEndTag) {
- if (element.HasStartOrEmptyTag && currTag.Name != element.StartTag.Name) {
- TagReader.OnSyntaxError(element, currTag.StartOffset + 2, currTag.StartOffset + 2 + currTag.Name.Length,
- "Expected '{0}'. End tag must have same name as start tag.", element.StartTag.Name);
- }
- element.AddChild(ReadSingleObject(objStream));
- element.HasEndTag = true;
- break;
- }
- AXmlObject nested = ReadTextOrElement(objStream);
-
- AXmlElement nestedAsElement = nested as AXmlElement;
- if (nestedAsElement != null) {
- if (!nestedAsElement.IsProperlyNested)
- element.IsProperlyNested = false;
- element.AddChildren(Split(nestedAsElement).ToList());
- } else {
- element.AddChild(nested);
- }
- }
- } else {
- element.HasEndTag = false;
- }
-
- element.StartOffset = element.FirstChild.StartOffset;
- element.EndOffset = element.LastChild.EndOffset;
-
- AXmlParser.Assert(element.HasStartOrEmptyTag || element.HasEndTag, "Must have at least start or end tag");
-
- AXmlParser.Log("Constructed {0}", element);
- trackedSegments.AddParsedObject(element, null); // Need all elements in cache for offset tracking
- return element;
- }
-
- IEnumerable Split(AXmlElement elem)
- {
- int myIndention = GetIndentLevel(elem);
- // Has start tag and no end tag ? (other then empty-element tag)
- if (elem.HasStartOrEmptyTag && elem.StartTag.IsStartTag && !elem.HasEndTag && myIndention != -1) {
- int lastAccepted = 0; // Accept start tag
- while (lastAccepted + 1 < elem.Children.Count) {
- AXmlObject nextItem = elem.Children[lastAccepted + 1];
- if (nextItem is AXmlText) {
- lastAccepted++; continue; // Accept
- } else {
- // Include all more indented items
- if (GetIndentLevel(nextItem) > myIndention) {
- lastAccepted++; continue; // Accept
- } else {
- break; // Reject
- }
- }
- }
- // Accepted everything?
- if (lastAccepted + 1 == elem.Children.Count) {
- yield return elem;
- yield break;
- }
- AXmlParser.Log("Splitting {0} - take {1} of {2} nested", elem, lastAccepted, elem.Children.Count - 1);
- AXmlElement topHalf = new AXmlElement();
- topHalf.HasStartOrEmptyTag = elem.HasStartOrEmptyTag;
- topHalf.HasEndTag = elem.HasEndTag;
- topHalf.AddChildren(elem.Children.Take(1 + lastAccepted)); // Start tag + nested
- topHalf.StartOffset = topHalf.FirstChild.StartOffset;
- topHalf.EndOffset = topHalf.LastChild.EndOffset;
- TagReader.OnSyntaxError(topHalf, topHalf.LastChild.EndOffset, topHalf.LastChild.EndOffset,
- "Expected '{0}>'", topHalf.StartTag.Name);
-
- AXmlParser.Log("Constructed {0}", topHalf);
- trackedSegments.AddParsedObject(topHalf, null);
- yield return topHalf;
- for(int i = lastAccepted + 1; i < elem.Children.Count; i++) {
- yield return elem.Children[i];
- }
- } else {
- yield return elem;
- }
- }
-
- int GetIndentLevel(AXmlObject obj)
- {
- int offset = obj.StartOffset - 1;
- int level = 0;
- while(true) {
- if (offset < 0) break;
- char c = input[offset];
- if (c == ' ') {
- level++;
- } else if (c == '\t') {
- level += 4;
- } else if (c == '\r' || c == '\n') {
- break;
- } else {
- return -1;
- }
- offset--;
- }
- return level;
- }
-
- ///
- /// Stack of still unmatched start tags.
- /// It includes the cost and backtack information.
- ///
- class Configuration
- {
- /// Unmatched start tags
- public ImmutableStack StartTags { get; set; }
- /// Properly nested tags
- public ImmutableStack Document { get; set; }
- /// Number of needed modificaitons to the document
- public int Cost { get; set; }
- }
-
- ///
- /// Dictionary which stores the cheapest configuration
- ///
- class Configurations: Dictionary, Configuration>
- {
- public Configurations()
- {
- }
-
- public Configurations(IEnumerable configs)
- {
- foreach(Configuration config in configs) {
- this.Add(config);
- }
- }
-
- /// Overwrite only if cheaper
- public void Add(Configuration newConfig)
- {
- Configuration oldConfig;
- if (this.TryGetValue(newConfig.StartTags, out oldConfig)) {
- if (newConfig.Cost < oldConfig.Cost) {
- this[newConfig.StartTags] = newConfig;
- }
- } else {
- base.Add(newConfig.StartTags, newConfig);
- }
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- foreach(var kvp in this) {
- sb.Append("\n - '");
- foreach(AXmlTag startTag in kvp.Value.StartTags.Reverse()) {
- sb.Append('<');
- sb.Append(startTag.Name);
- sb.Append('>');
- }
- sb.AppendFormat("' = {0}", kvp.Value.Cost);
- }
- return sb.ToString();
- }
- }
-
- // Tags used to guide the element creation
- readonly AXmlTag StartTagPlaceholder = new AXmlTag();
- readonly AXmlTag EndTagPlaceholder = new AXmlTag();
-
- ///
- /// Add start or end tag placeholders so that the documment is properly nested
- ///
- List MatchTags(IEnumerable objs)
- {
- Configurations configurations = new Configurations();
- configurations.Add(new Configuration {
- StartTags = ImmutableStack.Empty,
- Document = ImmutableStack.Empty,
- Cost = 0,
- });
- foreach(AXmlObject obj in objs) {
- configurations = ProcessObject(configurations, obj);
- }
- // Close any remaining start tags
- foreach(Configuration conifg in configurations.Values) {
- while(!conifg.StartTags.IsEmpty) {
- conifg.StartTags = conifg.StartTags.Pop();
- conifg.Document = conifg.Document.Push(EndTagPlaceholder);
- conifg.Cost += 1;
- }
- }
- // AXmlParser.Log("Configurations after closing all remaining tags:" + configurations.ToString());
- Configuration bestConfig = configurations.Values.OrderBy(v => v.Cost).First();
- AXmlParser.Log("Best configuration has cost {0}", bestConfig.Cost);
-
- return bestConfig.Document.Reverse().ToList();
- }
-
- /// Get posible configurations after considering given object
- Configurations ProcessObject(Configurations oldConfigs, AXmlObject obj)
- {
- AXmlParser.Log("Processing {0}", obj);
-
- AXmlTag objAsTag = obj as AXmlTag;
- AXmlElement objAsElement = obj as AXmlElement;
- AXmlParser.DebugAssert(objAsTag != null || objAsElement != null || obj is AXmlText, obj.GetType().Name + " not expected");
- if (objAsElement != null)
- AXmlParser.Assert(objAsElement.IsProperlyNested, "Element not properly nested");
-
- Configurations newConfigs = new Configurations();
-
- foreach(var kvp in oldConfigs) {
- Configuration oldConfig = kvp.Value;
- var oldStartTags = oldConfig.StartTags;
- var oldDocument = oldConfig.Document;
- int oldCost = oldConfig.Cost;
-
- if (objAsTag != null && objAsTag.IsStartTag) {
- newConfigs.Add(new Configuration { // Push start-tag (cost 0)
- StartTags = oldStartTags.Push(objAsTag),
- Document = oldDocument.Push(objAsTag),
- Cost = oldCost,
- });
- } else if (objAsTag != null && objAsTag.IsEndTag) {
- newConfigs.Add(new Configuration { // Ignore (cost 1)
- StartTags = oldStartTags,
- Document = oldDocument.Push(StartTagPlaceholder).Push(objAsTag),
- Cost = oldCost + 1,
- });
- if (!oldStartTags.IsEmpty && oldStartTags.Peek().Name != objAsTag.Name) {
- newConfigs.Add(new Configuration { // Pop 1 item (cost 1) - not mathcing
- StartTags = oldStartTags.Pop(),
- Document = oldDocument.Push(objAsTag),
- Cost = oldCost + 1,
- });
- }
- int popedCount = 0;
- var startTags = oldStartTags;
- var doc = oldDocument;
- foreach(AXmlTag poped in oldStartTags) {
- popedCount++;
- if (poped.Name == objAsTag.Name) {
- newConfigs.Add(new Configuration { // Pop 'x' items (cost x-1) - last one is matching
- StartTags = startTags.Pop(),
- Document = doc.Push(objAsTag),
- Cost = oldCost + popedCount - 1,
- });
- }
- startTags = startTags.Pop();
- doc = doc.Push(EndTagPlaceholder);
- }
- } else {
- // Empty tag or other tag type or text or properly nested element
- newConfigs.Add(new Configuration { // Ignore (cost 0)
- StartTags = oldStartTags,
- Document = oldDocument.Push(obj),
- Cost = oldCost,
- });
- }
- }
-
- // Log("New configurations:" + newConfigs.ToString());
-
- Configurations bestNewConfigurations = new Configurations(
- newConfigs.Values.OrderBy(v => v.Cost).Take(maxConfigurationCount)
- );
-
- // AXmlParser.Log("Best new configurations:" + bestNewConfigurations.ToString());
-
- return bestNewConfigurations;
- }
-
- #region Helper methods
- /*
- string PrintObjects(IEnumerable objs)
- {
- StringBuilder sb = new StringBuilder();
- foreach(AXmlObject obj in objs) {
- if (obj is AXmlTag) {
- if (obj == StartTagPlaceholder) {
- sb.Append("#StartTag#");
- } else if (obj == EndTagPlaceholder) {
- sb.Append("#EndTag#");
- } else {
- sb.Append(((AXmlTag)obj).OpeningBracket);
- sb.Append(((AXmlTag)obj).Name);
- sb.Append(((AXmlTag)obj).ClosingBracket);
- }
- } else if (obj is AXmlElement) {
- sb.Append('[');
- sb.Append(PrintObjects(((AXmlElement)obj).Children));
- sb.Append(']');
- } else if (obj is AXmlText) {
- sb.Append('~');
- } else {
- throw new InternalException("Should not be here: " + obj);
- }
- }
- return sb.ToString();
- }
- */
- #endregion
- }
-}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
index 8cce34376d..b7d44ee64d 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
@@ -35,7 +35,7 @@ using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp
{
- public abstract class AstNode : AbstractAnnotatable, ICSharpCode.NRefactory.TypeSystem.IFreezable, PatternMatching.INode
+ public abstract class AstNode : AbstractAnnotatable, ICSharpCode.NRefactory.TypeSystem.IFreezable, PatternMatching.INode, ICloneable
{
// the Root role must be available when creating the null nodes, so we can't put it in the Roles class
internal static readonly Role RootRole = new Role ("Root");
@@ -629,6 +629,11 @@ namespace ICSharpCode.NRefactory.CSharp
return copy;
}
+ object ICloneable.Clone()
+ {
+ return Clone();
+ }
+
public abstract void AcceptVisitor (IAstVisitor visitor);
public abstract T AcceptVisitor (IAstVisitor visitor);
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/AXmlParser.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/AXmlParser.cs
index e8451d5f95..50c3f9f4ee 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/AXmlParser.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/AXmlParser.cs
@@ -133,5 +133,15 @@ namespace ICSharpCode.NRefactory.Xml
var heuristic = new TagMatchingHeuristics(newTextSource);
return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken));
}
+
+ ///
+ /// Checks whether the given name is a valid XML name.
+ ///
+ public static bool IsValidXmlName(string name)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ throw new ArgumentException("The XML name cannot be null, empty or consist solely of white space", "name");
+ return TagReader.IsValidName(name);
+ }
}
}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/TagReader.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/TagReader.cs
index e5cab93435..3483291342 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/TagReader.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/TagReader.cs
@@ -822,7 +822,7 @@ namespace ICSharpCode.NRefactory.Xml
#endregion
#region Helper functions
- static bool IsValidName(string name)
+ internal static bool IsValidName(string name)
{
try {
System.Xml.XmlConvert.VerifyName(name);
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs
index e18bab610b..2b34828e62 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs
@@ -40,5 +40,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("5.0.0.0")]
// [AssemblyFileVersion] is the version of the NuGet package,
-// should follow http://semver.org/ rules
+// Versions with breaking changes / new features should increment the 'minor' (2nd) number.
+// Bugfix releases should increment the 'build' (3rd) number.
[assembly: AssemblyFileVersion("5.3.0")]
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs
index bd81681bfa..1a3dbd3a36 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs
@@ -59,6 +59,25 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (f != null)
f.Freeze();
}
+
+ public static T FreezeAndReturn(T item) where T : IFreezable
+ {
+ item.Freeze();
+ return item;
+ }
+
+ ///
+ /// If the item is not frozen, this method creates and returns a frozen clone.
+ /// If the item is already frozen, it is returned without creating a clone.
+ ///
+ public static T GetFrozenClone(T item) where T : IFreezable, ICloneable
+ {
+ if (!item.IsFrozen) {
+ item = (T)item.Clone();
+ item.Freeze();
+ }
+ return item;
+ }
}
[Serializable]
diff --git a/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs b/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs
index 5e1f073eea..861b782ba5 100644
--- a/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs
+++ b/src/Libraries/SharpTreeView/ICSharpCode.TreeView/SharpTreeView.cs
@@ -240,16 +240,20 @@ namespace ICSharpCode.TreeView
break;
case Key.Return:
if (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node) {
+ e.Handled = true;
container.Node.ActivateItem(e);
}
break;
case Key.Space:
if (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node) {
- if(container.Node.IsCheckable) {
+ e.Handled = true;
+ if (container.Node.IsCheckable) {
if(container.Node.IsChecked == null) // If partially selected, we want to select everything
container.Node.IsChecked = true;
else
container.Node.IsChecked = !container.Node.IsChecked;
+ } else {
+ container.Node.ActivateItem(e);
}
}
break;
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/BaseTypesTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/BaseTypesTreeNode.cs
new file mode 100644
index 0000000000..16f060cba2
--- /dev/null
+++ b/src/Main/Base/Project/Dom/ClassBrowser/BaseTypesTreeNode.cs
@@ -0,0 +1,94 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using ICSharpCode.NRefactory.TypeSystem;
+
+namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
+{
+ ///
+ /// Description of BaseTypesTreeNode.
+ ///
+ public class BaseTypesTreeNode : ModelCollectionTreeNode
+ {
+ ITypeDefinitionModel definition;
+ string text;
+ SimpleModelCollection baseTypes;
+
+ public BaseTypesTreeNode(ITypeDefinitionModel definition)
+ {
+ if (definition == null)
+ throw new ArgumentNullException("definition");
+ this.definition = definition;
+ this.definition.Updated += (sender, e) => UpdateBaseTypes();
+ this.text = SD.ResourceService.GetString("MainWindow.Windows.ClassBrowser.BaseTypes");
+ baseTypes = new SimpleModelCollection();
+ UpdateBaseTypes();
+ }
+
+ protected override IModelCollection ModelChildren {
+ get {
+ return baseTypes;
+ }
+ }
+
+ public bool HasBaseTypes()
+ {
+ return baseTypes.Count > 0;
+ }
+
+ void UpdateBaseTypes()
+ {
+ baseTypes.Clear();
+ ITypeDefinition currentTypeDef = definition.Resolve();
+ if (currentTypeDef != null) {
+ foreach (var baseType in currentTypeDef.DirectBaseTypes) {
+ ITypeDefinition baseTypeDef = baseType.GetDefinition();
+ if (baseTypeDef != null) {
+ ITypeDefinitionModel baseTypeModel = GetTypeDefinitionModel(baseTypeDef);
+ if (baseTypeModel != null)
+ baseTypes.Add(baseTypeModel);
+ }
+ }
+ }
+ }
+
+ ITypeDefinitionModel GetTypeDefinitionModel(ITypeDefinition definition)
+ {
+ ITypeDefinitionModel model = definition.GetModel();
+ if (model == null) {
+ // Try to get model from ClassBrowser's assembly list
+ var classBrowser = SD.GetService();
+ if (classBrowser != null) {
+ foreach (var assemblyModel in classBrowser.MainAssemblyList.Assemblies) {
+ model = assemblyModel.TopLevelTypeDefinitions[definition.FullTypeName];
+ if (model != null) {
+ return model;
+ }
+ }
+ }
+ }
+
+ return model;
+ }
+
+ protected override System.Collections.Generic.IComparer NodeComparer {
+ get {
+ return NodeTextComparer;
+ }
+ }
+
+ public override object Text {
+ get {
+ return text;
+ }
+ }
+
+ public override object Icon {
+ get {
+ return SD.ResourceService.GetImageSource("Icons.16x16.OpenFolderBitmap");
+ }
+ }
+ }
+}
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs b/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
index 0a02246a14..792804a706 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
@@ -12,11 +12,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
#region IClassBrowser implementation
- public ICollection SpecialNodes {
- get { return ((WorkspaceTreeNode)Root).SpecialNodes; }
+ public ICollection AssemblyLists {
+ get { return ((WorkspaceTreeNode)Root).AssemblyLists; }
}
- public AssemblyList AssemblyList {
+ public IAssemblyList MainAssemblyList {
get { return ((WorkspaceTreeNode)Root).AssemblyList; }
set { ((WorkspaceTreeNode)Root).AssemblyList = value; }
}
@@ -27,11 +27,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
WorkspaceTreeNode root = new WorkspaceTreeNode();
ClassBrowserTreeView instance = this;
- root.SpecialNodes.CollectionChanged += delegate {
- instance.ShowRoot = root.Children.Count > 1;
+ root.AssemblyLists.CollectionChanged += delegate {
+ instance.ShowRoot = root.AssemblyLists.Count > 0;
};
root.PropertyChanged += delegate {
- instance.ShowRoot = root.Children.Count > 1;
+ instance.ShowRoot = root.AssemblyLists.Count > 0;
};
this.Root = root;
}
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs b/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
index 26a9d84436..b326dc5c02 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
@@ -9,19 +9,12 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public interface IClassBrowser
{
- ICollection SpecialNodes { get; }
- AssemblyList AssemblyList { get; set; }
- }
-
- public class AssemblyList
- {
- public string Name { get; set; }
- public IMutableModelCollection Assemblies { get; set; }
+ IAssemblyList MainAssemblyList { get; set; }
+ ICollection AssemblyLists { get; }
- public AssemblyList()
- {
- Name = "";
- Assemblies = new SimpleModelCollection();
- }
+ /*
+ IAssemblyList MainAssemblyList { get; set; }
+ ICollection AssemblyLists { get; }
+ */
}
}
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs
index 962d69e5db..de10610ebe 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs
@@ -12,11 +12,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
ISolution solution;
- public SolutionTreeNode(ISolution solution)
+ public SolutionTreeNode(ISolutionAssemblyList solutionAssemblyList)
{
- if (solution == null)
- throw new ArgumentNullException("solution");
- this.solution = solution;
+ if (solutionAssemblyList == null)
+ throw new ArgumentNullException("solutionAssemblyList");
+ this.solution = solutionAssemblyList.Solution;
}
protected override object GetModel()
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs
index aaab2f62ac..e53205281f 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs
@@ -22,6 +22,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
if (definition == null)
throw new ArgumentNullException("definition");
this.definition = definition;
+ this.definition.Updated += (sender, e) => UpdateBaseTypesNode();
}
protected override object GetModel()
@@ -54,6 +55,20 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
}
+ protected override void LoadChildren()
+ {
+ base.LoadChildren();
+ UpdateBaseTypesNode();
+ }
+
+ void UpdateBaseTypesNode()
+ {
+ this.Children.RemoveAll(n => n is BaseTypesTreeNode);
+ var baseTypesTreeNode = new BaseTypesTreeNode(definition);
+ if (baseTypesTreeNode.HasBaseTypes())
+ Children.Insert(0, baseTypesTreeNode);
+ }
+
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
var target = definition.Resolve();
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
index d093409f91..4f72478357 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
@@ -13,12 +13,12 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
///
public class WorkspaceModel : System.ComponentModel.INotifyPropertyChanged
{
- IMutableModelCollection specialNodes;
- public IMutableModelCollection SpecialNodes {
- get { return specialNodes; }
+ IMutableModelCollection assemblyLists;
+ public IMutableModelCollection AssemblyLists {
+ get { return assemblyLists; }
}
- AssemblyList assemblyList;
+ IAssemblyList mainAssemblyList;
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
@@ -29,13 +29,13 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
}
- public AssemblyList AssemblyList {
+ public IAssemblyList MainAssemblyList {
get {
- return assemblyList;
+ return mainAssemblyList;
}
set {
- if (assemblyList != value) {
- assemblyList = value;
+ if (mainAssemblyList != value) {
+ mainAssemblyList = value;
OnPropertyChanged();
}
}
@@ -43,8 +43,8 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public WorkspaceModel()
{
- this.specialNodes = new SimpleModelCollection();
- this.AssemblyList = new AssemblyList();
+ this.assemblyLists = new SimpleModelCollection();
+ this.MainAssemblyList = new AssemblyList();
}
}
}
diff --git a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
index 0a7117eb12..fd6e1c29ca 100644
--- a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
+++ b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
@@ -26,7 +24,13 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
if (!(x is SolutionTreeNode) && (y is SolutionTreeNode))
return 1;
- // Both nodes are solutions or not solutions, compare their Text property
+ // AssemblyTreeNodes (no derived node classes!) appear at the bottom of list
+ if ((x.GetType() == typeof(AssemblyTreeNode)) && (y.GetType() != typeof(AssemblyTreeNode)))
+ return 1;
+ if ((x.GetType() != typeof(AssemblyTreeNode)) && (y.GetType() == typeof(AssemblyTreeNode)))
+ return -1;
+
+ // All other nodes are compared by their Text property
return stringComparer.Compare(x.Text.ToString(), y.Text.ToString());
}
}
@@ -34,19 +38,19 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
WorkspaceModel workspace;
protected static readonly IComparer ChildNodeComparer = new WorkspaceChildComparer();
- public IMutableModelCollection SpecialNodes {
- get { return workspace.SpecialNodes; }
+ public IMutableModelCollection AssemblyLists {
+ get { return workspace.AssemblyLists; }
}
- public AssemblyList AssemblyList {
- get { return workspace.AssemblyList; }
- set { workspace.AssemblyList = value; }
+ public IAssemblyList AssemblyList {
+ get { return workspace.MainAssemblyList; }
+ set { workspace.MainAssemblyList = value; }
}
public WorkspaceTreeNode()
{
this.workspace = new WorkspaceModel();
- this.workspace.SpecialNodes.CollectionChanged += SpecialNodesModelCollectionChanged;
+ this.workspace.AssemblyLists.CollectionChanged += AssemblyListsCollectionChanged;
}
protected override object GetModel()
@@ -55,7 +59,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
protected override IModelCollection ModelChildren {
- get { return workspace.AssemblyList.Assemblies; }
+ get { return workspace.MainAssemblyList.Assemblies; }
}
protected override IComparer NodeComparer {
@@ -64,7 +68,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public override object Text {
get {
- return "Workspace " + AssemblyList.Name;
+ return String.Format(SD.ResourceService.GetString("MainWindow.Windows.ClassBrowser.Workspace"), AssemblyList.Name);
}
}
@@ -81,12 +85,14 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
protected override void InsertSpecialNodes()
{
- foreach (var node in workspace.SpecialNodes) {
- Children.OrderedInsert(node, ChildNodeComparer);
+ foreach (var assemblyList in workspace.AssemblyLists) {
+ var treeNode = SD.TreeNodeFactory.CreateTreeNode(assemblyList);
+ if (treeNode != null)
+ Children.OrderedInsert(treeNode, ChildNodeComparer);
}
}
- void SpecialNodesModelCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems)
+ void AssemblyListsCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems)
{
SynchronizeModelChildren();
}
diff --git a/src/Main/Base/Project/Dom/IAssemblyList.cs b/src/Main/Base/Project/Dom/IAssemblyList.cs
new file mode 100644
index 0000000000..fc3a3194bc
--- /dev/null
+++ b/src/Main/Base/Project/Dom/IAssemblyList.cs
@@ -0,0 +1,28 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+
+namespace ICSharpCode.SharpDevelop.Dom
+{
+ ///
+ /// Base interface for assembly list implementations.
+ ///
+ public interface IAssemblyList
+ {
+ string Name { get; set; }
+ IMutableModelCollection Assemblies { get; set; }
+ }
+
+ public class AssemblyList : IAssemblyList
+ {
+ public string Name { get; set; }
+ public IMutableModelCollection Assemblies { get; set; }
+
+ public AssemblyList()
+ {
+ Name = "";
+ Assemblies = new NullSafeSimpleModelCollection();
+ }
+ }
+}
diff --git a/src/Main/Base/Project/Dom/IAssemblyModel.cs b/src/Main/Base/Project/Dom/IAssemblyModel.cs
index 29f32dd122..bc0558230b 100644
--- a/src/Main/Base/Project/Dom/IAssemblyModel.cs
+++ b/src/Main/Base/Project/Dom/IAssemblyModel.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Parser;
@@ -50,6 +51,11 @@ namespace ICSharpCode.SharpDevelop.Dom
///
IEntityModelContext Context { get; }
+ ///
+ /// Returns the location of the assembly represented by this model.
+ ///
+ FileName Location { get; }
+
///
/// Returns the assembly references.
///
@@ -111,6 +117,12 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
+ public FileName Location {
+ get {
+ return null;
+ }
+ }
+
public IReadOnlyList References {
get { return EmptyList.Instance; }
}
diff --git a/src/Main/Base/Project/Dom/IModelCollection.cs b/src/Main/Base/Project/Dom/IModelCollection.cs
index efde573e4b..7c6f5ece7a 100644
--- a/src/Main/Base/Project/Dom/IModelCollection.cs
+++ b/src/Main/Base/Project/Dom/IModelCollection.cs
@@ -7,45 +7,6 @@ using System.Linq;
namespace ICSharpCode.SharpDevelop.Dom
{
- ///
- /// Event handler for the event.
- ///
- ///
- /// We don't use the classic 'EventArgs' model for this event, because a EventArgs-class couldn't be covariant.
- ///
- public delegate void ModelCollectionChangedEventHandler(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems);
-
- public class ModelCollectionChangedEvent
- {
- List> _handlers = new List>();
-
- public void AddHandler(ModelCollectionChangedEventHandler handler)
- {
- _handlers.Add(handler);
- }
-
- public void RemoveHandler(ModelCollectionChangedEventHandler handler)
- {
- _handlers.Remove(handler);
- }
-
- public void Fire(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems)
- {
- foreach (var handler in _handlers) {
- if (handler != null) {
- handler(removedItems, addedItems);
- }
- }
- }
-
- public bool ContainsHandlers
- {
- get {
- return _handlers.Count > 0;
- }
- }
- }
-
///
/// A read-only collection that provides change notifications.
///
diff --git a/src/Main/Base/Project/Dom/ISolutionAssemblyList.cs b/src/Main/Base/Project/Dom/ISolutionAssemblyList.cs
new file mode 100644
index 0000000000..4ff2750491
--- /dev/null
+++ b/src/Main/Base/Project/Dom/ISolutionAssemblyList.cs
@@ -0,0 +1,19 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Project;
+
+namespace ICSharpCode.SharpDevelop.Dom
+{
+ ///
+ /// Represents a solution assembly list.
+ ///
+ public interface ISolutionAssemblyList : IAssemblyList
+ {
+ ///
+ /// Returns the instance behind this assembly list.
+ ///
+ ISolution Solution { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Main/Base/Project/Dom/ITypeDefinitionModel.cs b/src/Main/Base/Project/Dom/ITypeDefinitionModel.cs
index 62934f4576..795bde6c4a 100644
--- a/src/Main/Base/Project/Dom/ITypeDefinitionModel.cs
+++ b/src/Main/Base/Project/Dom/ITypeDefinitionModel.cs
@@ -13,6 +13,8 @@ namespace ICSharpCode.SharpDevelop.Dom
///
public interface ITypeDefinitionModel : IEntityModel
{
+ event EventHandler Updated;
+
FullTypeName FullTypeName { get; }
string Namespace { get; }
TypeKind TypeKind { get; }
diff --git a/src/Main/Base/Project/Dom/ModelCollectionChangedEvent.cs b/src/Main/Base/Project/Dom/ModelCollectionChangedEvent.cs
new file mode 100644
index 0000000000..686330d4e3
--- /dev/null
+++ b/src/Main/Base/Project/Dom/ModelCollectionChangedEvent.cs
@@ -0,0 +1,52 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+namespace ICSharpCode.SharpDevelop.Dom
+{
+ ///
+ /// Event handler for the event.
+ ///
+ ///
+ /// We don't use the classic 'EventArgs' model for this event, because a EventArgs-class couldn't be covariant.
+ ///
+ public delegate void ModelCollectionChangedEventHandler(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems);
+
+ ///
+ /// Helper class for implementations.
+ /// This is necessary because Delegate.Combine does not work with
+ /// co-/contravariant delegates.
+ ///
+ public class ModelCollectionChangedEvent
+ {
+ List> _handlers = new List>();
+
+ public void AddHandler(ModelCollectionChangedEventHandler handler)
+ {
+ if (handler != null)
+ _handlers.Add(handler);
+ }
+
+ public void RemoveHandler(ModelCollectionChangedEventHandler handler)
+ {
+ _handlers.Remove(handler);
+ }
+
+ public void Fire(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems)
+ {
+ foreach (var handler in _handlers.ToArray()) {
+ handler(removedItems, addedItems);
+ }
+ }
+
+ public bool ContainsHandlers {
+ get {
+ return _handlers.Count > 0;
+ }
+ }
+ }
+}
+
+
diff --git a/src/Main/Base/Project/Dom/SimpleModelCollection.cs b/src/Main/Base/Project/Dom/SimpleModelCollection.cs
index b91b83193c..90843c1f43 100644
--- a/src/Main/Base/Project/Dom/SimpleModelCollection.cs
+++ b/src/Main/Base/Project/Dom/SimpleModelCollection.cs
@@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom
///
public class SimpleModelCollection : IMutableModelCollection
{
- readonly ModelCollectionChangedEvent collectionChangedEvent;
+ readonly ModelCollectionChangedEvent collectionChangedEvent = new ModelCollectionChangedEvent();
readonly List list;
List addedItems;
List removedItems;
@@ -24,13 +24,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public SimpleModelCollection()
{
this.list = new List();
- collectionChangedEvent = new ModelCollectionChangedEvent();
}
public SimpleModelCollection(IEnumerable items)
{
this.list = new List(items);
- collectionChangedEvent = new ModelCollectionChangedEvent();
+ // Note: intentionally not using ValidateItem(), as calling a virtual method
+ // from a constructor is problematic
}
protected void CheckReentrancy()
@@ -39,6 +39,9 @@ namespace ICSharpCode.SharpDevelop.Dom
throw new InvalidOperationException("Cannot modify the collection from within the CollectionChanged event.");
}
+ ///
+ /// Called before an item
+ ///
protected virtual void ValidateItem(T item)
{
}
@@ -182,15 +185,20 @@ namespace ICSharpCode.SharpDevelop.Dom
if (items == null)
throw new ArgumentNullException("items");
CheckReentrancy();
- List itemsList = items.ToList();
- for (int i = 0; i < itemsList.Count; i++) {
- ValidateItem(itemsList[i]);
- }
- for (int i = 0; i < itemsList.Count; i++) {
- OnAdd(itemsList[i]);
+ try {
+ foreach (T item in items) {
+ // Add each item before validating the next,
+ // this is necessary because ValidateItem() might be checking
+ // for duplicates (e.g. KeyedModelCollection<,>)
+ ValidateItem(item);
+ OnAdd(item);
+ list.Add(item);
+ }
+ } finally {
+ // In case validation fails, we still need to raise the event
+ // for the items that were added successfully.
+ RaiseEventIfNotInBatch();
}
- list.AddRange(itemsList);
- RaiseEventIfNotInBatch();
}
public bool Remove(T item)
diff --git a/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs b/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs
index 241cba35de..367796a09e 100644
--- a/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs
+++ b/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs
@@ -31,10 +31,17 @@ namespace ICSharpCode.SharpDevelop.Dom
this.syncRoot = syncRoot;
}
- // Event registration is thread-safe on the underlying collection
public event ModelCollectionChangedEventHandler CollectionChanged {
- add { underlyingCollection.CollectionChanged += value; }
- remove { underlyingCollection.CollectionChanged -= value; }
+ add {
+ lock (syncRoot) {
+ underlyingCollection.CollectionChanged += value;
+ }
+ }
+ remove {
+ lock (syncRoot) {
+ underlyingCollection.CollectionChanged -= value;
+ }
+ }
}
#region IMutableModelCollection implementation
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionViewModel.cs b/src/Main/Base/Project/Editor/ContextActions/ContextActionViewModel.cs
similarity index 94%
rename from src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionViewModel.cs
rename to src/Main/Base/Project/Editor/ContextActions/ContextActionViewModel.cs
index c26e0fe8df..a7248352db 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionViewModel.cs
+++ b/src/Main/Base/Project/Editor/ContextActions/ContextActionViewModel.cs
@@ -6,13 +6,12 @@ using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media;
-using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Refactoring;
-namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
+namespace ICSharpCode.SharpDevelop.Editor.ContextActions
{
///
- /// Description of ContextActionViewModel.
+ /// ViewModel for a .
///
public class ContextActionViewModel
{
@@ -95,4 +94,4 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
return true;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsViewModel.cs b/src/Main/Base/Project/Editor/ContextActions/ContextActionsPopupViewModel.cs
similarity index 76%
rename from src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsViewModel.cs
rename to src/Main/Base/Project/Editor/ContextActions/ContextActionsPopupViewModel.cs
index 55de265154..d40033e20f 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsViewModel.cs
+++ b/src/Main/Base/Project/Editor/ContextActions/ContextActionsPopupViewModel.cs
@@ -5,12 +5,12 @@ using System;
using System.Collections.ObjectModel;
using System.Windows.Media;
-namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
+namespace ICSharpCode.SharpDevelop.Editor.ContextActions
{
///
- /// Description of ContextActionsViewModel.
+ /// ViewModel for a ContextActionsPopup.
///
- public class ContextActionsViewModel
+ public class ContextActionsPopupViewModel
{
public ImageSource Image { get; set; }
@@ -18,4 +18,4 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
public ObservableCollection Actions { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/src/Main/Base/Project/Editor/IEditorUIService.cs b/src/Main/Base/Project/Editor/IEditorUIService.cs
index 4bc521dd35..e1a9c9d647 100644
--- a/src/Main/Base/Project/Editor/IEditorUIService.cs
+++ b/src/Main/Base/Project/Editor/IEditorUIService.cs
@@ -2,9 +2,14 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.SharpDevelop.Editor.ContextActions;
+using ICSharpCode.SharpDevelop.Refactoring;
namespace ICSharpCode.SharpDevelop.Editor
{
@@ -17,6 +22,11 @@ namespace ICSharpCode.SharpDevelop.Editor
/// Gets the absolute screen position of given position in the document.
///
Point GetScreenPosition(int line, int column);
+
+ ///
+ /// Shows a ContextActionsPopup created from a ViewModel.
+ ///
+ void ShowContextActionsPopup(ContextActionsPopupViewModel viewModel);
}
public interface IInlineUIElement
diff --git a/src/Main/Base/Project/Editor/Search/SearchResultMatch.cs b/src/Main/Base/Project/Editor/Search/SearchResultMatch.cs
index 0be9711c2a..97d37498c9 100644
--- a/src/Main/Base/Project/Editor/Search/SearchResultMatch.cs
+++ b/src/Main/Base/Project/Editor/Search/SearchResultMatch.cs
@@ -22,7 +22,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
int length;
TextLocation startLocation;
TextLocation endLocation;
- HighlightedInlineBuilder builder;
+ RichText displayText;
HighlightingColor defaultTextColor;
public FileName FileName {
@@ -37,10 +37,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
get { return endLocation; }
}
- public HighlightedInlineBuilder Builder {
- get { return builder; }
- }
-
public HighlightingColor DefaultTextColor {
get { return defaultTextColor; }
}
@@ -62,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
return pattern;
}
- public SearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, HighlightedInlineBuilder builder, HighlightingColor defaultTextColor)
+ public SearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, RichText displayText, HighlightingColor defaultTextColor)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
@@ -71,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
this.endLocation = endLocation;
this.offset = offset;
this.length = length;
- this.builder = builder;
+ this.displayText = displayText;
this.defaultTextColor = defaultTextColor;
}
@@ -90,9 +86,9 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
///
/// Gets a special text to display, or null to display the line's content.
///
- public virtual string DisplayText {
+ public RichText DisplayText {
get {
- return null;
+ return displayText;
}
}
@@ -104,29 +100,12 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
}
}
- public class SimpleSearchResultMatch : SearchResultMatch
- {
- string displayText;
-
- public override string DisplayText {
- get {
- return displayText;
- }
- }
-
- public SimpleSearchResultMatch(FileName fileName, TextLocation position, int offset, string displayText)
- : base(fileName, position, position, offset, 0, null, null)
- {
- this.displayText = displayText;
- }
- }
-
public class AvalonEditSearchResultMatch : SearchResultMatch
{
ICSharpCode.AvalonEdit.Search.ISearchResult match;
- public AvalonEditSearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, HighlightedInlineBuilder builder, HighlightingColor defaultTextColor, ICSharpCode.AvalonEdit.Search.ISearchResult match)
- : base(fileName, startLocation, endLocation, offset, length, builder, defaultTextColor)
+ public AvalonEditSearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, RichText richText, HighlightingColor defaultTextColor, ICSharpCode.AvalonEdit.Search.ISearchResult match)
+ : base(fileName, startLocation, endLocation, offset, length, richText, defaultTextColor)
{
this.match = match;
}
diff --git a/src/Main/Base/Project/Editor/Search/SearchResultsPad.cs b/src/Main/Base/Project/Editor/Search/SearchResultsPad.cs
index e76007b65f..59c2002fee 100644
--- a/src/Main/Base/Project/Editor/Search/SearchResultsPad.cs
+++ b/src/Main/Base/Project/Editor/Search/SearchResultsPad.cs
@@ -149,24 +149,26 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
return new DummySearchResult { Text = title };
}
- public static HighlightedInlineBuilder CreateInlineBuilder(TextLocation startPosition, TextLocation endPosition, IDocument document, IHighlighter highlighter)
+ public static RichText CreateInlineBuilder(TextLocation startPosition, TextLocation endPosition, IDocument document, IHighlighter highlighter)
{
if (startPosition.Line >= 1 && startPosition.Line <= document.LineCount) {
- var inlineBuilder = highlighter.HighlightLine(startPosition.Line).ToInlineBuilder();
+ var highlightedLine = highlighter.HighlightLine(startPosition.Line);
+ var documentLine = highlightedLine.DocumentLine;
+ var inlineBuilder = highlightedLine.ToRichTextModel();
// reset bold/italics
- inlineBuilder.SetFontWeight(0, inlineBuilder.Text.Length, FontWeights.Normal);
- inlineBuilder.SetFontStyle(0, inlineBuilder.Text.Length, FontStyles.Normal);
+ inlineBuilder.SetFontWeight(0, documentLine.Length, FontWeights.Normal);
+ inlineBuilder.SetFontStyle(0, documentLine.Length, FontStyles.Normal);
// now highlight the match in bold
if (startPosition.Column >= 1) {
if (endPosition.Line == startPosition.Line && endPosition.Column > startPosition.Column) {
// subtract one from the column to get the offset inside the line's text
int startOffset = startPosition.Column - 1;
- int endOffset = Math.Min(inlineBuilder.Text.Length, endPosition.Column - 1);
+ int endOffset = Math.Min(documentLine.Length, endPosition.Column - 1);
inlineBuilder.SetFontWeight(startOffset, endOffset - startOffset, FontWeights.Bold);
}
}
- return inlineBuilder;
+ return new RichText(document.GetText(documentLine), inlineBuilder);
}
return null;
}
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
index 71e40ca34e..cdd9bf4c90 100755
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
@@ -165,11 +165,12 @@
class = "ICSharpCode.SharpDevelop.Gui.TaskListPad"
defaultPosition = "Bottom" />
-
+ tooltip = "${res:MainWindow.Windows.ClassBrowser.OpenAssemblyButton.ToolTip}">