diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/FileSystem/Commands.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Editors/FileSystem/Commands.uexml
index 72ed3914..799f1240 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Editors/FileSystem/Commands.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/FileSystem/Commands.uexml
@@ -49,7 +49,7 @@
-
+
@@ -149,6 +149,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Synthesized/MenuBar.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Synthesized/MenuBar.uexml
index a3a84a4a..669bafe1 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Synthesized/MenuBar.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Synthesized/MenuBar.uexml
@@ -74,8 +74,6 @@
-
-
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Waveform/Commands.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Waveform/Commands.uexml
index 3d071c64..db27dc7b 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Waveform/Commands.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/Audio/Waveform/Commands.uexml
@@ -3,25 +3,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.png b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.png
new file mode 100644
index 00000000..6f430f81
Binary files /dev/null and b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.png differ
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.svg b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.svg
new file mode 100644
index 00000000..b03a6dd1
--- /dev/null
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/cube.svg
@@ -0,0 +1,105 @@
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.png b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.png
new file mode 100644
index 00000000..c35485d6
Binary files /dev/null and b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.png differ
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.svg b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.svg
new file mode 100644
index 00000000..3419275a
--- /dev/null
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia3D/Model/Icons/sphere.svg
@@ -0,0 +1,78 @@
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Multimedia3D/Languages/English.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Multimedia3D/Languages/English.uexml
new file mode 100644
index 00000000..53ab99db
--- /dev/null
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Multimedia3D/Languages/English.uexml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index 8957004f..69474d60 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -326,6 +326,9 @@
+
+
+
@@ -363,6 +366,8 @@
+
+
@@ -373,6 +378,8 @@
+
+
diff --git a/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/CommonXMLSchemas.cs b/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/CommonXMLSchemas.cs
new file mode 100644
index 00000000..773bbb42
--- /dev/null
+++ b/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/CommonXMLSchemas.cs
@@ -0,0 +1,62 @@
+//
+// XMLSchemas.cs - provides common XML schema definitions used in a wide variety of applications
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2021 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.DataFormats.Markup.XML
+{
+ ///
+ /// Provides common XML schema definitions used in a wide variety of applications.
+ ///
+ public static class CommonXMLSchemas
+ {
+ ///
+ /// The /elements/1.1/ namespace was created in 2000 for the RDF representation of the fifteen-element
+ /// Dublin Core and has been widely used in data for more than twenty years. This namespace corresponds
+ /// to the original scope of ISO 15836, which was published first in 2003 and last revised in 2017 as
+ /// ISO 15836-1:2017.
+ ///
+ /// The XML schema for the original Dublin Core namespace.
+ public static string DublinCore { get; } = "http://purl.org/dc/elements/1.1/";
+ ///
+ /// The /terms/ namespace was originally created in 2001 for identifying new terms coined outside of the
+ /// original fifteen-element Dublin Core. In 2008, in the context of defining formal semantic constraints
+ /// for DCMI metadata terms in support of RDF applications, the original fifteen elements themselves were
+ /// mirrored in the /terms/ namespace. As a result, there exists both a dc:date (http://purl.org/dc/elements/1.1/date)
+ /// with no formal range and a corresponding dcterms:date (http://purl.org/dc/terms/date) with a formal
+ /// range of "literal". While these distinctions are significant for creators of RDF applications, most users
+ /// can safely treat the fifteen parallel properties as equivalent. The most useful properties and classes of
+ /// DCMI Metadata Terms have now been published as ISO 15836-2:2019 [ISO 15836-2:2019]. While the /elements/1.1/
+ /// namespace will be supported indefinitely, DCMI gently encourages use of the /terms/ namespace.
+ ///
+ /// The XML schema for the Dublin Core Terms namespace.
+ public static string DublinCoreTerms { get; } = "http://purl.org/dc/terms/";
+ ///
+ /// The /dcmitype/ namespace was created in 2001 for the DCMI Type Vocabulary, which defines classes for
+ /// basic types of thing that can be described using DCMI metadata terms.
+ ///
+ /// The XML schema for the Dublin Core DCMI Type namespace.
+ public static string DublinCoreDCMIType { get; } = "http://purl.org/dc/dcmitype/";
+ ///
+ /// The /dcam/ namespace was created in 2008 for terms used in the description of DCMI metadata terms.
+ ///
+ /// The XML schema for the Dublin Core DCAM namespace.
+ public static string DublinCoreDCAM { get; } = "http://purl.org/dc/dcam/";
+ }
+}
diff --git a/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs b/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs
index d4c1964b..e1720aa6 100644
--- a/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs
+++ b/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs
@@ -21,7 +21,7 @@
using System;
using System.Collections.Generic;
-
+using System.Text;
using UniversalEditor.ObjectModels.Markup;
using UniversalEditor.ObjectModels.PropertyList;
@@ -116,7 +116,7 @@ namespace UniversalEditor.DataFormats.Markup.XML
if (element is MarkupTagElement)
{
MarkupTagElement tag = element as MarkupTagElement;
- tw.Write(indent + Settings.TagBeginChar.ToString() + element.FullName);
+ tw.Write(indent + Settings.TagBeginChar.ToString() + GetFullName(element));
if (tag.Attributes.Count > 0)
{
tw.Write(" ");
@@ -199,6 +199,40 @@ namespace UniversalEditor.DataFormats.Markup.XML
}
}
}
+
+ private string GetFullName(MarkupElement element)
+ {
+ if (element is MarkupTagElement)
+ {
+ if ((element as MarkupTagElement).XMLSchema != null)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(GetPrefixForXMLSchema(element.ParentObjectModel, (element as MarkupTagElement).XMLSchema));
+ sb.Append(':');
+ sb.Append(element.Name);
+ return sb.ToString();
+ }
+ }
+ return element.FullName;
+ }
+
+ private string GetPrefixForXMLSchema(MarkupObjectModel mom, string xmlSchema)
+ {
+ foreach (MarkupElement el in mom.Elements)
+ {
+ if (el is MarkupTagElement)
+ {
+ foreach (MarkupAttribute att in (el as MarkupTagElement).Attributes)
+ {
+ if (att.Namespace == "xmlns" && att.Value == xmlSchema)
+ return att.Name;
+ }
+ break;
+ }
+ }
+ throw new InvalidOperationException(String.Format("xml prefix not found for schema '{0}'", xmlSchema));
+ }
+
public void WriteStartDocument()
{
this.WriteStartPreprocessor("xml");
diff --git a/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupContainerElement.cs b/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupContainerElement.cs
index 0d142c5f..19b12a4b 100644
--- a/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupContainerElement.cs
+++ b/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupContainerElement.cs
@@ -83,10 +83,14 @@ namespace UniversalEditor.ObjectModels.Markup
return basetag;
}
+ private string _XMLSchema = null;
public string XMLSchema
{
get
{
+ if (_XMLSchema != null)
+ return _XMLSchema;
+
if (this.Namespace == null)
return null;
@@ -103,6 +107,33 @@ namespace UniversalEditor.ObjectModels.Markup
return null;
}
+ set
+ {
+ if (this.ParentObjectModel == null)
+ {
+ _XMLSchema = value;
+ return;
+ }
+
+ for (int i = 0; i < this.ParentObjectModel.Elements.Count; i++)
+ {
+ MarkupTagElement tagTopLevel = (this.ParentObjectModel.Elements[i] as MarkupTagElement);
+ if (tagTopLevel == null)
+ continue;
+
+ foreach (MarkupAttribute att in tagTopLevel.Attributes)
+ {
+ if (att.Namespace == "xmlns")
+ {
+ if (att.Value == value)
+ {
+ Namespace = att.Name;
+ break;
+ }
+ }
+ }
+ }
+ }
}
protected override void UpdateParentObjectModel()
diff --git a/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupTagElement.cs b/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupTagElement.cs
index dd84d596..f939b80e 100644
--- a/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupTagElement.cs
+++ b/Libraries/UniversalEditor.Essential/ObjectModels/Markup/MarkupTagElement.cs
@@ -29,6 +29,21 @@ namespace UniversalEditor.ObjectModels.Markup
///
public class MarkupTagElement : MarkupContainerElement
{
+ public MarkupTagElement()
+ {
+ }
+ public MarkupTagElement(string fullName, string innerMarkup)
+ {
+ FullName = fullName;
+ Value = innerMarkup;
+ }
+ public MarkupTagElement(string schema, string name, string innerMarkup)
+ {
+ XMLSchema = schema;
+ Name = name;
+ Value = innerMarkup;
+ }
+
///
/// Combines the attributes and child elements of this with the given .
///
diff --git a/Libraries/UniversalEditor.Essential/ObjectModels/PropertyList/PropertyListObjectModel.cs b/Libraries/UniversalEditor.Essential/ObjectModels/PropertyList/PropertyListObjectModel.cs
index 5b2935f8..bdd6ff9f 100644
--- a/Libraries/UniversalEditor.Essential/ObjectModels/PropertyList/PropertyListObjectModel.cs
+++ b/Libraries/UniversalEditor.Essential/ObjectModels/PropertyList/PropertyListObjectModel.cs
@@ -46,11 +46,41 @@ namespace UniversalEditor.ObjectModels.PropertyList
}
public override void CopyTo(ObjectModel objectModel)
{
- PropertyListObjectModel omb = objectModel as PropertyListObjectModel;
- if (omb == null) throw new ObjectModelNotSupportedException();
+ PropertyListObjectModel clone = objectModel as PropertyListObjectModel;
+ if (clone == null) throw new ObjectModelNotSupportedException();
- // omb.Combine(this);
+ Combine(clone);
}
+
+ public void Combine(PropertyListObjectModel clone)
+ {
+ foreach (PropertyListItem item in Items)
+ {
+ if (item is Property)
+ {
+ if (clone.Items.Contains(item.Name) && clone.Items[item.Name] is Property)
+ {
+ (clone.Items[item.Name] as Property).Value = (item as Property).Value;
+ }
+ else
+ {
+ clone.Items.Add(((Property)item).Clone() as Property);
+ }
+ }
+ else if (item is Group)
+ {
+ if (clone.Items.Contains(item.Name) && clone.Items[item.Name] is Group)
+ {
+ (clone.Items[item.Name] as Group).Combine(item as Group);
+ }
+ else
+ {
+ clone.Items.Add(((Group)item).Clone() as Group);
+ }
+ }
+ }
+ }
+
public T GetValue(string propertyName)
{
return this.GetValue(new string[]
diff --git a/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj b/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj
index 575fa508..da6d2b1e 100644
--- a/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj
+++ b/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj
@@ -217,6 +217,7 @@
+
diff --git a/Libraries/UniversalEditor.UserInterface/Common/Reflection.cs b/Libraries/UniversalEditor.UserInterface/Common/Reflection.cs
index ec94f3f7..59eb0354 100644
--- a/Libraries/UniversalEditor.UserInterface/Common/Reflection.cs
+++ b/Libraries/UniversalEditor.UserInterface/Common/Reflection.cs
@@ -296,6 +296,20 @@ namespace UniversalEditor.UserInterface.Common
er.Variables.Add(varr);
}
}
+
+
+ MarkupTagElement tagCommandBars = (tagEditor.Elements["CommandBars"] as MarkupTagElement);
+ if (tagCommandBars != null)
+ {
+ foreach (MarkupElement elCommandBar in tagCommandBars.Elements)
+ {
+ CommandBar cb = CommandBarLoader.LoadCommandBarXML(elCommandBar as MarkupTagElement);
+ if (cb != null)
+ {
+ er.CommandBars.Add(cb);
+ }
+ }
+ }
}
}
}
diff --git a/Libraries/UniversalEditor.UserInterface/EditorApplication.cs b/Libraries/UniversalEditor.UserInterface/EditorApplication.cs
index 406bf2d3..d56b02dc 100644
--- a/Libraries/UniversalEditor.UserInterface/EditorApplication.cs
+++ b/Libraries/UniversalEditor.UserInterface/EditorApplication.cs
@@ -829,30 +829,13 @@ namespace UniversalEditor.UserInterface
Editor ed = LastWindow.GetCurrentEditor();
if (ed == null) return;
- Accessor acc = ed.ObjectModel?.Accessor ?? (ed.Parent as Pages.EditorPage)?.Document?.Accessor;
-
- // we cannot yet bookmark a file that does not yet exist. (this would be akin to creating a shortcut to a template I guess...?)
- if (acc == null) return;
-
- // FIXME: BookmarksAdd copypasta
- string filename = acc.GetFileName();
- BookmarksManager.FileNames.Add(filename);
-
- Command cmdBookmarks = Application.Instance.Commands["Bookmarks"];
- if (cmdBookmarks.Items.Count == 4)
- {
- cmdBookmarks.Items.Add(new SeparatorCommandItem());
- }
-
- ((UIApplication)Application.Instance).Commands.Add(new Command(String.Format("{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1).ToString()), System.IO.Path.GetFileName(((EditorApplication)Application.Instance).BookmarksManager.FileNames[(BookmarksManager.FileNames.Count - 1)])));
- ((UIApplication)Application.Instance).Commands["Bookmarks"].Items.Add(new CommandReferenceCommandItem(String.Format("Bookmarks_Bookmark{0}", (BookmarksManager.FileNames.Count - 1).ToString())));
-
- Application.Instance.AttachCommandEventHandler(String.Format("Bookmarks_Bookmark{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1).ToString()), Bookmarks_Bookmark_Click);
+ AddBookmark(ed.ObjectModel?.Accessor ?? (ed.Parent as Pages.EditorPage)?.Document?.Accessor);
ShowBookmarksManagerDialog();
});
Application.Instance.AttachCommandEventHandler("BookmarksAddAll", delegate (object sender, EventArgs e)
{
Page[] pages = LastWindow.GetPages();
+
for (int i = 0; i < pages.Length; i++)
{
if (pages[i] is Pages.EditorPage)
@@ -860,20 +843,7 @@ namespace UniversalEditor.UserInterface
Pages.EditorPage ep = (pages[i] as Pages.EditorPage);
Editor ed = (ep.Controls[0] as Editor);
- // FIXME: BookmarksAdd copypasta
- string filename = ed.ObjectModel.Accessor.GetFileName();
- BookmarksManager.FileNames.Add(filename);
-
- Command cmdBookmarks = ((UIApplication)Application.Instance).Commands["Bookmarks"];
- if (cmdBookmarks.Items.Count == 4)
- {
- cmdBookmarks.Items.Add(new SeparatorCommandItem());
- }
-
- Application.Instance.Commands.Add(new Command(String.Format("Bookmarks_Bookmark{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1)), System.IO.Path.GetFileName(((EditorApplication)Application.Instance).BookmarksManager.FileNames[(BookmarksManager.FileNames.Count - 1)])));
- Application.Instance.Commands["Bookmarks"].Items.Add(new CommandReferenceCommandItem(String.Format("Bookmarks_Bookmark{0}", ((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1)));
-
- Application.Instance.AttachCommandEventHandler(String.Format("Bookmarks_Bookmark{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1).ToString()), Bookmarks_Bookmark_Click);
+ AddBookmark(ed.ObjectModel?.Accessor ?? (ed.Parent as Pages.EditorPage)?.Document?.Accessor);
}
}
@@ -1029,6 +999,32 @@ namespace UniversalEditor.UserInterface
#endregion
}
+ ///
+ /// Adds a bookmark referencing the specified to the application's bookmarks menu.
+ ///
+ /// true, if bookmark was added, false otherwise.
+ /// The referencing the bookmark to add.
+ public bool AddBookmark(Accessor accessor)
+ {
+ // we cannot yet bookmark a file that does not yet exist. (this would be akin to creating a shortcut to a template I guess...?)
+ if (accessor == null) return false;
+
+ string filename = accessor.GetFileName();
+ BookmarksManager.FileNames.Add(filename);
+
+ Command cmdBookmarks = Application.Instance.Commands["Bookmarks"];
+ if (cmdBookmarks.Items.Count == 4)
+ {
+ cmdBookmarks.Items.Add(new SeparatorCommandItem());
+ }
+
+ ((UIApplication)Application.Instance).Commands.Add(new Command(String.Format("{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1).ToString()), System.IO.Path.GetFileName(((EditorApplication)Application.Instance).BookmarksManager.FileNames[(BookmarksManager.FileNames.Count - 1)])));
+ ((UIApplication)Application.Instance).Commands["Bookmarks"].Items.Add(new CommandReferenceCommandItem(String.Format("Bookmarks_Bookmark{0}", (BookmarksManager.FileNames.Count - 1).ToString())));
+
+ Application.Instance.AttachCommandEventHandler(String.Format("Bookmarks_Bookmark{0}", (((EditorApplication)Application.Instance).BookmarksManager.FileNames.Count - 1).ToString()), Bookmarks_Bookmark_Click);
+ return true;
+ }
+
void Td_HyperlinkClicked(object sender, TaskDialogHyperlinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("https://www.gnu.org/licenses/gpl-3.0.en.html");
diff --git a/Libraries/UniversalEditor.UserInterface/EditorContext.cs b/Libraries/UniversalEditor.UserInterface/EditorContext.cs
index 266231c8..086b7a2c 100644
--- a/Libraries/UniversalEditor.UserInterface/EditorContext.cs
+++ b/Libraries/UniversalEditor.UserInterface/EditorContext.cs
@@ -45,6 +45,10 @@ namespace UniversalEditor.UserInterface
{
Commands.Add(reference.Commands[i]);
}
+ for (int i = 0; i < reference.CommandBars.Count; i++)
+ {
+ CommandBars.Add(reference.CommandBars[i]);
+ }
for (int i = 0; i < reference.MenuBar.Items.Count; i++)
{
MenuItems.Add(reference.MenuBar.Items[i]);
diff --git a/Libraries/UniversalEditor.UserInterface/EditorReference.cs b/Libraries/UniversalEditor.UserInterface/EditorReference.cs
index 29a31aed..fe9b2f1b 100644
--- a/Libraries/UniversalEditor.UserInterface/EditorReference.cs
+++ b/Libraries/UniversalEditor.UserInterface/EditorReference.cs
@@ -30,6 +30,7 @@ namespace UniversalEditor.UserInterface
public MarkupTagElement Configuration { get; set; } = null;
public CommandBar MenuBar { get; } = new CommandBar();
+ public CommandBar.CommandBarCollection CommandBars { get; } = new CommandBar.CommandBarCollection();
public Command.CommandCollection Commands { get; } = new Command.CommandCollection();
public PanelReference.PanelReferenceCollection Panels { get; } = new PanelReference.PanelReferenceCollection();
public EditorView.EditorViewCollection Views { get; } = new EditorView.EditorViewCollection();
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.AddressBook.UserInterface/Editors/Contact/ContactEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.AddressBook.UserInterface/Editors/Contact/ContactEditor.cs
index 63f294c2..5bb4050f 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.AddressBook.UserInterface/Editors/Contact/ContactEditor.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.AddressBook.UserInterface/Editors/Contact/ContactEditor.cs
@@ -59,6 +59,7 @@ namespace UniversalEditor.Editors.Contact
this.Padding = new Padding(26);
TabContainer sidebar = new TabContainer();
+ sidebar.TabStyle = TabContainerTabStyle.Sidebar;
#region Summary Panel
{
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs
index 3ca36355..1019bb88 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs
@@ -25,6 +25,8 @@ using MBS.Framework.UserInterface.Layouts;
using UniversalEditor.UserInterface;
using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
+using System;
+using MBS.Framework;
namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized
{
@@ -35,6 +37,8 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized
InitializeComponent();
}
+ public MBS.Audio.ITransport Transport { get; set; } = null;
+
private static EditorReference _er = null;
public override EditorReference MakeReference()
{
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/Controls/WaveformAudioEditorTrackWaveform.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/Controls/WaveformAudioEditorTrackWaveform.cs
index d9269f44..58ed8908 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/Controls/WaveformAudioEditorTrackWaveform.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/Controls/WaveformAudioEditorTrackWaveform.cs
@@ -106,6 +106,8 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Au
WaveformAudioEditorTrack track = (Parent as WaveformAudioEditorTrack);
WaveformAudioObjectModel wave = track.ObjectModel;
+ if (wave.RawSamples == null)
+ return;
ScrollBounds = new MBS.Framework.Drawing.Dimension2D(wave.RawSamples.Length, 0);
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/WaveformAudioEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/WaveformAudioEditor.cs
index ff763a12..5bda67bd 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/WaveformAudioEditor.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Waveform/WaveformAudioEditor.cs
@@ -43,6 +43,8 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Au
return _er;
}
+ public MBS.Audio.ITransport Transport { get; set; } = null;
+
public WaveformAudioEditor()
{
Layout = new BoxLayout(Orientation.Vertical);
@@ -66,17 +68,21 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Au
protected override void OnCreated(EventArgs e)
{
base.OnCreated(e);
- Context.AttachCommandEventHandler("WaveformAudioEditor_ContextMenu_Playback_Play", delegate (object sender, EventArgs ee)
- {
- WaveformAudioObjectModel wave = (ObjectModel as WaveformAudioObjectModel);
- if (wave == null) return;
- // get the setting "Editors -> Audio -> Waveform -> Audio engine
+ Transport = new MBS.Audio.CustomTransport(Transport_Play, null, null);
+ }
- // get the setting "Editors -> Audio -> Waveform -> Synchronize with JACK transport
- AudioPlayer player = new AudioPlayer();
- player.Play(wave);
- });
+ private bool Transport_Play()
+ {
+ WaveformAudioObjectModel wave = (ObjectModel as WaveformAudioObjectModel);
+ if (wave == null) return false;
+
+ // get the setting "Editors -> Audio -> Waveform -> Audio engine
+
+ // get the setting "Editors -> Audio -> Waveform -> Synchronize with JACK transport
+ AudioPlayer player = new AudioPlayer();
+ player.Play(wave);
+ return true;
}
public override void UpdateSelections()
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Plugins/Transport/TransportPlugin.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Plugins/Transport/TransportPlugin.cs
new file mode 100644
index 00000000..00174853
--- /dev/null
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Plugins/Transport/TransportPlugin.cs
@@ -0,0 +1,181 @@
+//
+// TransportPlugin.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2021 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using MBS.Framework;
+using MBS.Framework.UserInterface;
+using MBS.Framework.UserInterface.Dialogs;
+using UniversalEditor.UserInterface;
+
+namespace UniversalEditor.Plugins.Multimedia.UserInterface.Plugins.Transport
+{
+ public class TransportPlugin : UserInterfacePlugin
+ {
+ public TransportPlugin()
+ {
+ ID = new Guid("{02e071ec-b2cd-4a72-999f-3b626e06d609}");
+ Title = "Transport Plugin";
+ Context = new UIContext(ID, "Transport Plugin");
+
+ cbTransport = new CommandBar("cbTransport", "Transport", new CommandItem[]
+ {
+ new CommandReferenceCommandItem("Transport_Rewind"),
+ new CommandReferenceCommandItem("Transport_Back"),
+ new CommandReferenceCommandItem("Transport_Play"),
+ new CommandReferenceCommandItem("Transport_Forward"),
+ new CommandReferenceCommandItem("Transport_End")
+ });
+ }
+
+ private CommandBar cbTransport = null;
+ private CommandReferenceCommandItem miTransport = null;
+
+ void Handle_EditorChanging(object sender, EditorChangingEventArgs e)
+ {
+ if (e.CurrentEditor == null)
+ return;
+
+ Type t = e.CurrentEditor.GetType();
+ System.Reflection.PropertyInfo piTransport = t.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ if (piTransport != null && piTransport.PropertyType == typeof(MBS.Audio.ITransport))
+ {
+ if (!e.CurrentEditor.Context.CommandBars.Contains(cbTransport))
+ {
+ e.CurrentEditor.Context.CommandBars.Add(cbTransport);
+ }
+
+ if (!e.CurrentEditor.Context.MenuItems.Contains(miTransport))
+ {
+ e.CurrentEditor.Context.MenuItems.Add(miTransport);
+ }
+ }
+ }
+
+
+ protected override void InitializeInternal()
+ {
+ base.InitializeInternal();
+
+ Context.Commands.Add(new Command("Transport_Rewind", "_Rewind") { StockType = StockType.MediaPrevious });
+ Context.Commands.Add(new Command("Transport_Back", "_Back") { StockType = StockType.MediaRewind });
+ Context.Commands.Add(new Command("Transport_Play", "_Play") { StockType = StockType.MediaPlay });
+ Context.Commands.Add(new Command("Transport_Forward", "_Forward") { StockType = StockType.MediaForward });
+ Context.Commands.Add(new Command("Transport_End", "_End") { StockType = StockType.MediaNext });
+ Context.Commands.Add(new Command("Transport_Transport", "P_layback", new CommandItem[]
+ {
+ new CommandReferenceCommandItem("Transport_Rewind"),
+ new CommandReferenceCommandItem("Transport_Back"),
+ new CommandReferenceCommandItem("Transport_Play"),
+ new CommandReferenceCommandItem("Transport_Forward"),
+ new CommandReferenceCommandItem("Transport_End"),
+ }));
+
+ Context.AttachCommandEventHandler("Transport_Rewind", Transport_Rewind);
+ Context.AttachCommandEventHandler("Transport_Back", Transport_Back);
+ Context.AttachCommandEventHandler("Transport_Play", Transport_Play);
+ Context.AttachCommandEventHandler("Transport_Forward", Transport_Forward);
+ Context.AttachCommandEventHandler("Transport_End", Transport_End);
+
+ ((EditorApplication)Application.Instance).EditorChanging += Handle_EditorChanging;
+
+
+ miTransport = new CommandReferenceCommandItem("Transport_Transport");
+ miTransport.InsertAfterID = "Project";
+ }
+
+ private void Transport_End(object sender, EventArgs e)
+ {
+ Editor ed = (((UIApplication)Application.Instance).CurrentWindow as UniversalEditor.UserInterface.MainWindow)?.GetCurrentEditor();
+ Type t = ed?.GetType();
+ System.Reflection.PropertyInfo piTransport = t?.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ MBS.Audio.ITransport transport = (piTransport?.GetValue(ed, null) as MBS.Audio.ITransport);
+
+ if (transport == null)
+ {
+ MessageDialog.ShowDialog("Transport unavailable", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ }
+
+ private void Transport_Forward(object sender, EventArgs e)
+ {
+ Editor ed = (((UIApplication)Application.Instance).CurrentWindow as UniversalEditor.UserInterface.MainWindow)?.GetCurrentEditor();
+ Type t = ed?.GetType();
+ System.Reflection.PropertyInfo piTransport = t?.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ MBS.Audio.ITransport transport = (piTransport?.GetValue(ed, null) as MBS.Audio.ITransport);
+
+ if (transport == null)
+ {
+ MessageDialog.ShowDialog("Transport unavailable", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ }
+
+ private void Transport_Play(object sender, EventArgs e)
+ {
+ Editor ed = (((UIApplication)Application.Instance).CurrentWindow as UniversalEditor.UserInterface.MainWindow)?.GetCurrentEditor();
+ Type t = ed?.GetType();
+ System.Reflection.PropertyInfo piTransport = t?.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ MBS.Audio.ITransport transport = (piTransport?.GetValue(ed, null) as MBS.Audio.ITransport);
+
+ if (transport == null)
+ {
+ MessageDialog.ShowDialog("Transport unavailable", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ transport.Play();
+ }
+
+ private void Transport_Back(object sender, EventArgs e)
+ {
+ Editor ed = (((UIApplication)Application.Instance).CurrentWindow as UniversalEditor.UserInterface.MainWindow)?.GetCurrentEditor();
+ Type t = ed?.GetType();
+ System.Reflection.PropertyInfo piTransport = t?.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ MBS.Audio.ITransport transport = (piTransport?.GetValue(ed, null) as MBS.Audio.ITransport);
+
+ if (transport == null)
+ {
+ MessageDialog.ShowDialog("Transport unavailable", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+
+ }
+
+ private void Transport_Rewind(object sender, EventArgs e)
+ {
+ Editor ed = (((UIApplication)Application.Instance).CurrentWindow as UniversalEditor.UserInterface.MainWindow)?.GetCurrentEditor();
+ Type t = ed?.GetType();
+ System.Reflection.PropertyInfo piTransport = t?.GetProperty("Transport", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ MBS.Audio.ITransport transport = (piTransport?.GetValue(ed, null) as MBS.Audio.ITransport);
+
+ if (transport == null)
+ {
+ MessageDialog.ShowDialog("Transport unavailable", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ transport.Stop();
+ }
+ }
+}
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj
index 6e28e675..365d8030 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj
@@ -60,6 +60,7 @@
+
@@ -83,6 +84,8 @@
+
+
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia3D.UserInterface/Editors/Model/ModelEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia3D.UserInterface/Editors/Model/ModelEditor.cs
index 9500ccaf..fa78e17e 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia3D.UserInterface/Editors/Model/ModelEditor.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia3D.UserInterface/Editors/Model/ModelEditor.cs
@@ -27,6 +27,7 @@ using MBS.Framework.Rendering;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Dialogs;
+using MBS.Framework.UserInterface.Input.Mouse;
using MBS.Framework.UserInterface.Layouts;
using UniversalEditor.ObjectModels.Multimedia3D.Model;
@@ -46,18 +47,29 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
{
_er = base.MakeReference();
_er.SupportedObjectModels.Add(typeof(ModelObjectModel));
+
+ _er.Commands.Add(new Command("ModelEditor_Insert_Cube", "Cube") { ImageFileName = "Editors/Multimedia3D/Model/Icons/cube.png" });
+ _er.Commands.Add(new Command("ModelEditor_Insert_Sphere", "Sphere") { ImageFileName = "Editors/Multimedia3D/Model/Icons/sphere.png" });
+ _er.Commands.Add(new Command("ModelEditor_Insert_Plane", "Plane") { ImageFileName = "Editors/Multimedia3D/Model/Icons/plane.png" });
+
+ _er.CommandBars.Add(new CommandBar("ModelEditor_Insert", "Insert", new CommandItem[]
+ {
+ new CommandReferenceCommandItem("ModelEditor_Insert_Cube"),
+ new CommandReferenceCommandItem("ModelEditor_Insert_Sphere"),
+ new CommandReferenceCommandItem("ModelEditor_Insert_Plane"),
+ new SeparatorCommandItem()
+ }));
}
return _er;
}
public override void UpdateSelections()
{
- throw new NotImplementedException();
}
protected override Selection CreateSelectionInternal(object content)
{
- throw new NotImplementedException();
+ return null;
}
private OpenGLCanvas gla = null;
@@ -67,6 +79,7 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
this.Layout = new BoxLayout(Orientation.Vertical);
gla = new OpenGLCanvas();
+ gla.FocusOnClick = true;
gla.Realize += gla_Realize;
gla.Render += gla_Render;
this.Controls.Add(gla, new BoxLayout.Constraints(true, true));
@@ -116,7 +129,7 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
new VERTEX(-0.5f, -0.366f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f)
};
- VertexArray[] vaos = null;
+ VertexArray vao = null;
///
/// Computes the modelview projection
@@ -176,6 +189,16 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
void gla_Render(object sender, OpenGLCanvasRenderEventArgs e)
{
+ if (fatalError)
+ return;
+
+ if (e.Canvas == null)
+ {
+ MessageDialog.ShowDialog(String.Format("{0} . {1} {2} .\n\n", this._("Multimedia3D.Errors.CanvasInaccessible"), this._("Multimedia3D.Errors.RenderingUnavailable"), this._("Multimedia3D.Errors.CheckRequiredLibraries")), this._("Framework.Errors.GenericErrorTitle"), MessageDialogButtons.OK, MessageDialogIcon.Error);
+ fatalError = true;
+ return;
+ }
+
e.Canvas.Clear(Colors.Gray);
if (p == null && !fatalError)
@@ -185,7 +208,7 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
string vtxFileName = ((UIApplication)Application.Instance).ExpandRelativePath("~/Editors/Multimedia3D/Model/Shaders/Default/default_vtx.glsl");
if (!System.IO.File.Exists(vtxFileName))
{
- MessageDialog.ShowDialog(String.Format("Vertex shader not found . The rendering will be unavailable. Check to ensure the file exists and is readable .\n\n{0}", vtxFileName), "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ MessageDialog.ShowDialog(String.Format("{0} . {1} {2} .\n\n", this._("Multimedia3D.Errors.VertexShaderNotFound"), this._("Multimedia3D.Errors.RenderingUnavailable"), this._("Multimedia3D.Errors.CheckRequiredFile")), this._("Framework.Errors.GenericErrorTitle"), MessageDialogButtons.OK, MessageDialogIcon.Error);
fatalError = true;
p = null;
return;
@@ -197,7 +220,7 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
string frgFileName = ((UIApplication)Application.Instance).ExpandRelativePath("~/Editors/Multimedia3D/Model/Shaders/Default/default_frg.glsl");
if (!System.IO.File.Exists(vtxFileName))
{
- MessageDialog.ShowDialog(String.Format("Fragment shader not found . The rendering will be unavailable. Check to ensure the file exists and is readable .\n\n{0}", frgFileName), "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ MessageDialog.ShowDialog(String.Format("{0} . {1} {2} .\n\n", this._("Multimedia3D.Errors.FragmentShaderNotFound"), this._("Multimedia3D.Errors.RenderingUnavailable"), this._("Multimedia3D.Errors.CheckRequiredFile")), this._("Framework.Errors.GenericErrorTitle"), MessageDialogButtons.OK, MessageDialogIcon.Error);
fatalError = true;
p = null;
return;
@@ -220,11 +243,11 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
}
/* use the buffers in the VAO */
- if (vaos != null)
+ if (vao != null)
{
try
{
- vaos[0].Bind();
+ vao.Bind();
/* draw the three vertices as a triangle */
e.Canvas.DrawArrays(RenderMode.Triangles, 0, vertex_data.Length);
@@ -289,18 +312,18 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
vertex_data = list.ToArray();
}
- if (vaos != null)
+ if (vao != null)
{
- gla.Engine.DeleteVertexArray(vaos);
+ gla.Engine.DeleteVertexArray(vao);
}
// we need to create a VAO to store the other buffers
- vaos = gla.Engine.CreateVertexArray(1);
+ vao = gla.Engine.CreateVertexArray();
// this is the VBO that holds the vertex data
using (RenderBuffer buffer = gla.Engine.CreateBuffer())
{
- vaos[0].Bind();
+ vao.Bind();
buffer.Bind(BufferTarget.ArrayBuffer);
buffer.SetData(vertex_data, BufferDataUsage.StaticDraw);
@@ -320,7 +343,7 @@ namespace UniversalEditor.Plugins.Multimedia3D.UserInterface.Editors.Model
// reset the state; we will re-enable the VAO when needed
buffer.Unbind();
- vaos[0].Unbind(); // must be called BEFORE the buffer gets disposed
+ vao.Unbind(); // must be called BEFORE the buffer gets disposed
}
changed = false;
}
diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Waveform/WaveformAudioObjectModel.cs b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Waveform/WaveformAudioObjectModel.cs
index 2da0f2fe..cb9fb7d8 100644
--- a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Waveform/WaveformAudioObjectModel.cs
+++ b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Waveform/WaveformAudioObjectModel.cs
@@ -152,8 +152,8 @@ namespace UniversalEditor.ObjectModels.Multimedia.Audio.Waveform
clone.Header.DataRate = this.Header.DataRate;
clone.Header.FormatTag = this.Header.FormatTag;
clone.Header.SampleRate = this.Header.SampleRate;
- clone.RawData = (this.mvarRawData.Clone() as byte[]);
- clone.RawSamples = (this.RawSamples.Clone() as WaveformAudioSamples);
+ clone.RawData = (this.RawData?.Clone() as byte[]);
+ clone.RawSamples = (this.RawSamples?.Clone() as WaveformAudioSamples);
clone.Information.AlbumTitle = (Information.AlbumTitle.Clone() as string);
clone.Information.Comments = (Information.Comments.Clone() as string);
diff --git a/update.sh b/update.sh
new file mode 100755
index 00000000..dcb0f8e6
--- /dev/null
+++ b/update.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+GIT_USER=alcexhim
+GIT_URL=git@github.com:$GIT_USER
+GIT_PROJECTS="MBS.Audio MBS.Framework MBS.Framework.UserInterface MBS.Framework.Rendering UniversalEditor"
+
+for name in $GIT_PROJECTS; do
+
+ if [ -d ../$name ]; then
+ cd ../$name && git pull
+ else
+ cd ../ && git clone $GIT_URL/$name
+ cd $name
+ fi
+
+done