Thursday, January 27, 2011

Using VNCServer with SSH

This blog entry isn't directly related to WPF, but there are cases where a WPF project is deployed to a unix environment and there is a need to work with xwindows.

I've been successfully using vcnserver for many years with various flavors of unix, but I've always been stumped by something - when I ssh into another machine, my xwindows display stops working. As long as I stay on the original machine that is running vncserver, everything is fine but if I move to a different box I get the following error:

pdvboxb:/home/dsixe>xcalc
Xlib: connection to "pdvboxa:1.0" refused by server
Xlib: Client is not authorized to connect to Server
Error: Can't open display: pdvboxa:1.0

Well today I was in need to run an application that required xwindows and I decided to buckle down and find a solution to this nagging situation. Since my memory isn't what it once was, I'm going to record it on this blog so the next time I run into it I'll be able to trace my solution and maybe someone else will find it useful as well.

Here's the scenario, there are two machines - pdvboxa and pdvboxb. I log into pdvboxa using something like putty and fire up vncserver, then I log out and go back in using vnc viewer client to pdvboxa:1. Xcalc works fine here but not when I ssh to pdvboxb.

Several sites recommend using xhost + which seems to open up connections to anyone, but that would be bad. Besides, in my scenario it didn't work anyways.


Using xauth

A better solution is to use xauth to copy the magic cookie created by vncserver (I'm pretty sure vncserver created it) to the second machine pdvboxb.

On pdvboxa  run the command xauth list which returns something like:
pdvboxa:1  MIT-MAGIC-COOKIE-1  f73147c509311da56b94ba84597fa41b
pdvboxa/unix:1  MIT-MAGIC-COOKIE-1  f73147c509311da56b94ba84597fa41b

Now go to pdvboxb and run the command xauth add using the first magic cookie:
xauth add pdvboxa:1  MIT-MAGIC-COOKIE-1  f73147c509311da56b94ba84597fa41b

Ensure the display var is set correctly:
export DISPLAY=pdvboxa:1.0

Test by running xcalc and you should be good to go.

Thursday, January 13, 2011

Variables and Schemas in Portlet Factory

Anyone who has played with portlet factory will quickly learn that it depends heavily on xml defined by a schema. Putting some thought into this I realized that a schema is really a way to define a type and a WPF variable is an instance of that type. For example there is a close correlation between a java type definition such as:

public class Contact{
   public String name;
   public String phone;
}
...
public class Data{
   public List<Contact> dsixe;
}

and an xml representation of the same information as

<dsixe>
    <contact>
        <name/>
        <phone/>
    </contact>
</dsixe>

with a schema that looks like this

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dsixe="http://dsixe.com/contact" targetNamespace="http://dsixe.com/contact">
   <xsd:element name="dsixe">
      <xsd:complexType>
         <xsd:sequence>
            <xsd:element ref="dsixe:contact" minOccurs="1" maxOccurs="unbounded" />
         </xsd:sequence>
      </xsd:complexType>
   </xsd:element>
   <xsd:element name="contact">
      <xsd:complexType>
         <xsd:sequence>
            <xsd:element ref="dsixe:name" minOccurs="1" maxOccurs="1" />
            <xsd:element ref="dsixe:phone" minOccurs="1" maxOccurs="1" />
         </xsd:sequence>
      </xsd:complexType>
   </xsd:element>
   <xsd:element name="name" type="xsd:string" />
   <xsd:element name="phone" type="xsd:string" />
</xsd:schema>

Combining the variable builder with the schema builder

Portlet factory provides separate builders to define a schema and a variable, but sometimes it would be nice to combine both into one when I need a quick and dirty variable and I don't want to create a standalone schema file. If I know what my xml structure looks like then I want WPF to just figure out what the schema is based on some sample data in one motion.
To that end I created a custom builder that combines elements from the variable builder with those of a schema builder:


The builder creates a schema in the model with a suffix _xsd and a variable with a suffix _var:

The builder can be downloaded and installed as a WPF package under Optional Libraries feature set.

Adding Help Feature to Custom Builders

Portlet factory has a great feature which allows creation of custom builders, fantastic for extending the already rich set of builders provided by the tool. Sometimes these custom builders are used to encapsulate business specific functionality to be shared across an organization and providing some help documents can accelerate their adoption.
Adding custom help files that integrate with the designer is quite easy, just take a look at the builder definition file and you'll find a HelpFile element:

  <HelpFile>WEB-INF/builders/com/dsixe/builders/doc/schemagen_builder.htm</HelpFile>

The developer can specify a location for html help that will be tied to the help button on the builder. I like to follow the same look and feel of the stock builder help, so I usually start with an existing file which can be found in {WPF_INSTALL}\Designer\eclipse\plugins\com.bowstreet.designer.doc_*\designer and copy it to my local project.
Using this approach I can put together some really professional looking documentation to support the hard work I put into creating the builders.

An example builder definition file can be found in the attachment for my previous post Variables and Schemas in Portlet Factory.

Wednesday, January 5, 2011

Adding a Custom Toolbar Item to Dojo Rich Text Edit

As mentioned in a previous blog post, dojo's rich text editor includes a plugin mechanism to add custom toolbar items. In this post I will explore how I accomplished this, details of how to integrate into WPF can be found here.

My goal is to be able to click on a toolbar button and have a modal dialog box with a lightbox effect appear. The contents of the dialog is a custom search result where individual result items can be selected, causing the dialog to close and inserting a link to that item in the rich text edit.

Create a New Plugin

Since writing code from scratch is tedious (I am impatient) I always prefer to start with something that works and then modify it to meet my needs. In this case I've taken the plugin named factory\dojo\dijit\_editor\plugins\ToggleDir.js since it's nice and short, and re-purposed it to create a modal popup window when clicked. I'm going to copy it into a new file named SearchPopup.js.

dojo.provide("dijit._editor.plugins.SearchPopup");
dojo.require("dijit._editor._Plugin");
dojo.declare("dijit._editor.plugins.SearchPopup",
    dijit._editor._Plugin,
    {
        // summary:
        //        This plugin provides a popup window to search and select content
        //
        // description:
        //        The commands provided by this plugin are:

    _initButton: function(){
        // summary:
        // This is the button that will appear on the toolbar
        this.button = new dijit.form.Button({
            label: "Search and add content",
            showLabel: false,
            iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "CreateLink",
            tabIndex: "-1",
            onClick: dojo.hitch(this, function(){popupSearch()})
        });
        }
        
    }
);

// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
    if(o.plugin){ return; }
    switch(o.args.name){
    case "searchPopup": 
        o.plugin = new dijit._editor.plugins.SearchPopup();
    }
});


This is probably the most basic plugin that can be created. All it does is invoke a javascript function named popupSearch() when the button is clicked:
onClick: dojo.hitch(this, function(){popupSearch()})

The code to pick an icon is a little tricky, it refers to factory\dojo\dijit\themes\tundra\images\editor.gif which is an image containing a long strip of icons like this:

and finally the iconClass can be tracked down in factory\dojo\dijit\themes\tundra\Editor.css:
Code:
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "CreateLink",

Matching CSS:
.tundra .dijitEditorIconCreateLink { background-position: -90px; }

If I wanted to use my own icon I'd have to edit the icon strip and add a new image, but since I can't draw to save my life I decided to just reuse the one for creating a link. The rest of the code is just boilerplate, and we can add our newly minted plugin to the toolbar with some javascript:
dojo.addOnLoad(function(){
 dojo.require("dijit._editor.plugins.SearchPopup");
 var widget = dijit.byId(gcps.assessmentWidget);
 widget.addPlugin('searchPopup');
});

EDIT 2/14/2012: I found a pretty good developerworks article on this topic. Check it out.