Usingnamespace – Blog

C#, XUL, Javascript, C++ …

I am pleased to share one creation of mine :) .

The following widget is a XBL binding based on the XUL’s XNL templates technology.
https://developer.mozilla.org/en/XUL/Template_Guide/XML_Templates

If you need to display xml data into a xul menulist -combobox- or in a radiogroup -radiobox-, without having to implement an XML parser, here is the solution :

xml-combobox
xml-radiobox

<xml-combobox id="myid" datasources="chrome://application/pathtoxmlfile" expr=""/>
<xml-radiobox id="myid" datasources="chrome://application/pathtoxmlfile" expr=""/>

Attributes :

datasources : URL of an XML document, either a local file or a remote web site.

expr : the expr attribute is a very simple XPath expression which simply retrieves the root elements of your query within the datasource.

label :

  • starting with « ! » : an XPath expression corresponding to the node you want to use as a label.
  • starting with « ? » : a property of the node corresponding to the expr result, you want to use as a label.
  • Otherwise just a text used as a label for all the generated lines (can be empty).



value :

  • starting with « ! » : an XPath expression corresponding to the node you want to use as a value.
  • starting with « ? » : a property of the node corresponding to the expr result, you want to use as a value.
  • Otherwise just a text used as a value for all the generated lines (can be empty).



image :

  • starting with « ! » : an XPath expression corresponding to the node you want to use as an image.
  • starting with « ? » : a property of the node corresponding to the expr result, you want to use as an image.
  • Otherwise just a text used as an image for all the generated lines (can be empty).



imageBaseFolder : if the attribute image is used, the base folder where to look the images for. Useful if the image query result is just a file name, or a relative path. Must contain the final « / » or « \ ». Can be left empty.

orient : (xml-radiobox only) : « horizontal » or « vertical ».

onselect: occurs when selection changed.

Examples :

Example 1 : simple example using the properties of a XML node

<people>
  <person name="Napoleon Bonaparte" id="NB"/>
  <person name="Cleopatra" id="Cl"/>
  <person name="Julius Caesar" id="JC"/>
  <person name="Ferdinand Magellan" id="FM"/>
  <person name="Laura Secord" id="LS"/>
</people>
<xml-combobox id="myid" datasources="chrome://application/pathtoxmlfile" expr="person/" label="?name" value="?id"/>

Example 2 : using a node property for the id and a XPath from the targeted node for the label (here the text contained in the subnode « name »)

<people>
  <person id="NB">
    <name>Napoleon Bonaparte</name>
    <gender>Male</gender>
  </person>
  <person id="Cl">
    <name>Cleopatra</name>
    <gender>Female</gender>
  </person>
  <person id="JC">
    <name>Julius Caesar</name>
    <gender>Male</gender>
  </person>
  <person id="FM">
    <name>Ferdinand Magellan</name>
    <gender>Male</gender>
  </person>
  <person id="LS">
    <name>Laura Secord</name>
    <gender>Female</gender>
  </person>
</people>
<xml-radiobox id="myid" datasources="chrome://application/pathtoxmlfile" expr="person/" label="!./name/text()" value="?id" orient="horizontal"/>

Example 3 : same as example 2 but with a xml-combobox and using the image property and imageBaseFolder to specify where the widget should look the images for

<people>
  <person id="NB">
    <name>Napoleon Bonaparte</name>
    <gender>Male</gender>
    <picture>nap.png</picture>
  </person>
  <person id="Cl">
    <name>Cleopatra</name>
    <gender>Female</gender>
    <picture>cleo.png</picture>
  </person>
  <person id="JC">
    <name>Julius Caesar</name>
    <gender>Male</gender>
    <picture>julius.png</picture>
  </person>
  <person id="FM">
    <name>Ferdinand Magellan</name>
    <gender>Male</gender>
    <picture>magellan.png</picture>
  </person>
  <person id="LS">
    <name>Laura Secord</name>
    <gender>Female</gender>
    <picture>secord.png</picture>
  </person>
</people>
<xml-combobox id="myid" datasources="chrome://application/pathtoxmlfile" expr="person/" label="!./name/text()" value="?id" imageBaseFolder="chrome://application/skin/pic_small/" image="!./picture/text()"/>

And like all the XBL widgets, the bindings need to be done in a CSS :

xml-combobox{
	-moz-binding: url("chrome://application/content/bindings/xml-combobox.xml#xml-combobox") !important;
}
 
xml-radiobox{
	-moz-binding: url("chrome://application/content/bindings/xml-radiobox.xml#xml-radiobox") !important;
}

How to export rock music to an area like the Emirates ?

MTV has a pretty funny/clever answer :

Here are some useful functions I wrote or found on the web.
Suggestions are welcome :)

Chrome url to file path :

function chromeToPath (aChromePath) {
 
   if (!aChromePath) || !(/^chrome:/.test(aChromePath))))
      return; //not a chrome url
   var rv;
 
   var ios = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces["nsIIOService"]);
   var uri = ios.newURI(aPath, "UTF-8", null);
   var cr = Components.classes['@mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces["nsIChromeRegistry"]);
   rv = cr.convertChromeURL(uri).spec;
 
   if (/^file:/.test(rv))
      rv = this.urlToPath(rv);
   else
      rv = this.urlToPath("file://"+rv);
 
   return rv;
}

URL to file path :

function urlToPath (aURL) {
 
   if (!aURL || !/^file:/.test(aURL))
      return ;
   var rv;
   var ph = Components.classes["@mozilla.org/network/protocol;1?name=file"]
        .createInstance(Components.interfaces.nsIFileProtocolHandler);
    rv = ph.getFileFromURLSpec(aPath).path;
    return rv;
}

Get a nsILocalFile’s URL :

function pathToUrl (aFile) {
   //aFile must be an instance of nsILocalFile
   var rv;
   var ph = Components.classes["@mozilla.org/network/protocol;1?name=file"]
        .createInstance(Components.interfaces.nsIFileProtocolHandler);
    rv = ph.getURLSpecFromFile(aFile);
    return rv;
}

Check if file exists :

function fileExists(aPath){
  try {
    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
    var file = Components.classes["@mozilla.org/file/local;1"]
                         .createInstance(Components.interfaces.nsILocalFile);
    file.initWithPath(aPath);
    return file.exists();
  } catch(ex) {
    return false;
  }
}

Quit function :

function quit (aForceQuit) {
  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
  var appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1'].
    getService(Components.interfaces.nsIAppStartup);
 
  // eAttemptQuit will try to close each XUL window, but the XUL window can cancel the quit
  // process if there is unsaved data. eForceQuit will quit no matter what.
  var quitSeverity = aForceQuit ? Components.interfaces.nsIAppStartup.eForceQuit :
                                  Components.interfaces.nsIAppStartup.eAttemptQuit;
  appStartup.quit(quitSeverity);
}

.NET is quite great to create and publish your own web services, and an eventually a client for it, almost without typing anything.
How to give your client the capacity to choose which server to connect to, in case of a distributed web service ?

When you create your web service in Visual studio, it asks you for the address of the service in order to generate the Service Reference, and then writes this address into the config file.
So, how to dynamically change the address of the targeted web service ?

//We set the server's new address
string server_address = "http://www.newaddress.com:80";
ServiceName.ServiceReferenceSoapClient server = new ServiceName.ServiceReferenceSoapClient();
System.ServiceModel.EndpointAddress addr = new System.ServiceModel.EndpointAddress(server_address);
server.Endpoint.Address = addr;
Uri site = new Uri(server_address);
server.Endpoint.ListenUri = site;
 
//Then use the server as usual :
server.HelloWorld();

If you ever wondered how to open an excel file and write data into it from your .NET project, here is the solution :

using Excel = Microsoft.Office.Interop.Excel;
 
Excel.Application xlApp = new Excel.ApplicationClass();
 
xlApp.Visible = true; //If true, the Excel window will be visible during the process, if not, it is done in background
Excel.Workbook xlWBook = xlApp.Workbooks.Open(filename, 0, false, 5, System.Reflection.Missing.Value, System.Reflection.Missing.Value, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value, true, false, System.Reflection.Missing.Value, false, false, false);//Opens the Excel sheets
Excel.Worksheet xlSheet = (Excel.Worksheet)xlWBook.Worksheets[1]; //Get the first Sheet of the Excel file
 
//Write Something at Cell A1 :
string value = "Test";
Excel.Range excelCell2 = (Excel.Range)xlSheet.get_Range("A1:A1", Type.Missing); //Selects a Cell A1
excelCell2.Cells.Value2 = value;
 
//Duplicate a line
 
int line = 5; //Will copy line 5 and paste the copy above
Excel.Range R1 = xlSheet.get_Range(xlSheet.Cells[line, 1], xlSheet.Cells[line, 1]).EntireRow;
xlSheet.get_Range(xlSheet.Cells[line, 1], xlSheet.Cells[line, 1]).EntireRow.Copy(Type.Missing);
R1.EntireRow.Insert(Excel.XlInsertShiftDirection.xlShiftDown, true);
 
//Here we copy the cells' formats, style and formulas.
R1.EntireRow.PasteSpecial(Excel.XlPasteType.xlPasteFormulasAndNumberFormats, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, true)

More info about the XlPasteType and XlPasteSpecialOperation :

http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.pastespecial%28VS.80%29.aspx

Also helpful :

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.applicationclass%28office.11%29.aspx

Troubleshooting:

If like me you have an Operating System and an Excel which uses different money and number formats (for me French OS and US Excel), you will encounter the following exception while opening Workbook :

System.Runtime.InteropServices.COMException (0×80028018): Ancien format ou bibliothèque de types non valide. (Exception de HRESULT : 0×80028018 (TYPE_E_INVDATAREAD))

à Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)

You can fix this bug by setting the current thread culture to « en – US » :

System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");

Be careful though, if you do so it changes to whole behaviour of you program concerning number and money formats. For instance the float.Parse() function will behave differently if the new Culture has a different number formatting than yours !

Do you speak C#, XUL, javascript or even C/C++ ? Well, you might find some interesting stuff here, so take a tour !

This blog exists to share the solutions to the problems I have been through while programming, share the tips I can give and show some creations of mine.

Firsts posts coming soon,

Thanks for reading and please feel free to leave comments !

Anthony