AvalonEdit - xshd for JSON highlighting - wpf

Is there an xshd ruleset for the AvalonEdit control to highlight the JSON syntax? I tried the definition for JavaScript, but it doesn't work well, i.e.:
{
"name" : "value"
}
both name and value have the same color using the JavaScript definition.
Is there a ruleset for JSON, and if not, how can I modify the xshd so that I get different colors for the name and value in JSON?

If somebody needs something like that, I worked it out in following way:
<?xml version="1.0" encoding="utf-8" ?>
<SyntaxDefinition name="Json" extensions=".js" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color name="Digits" foreground="#8700FF" exampleText="3.14" />
<Color name="Value" foreground="#000CFF" exampleText="var text = "Hello, World!";" />
<Color name="ParamName" foreground="#057500" exampleText="var text = "Hello, World!";" />
<RuleSet ignoreCase="false">
<Keywords color="Digits" >
<Word>true</Word>
<Word>false</Word>
</Keywords>
<Span color="ParamName">
<Begin>"</Begin>
<End>(?=:)</End>
</Span>
<Span color="Value" multiline="true">
<Begin>
(?<=:)\040"[^"]*
</Begin>
<End>"</End>
</Span>
<Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule>
</RuleSet>
</SyntaxDefinition>
Not perfect, but for me enough.

Just use AvalonEdit's JavaScript highlighter.
Sample code:
using (var stream = Assembly.GetAssembly(typeof(ICSharpCode.AvalonEdit.TextEditor)).GetManifestResourceStream("ICSharpCode.AvalonEdit.Highlighting.Resources.JavaScript-Mode.xshd"))
{
using (var reader = new XmlTextReader(stream))
{
avalonEdit.SyntaxHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
SearchPanel.Install(avalonEdit);
}
}

Related

Xpages: Combobox does not retain value when going from read to edit mode

A combobox is bound to a java bean. Documents is opened in read mode, and the selected value is displayed.
But when I go into Edit mode the value is "lost".
I would like to avoid making two fields on the page, but I guess I can if I must. But it seems like something is wrong with my code or my approach.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.afterPageLoad><![CDATA[#{javascript:sessionScope.models = PCConfig.models;
viewScope.readOnly = "Yes";}]]></xp:this.afterPageLoad>
<xp:button value="Toggle Edit Mode" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:if (viewScope.readOnly == "Yes")
{viewScope.readOnly = "No"}
else
{viewScope.readOnly = "Yes"}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:text escape="true" id="computedField1" value="#{viewScope.readOnly}"></xp:text>
<xp:br></xp:br>
<xp:panel id="pnlAll">
<xp:this.data>
<xe:objectData saveObject="#{javascript:PCModel.save()}"
var="PCModel">
<xe:this.createObject><![CDATA[#{javascript:var pc = new com.scoular.model.PC();
var unid = sessionScope.get("key");
if (unid != null) {
pc.loadByUnid(unid);
sessionScope.put("key","");
viewScope.put("readOnly","Yes");
} else {
pc.create();
viewScope.put("readOnly","No");
}
return pc;}]]></xe:this.createObject>
</xe:objectData>
</xp:this.data>
<xp:comboBox id="model" value="#{PCModel.model}"
disableValidators="true" disableClientSideValidation="true"
styleClass="form-control">
<xp:this.attrs>
<xp:attr name="disabled" value="disabled">
<xp:this.rendered><![CDATA[#{javascript:if (viewScope.readOnly == "Yes")
{return true}
else
{return false}}]]></xp:this.rendered>
</xp:attr>
</xp:this.attrs>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:"--Select A Value--|"}]]></xp:this.value>
</xp:selectItems>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:sessionScope.models}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:panel>
</xp:view>
Replace your code for setting comboBox's property disabled
<xp:comboBox
id="model"
value="#{PCModel.model}"
...>
<xp:this.attrs>
<xp:attr name="disabled" value="disabled">
<xp:this.rendered><![CDATA[#{javascript:if
(viewScope.readOnly == "Yes")
{return true}
else
{return false}}]]></xp:this.rendered>
</xp:attr>
</xp:this.attrs>
by
<xp:comboBox
id="model"
value="#{PCModel.model}"
...
disabled="#{javascript:viewScope.readOnly == 'Yes'}">
Seems, comboBox can't deal correctly with the disabled setting by attr (whereas it works fine for an inputText control).
But, comboBox's direct property disabled is better to handle than by attrs / attr code anyway.

Include SAP Gateway labels in Breeze custom metadata

I am building an Angular 1.3.5 app using Breeze 1.5.1 to interface with a SAP gateway server. One requirement is to minimize duplicate UI translations by re-using the human-readable metadata labels provided by the server. From what I can gather, Breeze's support for custom metadata properties should allow me to load these labels alongside all the standard entity metadata, but I'm struggling to work out exactly how to approach this.
The metadata service provides data in the following format:
<EntityType Name="ContactPersonEmail" sap:content-version="1">
<Key>
<PropertyRef Name="email"/>
</Key>
<Property Name="cpGuid" Type="Edm.Guid" sap:label="Long Text String for XML and HTML Output"/>
<Property Name="primaryEmail" Type="Edm.Boolean" Nullable="false" sap:label="Standard No."/>
<Property Name="email" Type="Edm.String" Nullable="false" MaxLength="241" sap:label="E-Mail Address"/>
<Property Name="homeIndicator" Type="Edm.Boolean" Nullable="false" sap:label="Home address"/>
<Property Name="location" Type="Edm.String" Nullable="false" MaxLength="2" sap:label="Email Type"/>
<Property Name="emailType" Type="Edm.String" Nullable="false" MaxLength="2" sap:label="Email Type"/>
<Property Name="emailTypeText" Type="Edm.String" Nullable="false" MaxLength="60"/>
</EntityType>
where the sap:label attribute is the text I want to add to the Breeze entity type. Is this feasible? The Breeze documentation mostly seems to be focused on loading custom metadata from a local file or already-loaded data, rather than including an additional property on data load, so perhaps this approach is naive.
Once this is resolved I'll work out how to get the text onto the page, but that's for later.
Update: Solution
Per Jeremy's answer below, I was able to run the metadata response through an initialisation function and capture the label field via the metadataProperty's extension property. Example (pre-refactor) code as follows:
// ...
if (entityProperty) {
if (typeof metadataProperty.extensions !== "undefined" && metadataProperty.extensions.length) {
var extension = metadataProperty.extensions[0];
entityProperty[extension.name] = extension.value;
}
}
// ...
The extension.name in this instance is "label", and it's the only extension in the array where it appears. Now all that remains is to get the data onto the UI, but I'm sure that'll be trivial :)
I think this is possible although I'll admit I have only supplemented the Breeze Metadata JSON schema, never XML.
When fetching the metadata on the client you'll just need to do a bit of additional processing to supplement the breeze entity type with your custom metadata properties. In the example code below four custom metadata props are added: displayName, displayOrder, autoGenerateField and allowEmptyStrings.
function initializeMetadataStore(metadataStore, metadata) {
var metadataType, metadataProperty, entityProperty, i, j;
for (i = 0; i < metadata.schema.entityType.length; i++) {
metadataType = metadata.schema.entityType[i];
var entityType = metadataStore.getEntityType(metadataType.name);
for (j = 0; j < metadataType.property.length; j++) {
metadataProperty = metadataType.property[j];
entityProperty = entityType.getProperty(metadataProperty.name);
if (entityProperty) {
if (typeof metadataProperty.displayName !== 'undefined') {
entityProperty.displayName = metadataProperty.displayName;
}
if (typeof metadataProperty.displayOrder !== 'undefined') {
entityProperty.displayOrder = metadataProperty.displayOrder;
}
if (typeof metadataProperty.autoGenerateField !== 'undefined') {
entityProperty.autoGenerateField = metadataProperty.autoGenerateField;
}
if (typeof metadataProperty.allowEmptyStrings !== 'undefined') {
entityProperty.allowEmptyStrings = metadataProperty.allowEmptyStrings;
}
}
}
}
}
var entityManager = ....something...;
entityManager.fetchMetadata(function (metadata) {
return initializeMetadataStore(entityManager.metadataStore, metadata);
});
Here's my answer to a similar question however the OP's backend is .NET and they're using the Breeze Metadata JSON schema.

Flash Builder - Customizing comboBox

I'm populating items to a comboBox from an xml file. I'm trying to customize the font-color of each item that appears in the comboBox. Any suggestions?
Thanks!
--Moe
The process is simple if you are using Flash Builder. Each item in your ComboBox is made of an ItemRenderer. Create a custom item render (file - > new -> mxml component) extending that basic ItemRenderer class then assign this new ItemRenderer to your ComboBox. Now inside your custom ItemRenderer you can change values, font sizes, etc ...
You will need to use an ItemRenderer. Though you have not mentioned but it seems you are using Flex 3. The way of using ItemRenderer is slightly different in Flex 3 vs Flex 4. So here is the version for Flex 3:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
<mx:XMLList id="statesXMLList" xmlns="">
<state abbrev="AK" name="Alaska" />
<state abbrev="AZ" name="Arizona" />
<state abbrev="AR" name="Arkansas" />
<state abbrev="CA" name="California" />
<state abbrev="CO" name="Colorado" />
<state abbrev="CT" name="Connecticut" />
</mx:XMLList>
<mx:ComboBox id="comboBox"
prompt="Please select a State..."
dataProvider="{statesXMLList}"
rowCount="3"
labelField="#name"
itemRenderer="ComboBoxItemRenderer"
/>
</mx:Application>
The class for ItemRenderer is ComboBoxItemRenderer which is shown below:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
override public function set data(value:Object):void
{
super.data = value;
lbl.text = value.#name;
if(value.#abbrev == "AK") {
lbl.setStyle("color","#FF0000");
}
else if(value.#abbrev == "AR") {
lbl.setStyle("color","#FF00FF");
}
else {
lbl.setStyle("color","#000000");
}
}
]]>
</mx:Script>
<mx:Label id="lbl"/>
</mx:VBox>
Do not forget the last if (default case) whenever you override set data method.

Populating a listview contents with an array

I have created a function that would be able to place the array contents into a listview, Here is my progress so far.
<div id="MainPage" data-role="page" >
<div data-role="content">
RENAME
</div>
</div>
<div id="ViewPage" data-role="page" >
<div data-role="content">
<ul id="viewlist" data-role="listview" data-filter="true" data-filter-placeholder="Sample Contents" data-inset="true">
<!-- array contents goes here -->
</ul>
</div>
</div>
<script>
var sampleContent = new Array( );
displayArray( )
{
for(var scan=0; scan<sampleContent.length; detect++)
{
$('#viewlist').append('<li>' + sampleContent[scan] + '</li>');
}
}
</script>
My code works during the first press of the button but when i pressed it the second time, the list view becomes messed up.
Any help or advice will be glady accepted thanks in advance.
edited, i have figured out how to do it but I am having problems during the second press of the button.
First of i don't want to be rude but i think you should start first to read some basics about android.
Like:
Android Activities , life cycle of activities
Layout in Android (how to add button on an activity then respond to a click etc) , different existing Layout in android and android widget (like the listView for example)
of course there are a lot more to read but it s a good way to start.
However i will provide you codes that will do what you are asking for and i will try to explain as much as i can
First of all you need to create the other activity and inside the layout of that activity insert a listview
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_gravity="center_horizontal" />
</LinearLayout>
then the java code of the other activity will look like this
public class MainActivity2 extends Activity {
//create the array adapter that will input your array and convert it into a list of view
ArrayAdapter<String> arrayAdapter;
String[] list;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
listView = (ListView)findViewById(R.id.listView);
// get the array from ressource and insert them on an array
list = getResources().getStringArray(R.array.listArray);
// then create the arrayadpater with input your array of string if you dont get //anything here just read android documentation about arrayAdapter
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list );
//then set the adapter to your listView
listView.setAdapter(arrayAdapter);
}
}
res xml file
<resources>
<string-array name="listArray">
<item>Apple</item>
<item>Banana</item>
<item>Cherry</item>
<item>Cranberry</item>
<item>Grape</item>
<item>Grape</item>
</string-array>
</resources
>
Hope it will help
Just add .listview('refresh') after you have added all items.
$('#viewlist').listview('refresh');
If you want to empty the list each time and refill it, call .empty() before the for loop:
$('#viewlist').empty();
To use better jquery mobile coding, structure your code like this:
Take the onclick out of the anchor tag and add an id:
<a id="viewPageBtn" href="#ViewPage" data-role="button" >RENAME</a>
In your script tag, handle pagecreate on the main page, and within it handle the click event of the anchor:
$(document).on("pagecreate", "#MainPage", function(){
var sampleContent = ["item 1", "item 2", "item 3"];
$("#viewPageBtn").on("click", function(){
$('#viewlist').empty();
for(var scan=0; scan < sampleContent.length; scan++)
{
$('#viewlist').append('<li>' + sampleContent[scan] + '</li>').listview('refresh');
}
$('#viewlist').listview('refresh');
});
});

How to serialize XAML as part of other plain XML nodes?

I want to serialize XAML and other app's-settings-info in a single settings-file. Something like:
<root>
<settings>
...
</settings>
<xaml_stuff>
...
</xaml_stuff>
</root>
I'll be thankful for any guidance how to elegantly accomplish it: I have XamlWriter on one hand and the other XML-API\namespaces on the other, but I can't find a way to connect them together.
See if this helps: http://msdn.microsoft.com/en-us/library/ms590446.aspx.
From what I understand, it first serializes it to XmlWriter, which you can then use to add other non-xaml stuff
Edit: Here's a concrete C# example (with some changes to what I said previously)...
XmlTextWriter w = new XmlTextWriter("test.xml", Encoding.UTF8);
w.WriteStartElement("root");
w.WriteAttributeString("xmlns", "x");
w.WriteStartElement("item1");
w.WriteEndElement();
w.WriteStartElement("item2");
w.WriteEndElement();
Button btn = new Button();
btn.Content = "Test Button";
btn.Width = 200;
btn.Height = 100;
btn.Foreground = Brushes.Green;
string buf = XamlWriter.Save(btn);
XmlTextReader reader = new XmlTextReader(new StringReader(buf));
reader.Read();
w.WriteNode(reader, true);
w.WriteEndElement();
w.Flush();
w.Close();
And here are the contents of the file it generates:
<root xmlns="x">
<item1 />
<item2 />
<Button Foreground="#FF008000" Width="200" Height="100" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">Test Button</Button>
</root>

Resources