Sybase ASE: Get one line for each value of a column

Let’s assume you have such a table:

CREATE TABLE benohead(SP1 int, SP2 int, SP3 int)

Column SP1 has non unique values and you want to keep only one row per unique SP1 value.

Assuming we have inserted the following values in the table:

INSERT INTO benohead VALUES(1,2,3)
INSERT INTO benohead VALUES(1,4,5)
INSERT INTO benohead VALUES(1,6,7)
INSERT INTO benohead VALUES(2,3,2)
INSERT INTO benohead VALUES(3,4,6)
INSERT INTO benohead VALUES(3,7,8)
INSERT INTO benohead VALUES(4,1,7)

It’d look like this:

SP1         SP2         SP3
----------- ----------- -----------
          1           2           3
          1           4           5
          1           6           7
          2           3           2
          3           4           6
          3           7           8
          4           1           7

Since SP2 and SP3 can have any value and you could also have rows where all 3 fields have the same value, it’s not so trivial to get a list looking like this:

SP1         SP2         SP3
----------- ----------- -----------
          1           6           7
          2           3           2
          3           7           8
          4           1           7

Even if the table is sorted, iterating through the rows and keeping track of the last SP1 you’ve seen will not help you since you cannot delete the second row because you do not have anything to identify it (like ROW_COUNT in Oracle).

One way to handle it is getting a list of unique SP1 values and their row count:

SELECT SP1, count(*) as rcount FROM benohead GROUP BY SP1

This will return something like this:

SP1         rcount
----------- -----------
          1           3
          2           1
          3           2
          4           1

You can then iterate through this and for each value of SP1 set a rowcount to rcount-1 and delete entries with that SP1 value. In the end, you’ll have one row per SP1 values. Of course, if you just need the data and do not want to actually clean up the table, you’ll have to do it on a copy of the table.

Instead of deleting, you can also iterate through the values of SP1 and fetch the top 1 row for this value:

SELECT TOP 1 SP1, SP2, SP3 FROM benohead WHERE SP1=1

If you had only one additional column (e.g. SP2), it’d be even easier, since you could just use MAX and GROUP BY:

SELECT SP1, MAX(SP2) AS SP2 FROM benohead GROUP BY SP1

which returns:

SP1         SP2
----------- -----------
          1           6
          2           3
          3           7
          4           1

Unfortunately this doesn’t scale to multiple columns. If you also have SP3, you cannot use MAX twice since you will then combinations which didn’t exist in the original table. Let’s insert an additional row:

INSERT INTO benohead VALUES(1,1,9)

The following statement:

SELECT SP1, MAX(SP2) AS SP2, MAX(SP3) AS SP3 FROM benohead GROUP BY SP1

will return:

 SP1         SP2         SP3
 ----------- ----------- -----------
           1           6           9
           2           3           2
           3           7           8
           4           1           7

Although we had no row with SP1=1, SP2=6 and SP3=9.

So if you don’t like the solution iterating and delete with rowcount, you’ll need to introduce a way to uniquely identify each row: an identity column.

You can add an identity column to the table:

ALTER TABLE benohead ADD ID int identity

And them select the required rows like this:

SELECT * from benohead b WHERE b.ID = (SELECT MAX(ID) FROM benohead b2 WHERE b.SP1=b2.SP1)

This will fetch for each value of SP1 the row with the highest ID.

Or you can create a temporary table with an indentity column:

SELECT ID=identity(1), SP1, SP2, SP3 INTO #benohead FROM benohead	

And then use a similar statement on the temporary table.

 

JavaScript: Tracing performance to the console

I wanted to trace the performance of Ajax call in a project I’m working on. The obvious place to store this kind of information is the developer console. If your browser supports debugging, you can writen to the console object and display it in the browser. You should be able to open it in most browsers by pressing F12 or Ctrl-Shift-I.

Elapsed time

You’ve probably already used console.log or console.debug but the console global JavaScript object does provide many more functions. Two of them which are useful in our use case are:

  1. console.time()
  2. console.timeEnd()

They both take a timer name and when time() is called a timer with this name will be started. When timeEnd() is called the specified timer is stopped and the elapsed time since its start in milliseconds is logged to the console at the Info level. Here is how the ouput looks like in Firefox:

console time

Your code would look like this:

console.time("refreshGrid");
// refresh the grid
console.timeEnd("refreshGrid");
console.time("fillGrid");
// fill the grid
console.timeEnd("fillGrid");

You can also have an outer timer logging the total time an operation lasts and some inner timers logging the time for individual steps:

console.time("total");

console.time("refreshGrid");
// refresh the grid
console.timeEnd("refreshGrid");

console.time("fillGrid");
// fill the grid
console.timeEnd("fillGrid");

console.timeEnd("total");

Timestamps

Another function of the console global JavaScript object which you could use is console.timeStamp() e.g.:

console.timeStamp("started");
// fill the grid
console.timeStamp("ended");

This will output the following to the console:

console timeStamp

If you are using Firefox, please note that the Firefox Web Console doesn’t support the console.timeStamp(). But Firebug does. So if you want to use it, you’ll need to install Firebug which is an awesome plugin anyway.

Check for existence

Another thing you have to keep in mind is that although these console functions are pretty well supported by most popular browsers they do not seem to be part of any specification and you might find some browsers (e.g. mobile browser) which do not support them. Calling these functions in such a browser will cause you JavaScript code to fail. So you should either make sure that you only use this in your development environment but do not push it to you production site or at least check whether the console object and its functions exist:

if (console && console.time) { console.time("test"); }
if (console && console.timeEnd) { console.timeEnd("test"); }
if (console && console.timeStamp) { console.timeStamp("test"); }

Internet Explorer 8 doesn’t support the console global JavaScript object. Internet Explorer 11 does. It also looks like Internet Explorer 10 also supports this but I couldn’t check it.

Network calls

If all you’re after is to check how long your Ajax calls to the server last, you can just use the network call analyzer available in the developer tools of your favorite browser.

In Chrome it looks like this:

Network tab Chrome

In Firebug (Firefox plugin):

Network tab Firebug

Note that in Firefox you can get the same information without Firebug, in the Web Console:

Network tab Firefox

It’s still a good idea to use Firebug which is a great plugin. But you don’t need it if all you’re after is this type of information.

 

Generate icons for checkboxes

Instead of using this square check boxes you can also set your own images using the three following methods of JCheckBox:

  • setIcon to set the default icon.
  • setSelectedIcon to set the icon displayed when the box is checked.
  • setDisabledIcon to set the icon used when the box is disabled.

Now I mostly need the same image as the default image for selected and disabled icon with either an outline when it’s selected or grayed out if disabled.
So that I don’t have to set those three icons manually each time, I’ve subclassed JCheckBox so that the setIcon sets all three icons:

public void setIcon(Icon defaultIcon) {
	super.setIcon(defaultIcon);
	// New icon should have the same size
	int height = defaultIcon.getIconHeight();
	int width = defaultIcon.getIconWidth();
	// Get an image with the icon
	BufferedImage image = new BufferedImage(width, height,
			BufferedImage.TYPE_INT_ARGB);
	Graphics2D g2 = image.createGraphics();
	// First paint the icon
	defaultIcon.paintIcon(this, g2, 0, 0);
	// Buffer for the new image
	BufferedImage selected = new BufferedImage(width, height,
			BufferedImage.TYPE_INT_ARGB);
	g2 = selected.createGraphics();
	// Draw the original icon
	g2.drawImage(image, null, 0, 0);
	// Create the stroke for the outline
	g2.setColor(UIManager.getColor("CheckBox.outlineColor"));
	int strokeSize = (int) (.15 * width);
	g2.setStroke(new BasicStroke(strokeSize, BasicStroke.CAP_ROUND,
			BasicStroke.JOIN_ROUND));
	// Then draw the outline
	g2.drawRoundRect(0, 0, width, height, height, height);
	// And create an ImageIcon to use as selected icon
	setSelectedIcon(new ImageIcon(selected));
	// For the disabled icon we just apply a gray filter
	ImageFilter filter = new GrayFilter(false, 0);
	// Apply the filter to the original image
	Image disabled = createImage(new FilteredImageSource(image.getSource(),
			filter));
	// And create an ImageIcon to use as disabled icon
	setDisabledIcon(new ImageIcon(disabled));
}

Now I just need to set one of them and the others are created automatically. The result looks like this:
checkboxes
Of course the outline shouldn’t be so thick and the icon already should provide space for the outline.

Java: Vertical Label in Swing

This is an article I’ve published over 8 years ago on jroller. I’ve now republished it on my current blog because I was asked to clarify the license terms (see next paragraph) and I found it better to do it here than to update a post on a blog I’m not maintaining anymore.

License clarification: You can use the code of any article on this blog as you wish. I’ve just published this code in the hope to be helpful and do not expect anything in return. So from my point of view you can consider it being released under the WTFPL license terms.

Today, let’s see how to implement a vertical label in Swing. This component should extend JLabel and provide the possibility to rotate 90° to the right or to the left.

Like normal JLabel, it should work whether it contains an icon, a text or both.

Here’s a screenshot of how it should look like:

vertical label

The label with a rotation to the left, no rotation and a rotation to the right.

So that the label painted according to the current look and feel, I didn’t want to paint it myself but to delegate it and rotate it.

In order to do this, I had to rotate and translate the graphics object. The remaining problem is that the UI delegate uses some methods of the label to get the size of the component and the insets. So we have to trick the UI delegate into thinking that the component is horizontal and not vertical.

  public Insets getInsets(Insets insets) {
        insets = super.getInsets(insets);
        if (painting) {
            if (rotation == ROTATE_LEFT) {
                int temp = insets.bottom;
                insets.bottom = insets.left;
                insets.left = insets.top;
                insets.top = insets.right;
                insets.right = temp;
            }
            else if (rotation == ROTATE_RIGHT) {
                int temp = insets.bottom;
                insets.bottom = insets.right;
                insets.right = insets.top;
                insets.top = insets.left;
                insets.left = temp;
            }
        }
        return insets;
    }
    public Insets getInsets() {
        Insets insets = super.getInsets();
        if (painting) {
            if (rotation == ROTATE_LEFT) {
                int temp = insets.bottom;
                insets.bottom = insets.left;
                insets.left = insets.top;
                insets.top = insets.right;
                insets.right = temp;
            }
            else if (rotation == ROTATE_RIGHT) {
                int temp = insets.bottom;
                insets.bottom = insets.right;
                insets.right = insets.top;
                insets.top = insets.left;
                insets.left = temp;
            }
        }
        return insets;
    }
    public int getWidth() {
        if ((painting) && (isRotated()))
            return super.getHeight();
        return super.getWidth();
    }
    public int getHeight() {
        if ((painting) && (isRotated()))
            return super.getWidth();
        return super.getHeight();
    }

The painting variable is set in the paintComponent method just before calling the method of the super class:

protected void paintComponent(Graphics g) {
	Graphics2D g2d = (Graphics2D) g;

	if (isRotated())
		g2d.rotate(Math.toRadians(90 * rotation));
	if (rotation == ROTATE_RIGHT)
		g2d.translate(0, -this.getWidth());
	else if (rotation == ROTATE_LEFT)
		g2d.translate(-this.getHeight(), 0);
	painting = true;

	super.paintComponent(g2d);

	painting = false;
	if (isRotated())
		g2d.rotate(-Math.toRadians(90 * rotation));
	if (rotation == ROTATE_RIGHT)
		g2d.translate(-this.getWidth(), 0);
	else if (rotation == ROTATE_LEFT)
		g2d.translate(0, -this.getHeight());
}

Now one remaining problem is that a normal label uses the icon and the text to compute it’s preferred, minimum and maximum size assuming it’s layed out horizontally. Now the layour managers use this methods to layout the components. So we need to return sizes based on a vertical layout. Since we do not want to compute the sizes ourselves, we have to let the super class compute it and switch height and width (when there’s a rotation):

public Dimension getPreferredSize() {
	Dimension d = super.getPreferredSize();
	if (isRotated()) {
		int width = d.width;
		d.width = d.height;
		d.height = width;
	}
	return d;
}

public Dimension getMinimumSize() {
	Dimension d = super.getMinimumSize();
	if (isRotated()) {
		int width = d.width;
		d.width = d.height;
		d.height = width;
	}
	return d;
}

public Dimension getMaximumSize() {
	Dimension d = super.getMaximumSize();
	if (isRotated()) {
		int width = d.width;
		d.width = d.height + 10;
		d.height = width + 10;
	}
	return d;
}

That’s it, now our component behaves exactly like a JLabel except that it can be rotated to the left or to the right. The whole source code here for your reference:

package org.jroller.henribenoit.swing;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;

public class VerticalLabel extends JLabel {
    public final static int ROTATE_RIGHT = 1;

    public final static int DONT_ROTATE = 0;

    public final static int ROTATE_LEFT = -1;

    private int rotation = DONT_ROTATE;

    private boolean painting = false;

    public VerticalLabel() {
        super();
    }

    public VerticalLabel(Icon image, int horizontalAlignment) {
        super(image, horizontalAlignment);
    }

    public VerticalLabel(Icon image) {
        super(image);
    }

    public VerticalLabel(String text, Icon icon, int horizontalAlignment) {
        super(text, icon, horizontalAlignment);
    }

    public VerticalLabel(String text, int horizontalAlignment) {
        super(text, horizontalAlignment);
    }

    public VerticalLabel(String text) {
        super(text);
    }

    public int getRotation() {
        return rotation;
    }

    public void setRotation(int rotation) {
        this.rotation = rotation;
    }

    public boolean isRotated() {
        return rotation != DONT_ROTATE;
    }

    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;

        if (isRotated())
            g2d.rotate(Math.toRadians(90 * rotation));
        if (rotation == ROTATE_RIGHT)
            g2d.translate(0, -this.getWidth());
        else if (rotation == ROTATE_LEFT)
            g2d.translate(-this.getHeight(), 0);
        painting = true;

        super.paintComponent(g2d);

        painting = false;
        if (isRotated())
            g2d.rotate(-Math.toRadians(90 * rotation));
        if (rotation == ROTATE_RIGHT)
            g2d.translate(-this.getWidth(), 0);
        else if (rotation == ROTATE_LEFT)
            g2d.translate(0, -this.getHeight());
    }

    public Insets getInsets(Insets insets) {
        insets = super.getInsets(insets);
        if (painting) {
            if (rotation == ROTATE_LEFT) {
                int temp = insets.bottom;
                insets.bottom = insets.left;
                insets.left = insets.top;
                insets.top = insets.right;
                insets.right = temp;
            }
            else if (rotation == ROTATE_RIGHT) {
                int temp = insets.bottom;
                insets.bottom = insets.right;
                insets.right = insets.top;
                insets.top = insets.left;
                insets.left = temp;
            }
        }
        return insets;
    }

    public Insets getInsets() {
        Insets insets = super.getInsets();
        if (painting) {
            if (rotation == ROTATE_LEFT) {
                int temp = insets.bottom;
                insets.bottom = insets.left;
                insets.left = insets.top;
                insets.top = insets.right;
                insets.right = temp;
            }
            else if (rotation == ROTATE_RIGHT) {
                int temp = insets.bottom;
                insets.bottom = insets.right;
                insets.right = insets.top;
                insets.top = insets.left;
                insets.left = temp;
            }
        }
        return insets;
    }

    public int getWidth() {
        if ((painting) && (isRotated()))
            return super.getHeight();
        return super.getWidth();
    }

    public int getHeight() {
        if ((painting) && (isRotated()))
            return super.getWidth();
        return super.getHeight();
    }

    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        if (isRotated()) {
            int width = d.width;
            d.width = d.height;
            d.height = width;
        }
        return d;
    }

    public Dimension getMinimumSize() {
        Dimension d = super.getMinimumSize();
        if (isRotated()) {
            int width = d.width;
            d.width = d.height;
            d.height = width;
        }
        return d;
    }

    public Dimension getMaximumSize() {
        Dimension d = super.getMaximumSize();
        if (isRotated()) {
            int width = d.width;
            d.width = d.height + 10;
            d.height = width + 10;
        }
        return d;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new FlowLayout());
        VerticalLabel label = new VerticalLabel("Testing something");
        VerticalLabel label2 = new VerticalLabel("Testing something");
        VerticalLabel label3 = new VerticalLabel("Testing something");
        label.setIcon(new ImageIcon("shortcut.png"));
        label2.setIcon(new ImageIcon("shortcut.png"));
        label3.setIcon(new ImageIcon("shortcut.png"));
        label.setRotation(VerticalLabel.ROTATE_LEFT);
        label2.setRotation(VerticalLabel.DONT_ROTATE);
        label3.setRotation(VerticalLabel.ROTATE_RIGHT);
        frame.getContentPane().add(label);
        frame.getContentPane().add(label2);
        frame.getContentPane().add(label3);
        frame.pack();
        frame.setVisible(true);
    }
}

 

Sybase ASE Cookbook Update

I’ve written this cookbook about 10 months ago. It basically contains all the information about Sybase ASE I’ve documented on my blog over the years. I use it when I need offline access to some tricks (since I’m not getting younger, it’s sometimes useful to have a kind of brain dump somewhere). I also compiled it and published it here in the hope that someone else might find it useful.

I’ve just updated the cookbook with a few new things. But it’s really a small update.

This cookbook is still available for free. And I am still no professional writer and still cannot afford paying someone for proof-read it. So if you notice any mistakes, explanations which cannot be understood or anything like this, please leave a comment here or contact me at henri.benoit@gmail.com. I can’t guarantee how fast I can fix mistakes but I’ll do my best to do it in a timely manner.

Benohead Sybase ASE Cookbook

Downloading files and directories via SFTP using SSH.Net

SSH.NET is a .NET library implementing the SSH2 client protocol. It is inspired by a port of the Java library JSch called Sharp.SSH. It allows you to execute SSH commands and also provides both SCP and SFTP functionality.

In this article, I’ll show you how to download a complete directory tree using SSH.NET.

First you’ll need to add a few usings:

using System;
using System.IO;
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;

SSH.NET can be added to your project using NuGet.

In order to work with SFTP, you’ll need to get an instance of SftpClient. You can either directly give details like host, port, username and password or you can provide a ConnectionInfo object. In this example we’ll use a KeyboardInteractiveConnectionInfo. This is required if the server expects an interactive keyboard authentication providing the password. The alternatives are PasswordConnectionInfo and PrivateKeyConnectionInfo.

First we’ll create the ConnectionInfo object:

var connectionInfo = new KeyboardInteractiveConnectionInfo(Host, Port, Username);

Host, Port and Username are constants I’ve defined before.

Then we need to define a delegate which will get the prompts returned by the server and will send the password when requested:

connectionInfo.AuthenticationPrompt += delegate(object sender, AuthenticationPromptEventArgs e)
{
	foreach (var prompt in e.Prompts)
	{
		if (prompt.Request.Equals("Password: ", StringComparison.InvariantCultureIgnoreCase))
		{
			prompt.Response = Password;
		}
	}
};

It waits for the prompt “Password: ” and sends the password I’ve defined in a constant called Password.

Then using this SFTP client, we’ll connect to the server and download the contents of the directory recursively:

using (var client = new SftpClient(connectionInfo))
{
	client.Connect();
	DownloadDirectory(client, Source, Destination);
}

Source is the directory you want to download on the remote server and destination is the local directory e.g.:

private const string Source = "/tmp";
private const string Destination = @"c:\temp";

Now we’ll define the DownloadDirectory method. It will get the directory listing and iterate through the entries. Files will be downloaded and for each directory in there, we’ll recursively call the DownloadDirectory method:

private static void DownloadDirectory(SftpClient client, string source, string destination)
{
	var files = client.ListDirectory(source);
	foreach (var file in files)
	{
		if (!file.IsDirectory && !file.IsSymbolicLink)
		{
			DownloadFile(client, file, destination);
		}
		else if (file.IsSymbolicLink)
		{
			Console.WriteLine("Ignoring symbolic link {0}", file.FullName);
		}
		else if (file.Name != "." && file.Name != "..")
		{
			var dir = Directory.CreateDirectory(Path.Combine(destination, file.Name));
			DownloadDirectory(client, file.FullName, dir.FullName);
		}
	}
}

I am ignoring symbolic links because trying to download them just fails and the SftpFile class provides no way to find what this link points to. “.” and “..” are also ignored.

Now let’s see how to download a single file:

private static void DownloadFile(SftpClient client, SftpFile file, string directory)
{
	Console.WriteLine("Downloading {0}", file.FullName);
	using (Stream fileStream = File.OpenWrite(Path.Combine(directory, file.Name)))
	{
		client.DownloadFile(file.FullName, fileStream);
	}
}

It’s pretty easy: you create a file stream to the destination file and use the DownloadFile method of the SFTP client to download the file.

That’s it ! Here the full code for your convenience:

using System;
using System.IO;
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;

namespace ConsoleApplication1
{
    public static class SftpTest
    {
        private const string Host = "192.168.xxx.xxx";
        private const int Port = 22;
        private const string Username = "root";
        private const string Password = "xxxxxxxx";
        private const string Source = "/tmp";
        private const string Destination = @"c:\temp";

        public static void Main()
        {
            var connectionInfo = new KeyboardInteractiveConnectionInfo(Host, Port, Username);

            connectionInfo.AuthenticationPrompt += delegate(object sender, AuthenticationPromptEventArgs e)
            {
                foreach (var prompt in e.Prompts)
                {
                    if (prompt.Request.Equals("Password: ", StringComparison.InvariantCultureIgnoreCase))
                    {
                        prompt.Response = Password;
                    }
                }
            };

            using (var client = new SftpClient(connectionInfo))
            {
                client.Connect();
                DownloadDirectory(client, Source, Destination);
            }
        }

        private static void DownloadDirectory(SftpClient client, string source, string destination)
        {
            var files = client.ListDirectory(source);
            foreach (var file in files)
            {
                if (!file.IsDirectory && !file.IsSymbolicLink)
                {
                    DownloadFile(client, file, destination);
                }
                else if (file.IsSymbolicLink)
                {
                    Console.WriteLine("Ignoring symbolic link {0}", file.FullName);
                }
                else if (file.Name != "." && file.Name != "..")
                {
                    var dir = Directory.CreateDirectory(Path.Combine(destination, file.Name));
                    DownloadDirectory(client, file.FullName, dir.FullName);
                }
            }
        }

        private static void DownloadFile(SftpClient client, SftpFile file, string directory)
        {
            Console.WriteLine("Downloading {0}", file.FullName);
            using (Stream fileStream = File.OpenWrite(Path.Combine(directory, file.Name)))
            {
                client.DownloadFile(file.FullName, fileStream);
            }
        }
    }
}

So except for the issue with the symbolic link, it works pretty good and is also quite fast.

 

The c# project is targeting “.NET Framework,Version=v4.0″, which is not installed on this machine.

Since I needed some space on my hard disk to install some software I went through the list of installed software and saw that Visual Studio 2010 was installed but I actually only use Visual Studio 2012 (or Visual Studio 2005 for some very old stuff which hasn’t been ported yet). So I thought it makes sense to uninstall Visual Studio 2010. And ended up wasting alot of time…

After uninstalling VS 2010, I started getting the following message in VS2012 whenever I opened a project targeted at the .NET framework v4.0:

The C# project xxx is targeting ‘.NETFramework,Version=v4.0″, which is not installed on this machine. to proceed, you must select an option below.

1.Change the target to .NET Framework 4.5…..

2.Download the targeting pack for “.NET Framework, Version = v4.0″…

3.Do not load the project

When you choose option 2 you are redirected to a web page where you actually cannot download the v4.0 .NET framework. Checking in the registry, I saw that the .NET framework was gone. I also found the installation package for the .NET framework v4.0. Unfortunately, it refuses to install since the v4.5 framework is already installed.

So my next great idea was to uninstall the v4.5 framework. Then I could install the v4.0 version. Of course, after that VS 2012 wouldn’t start anymore. So I installed the v4.5 framework again. During the installation, it told me that it’s an in-place update for the v4.0 framework. I immediately thought that it might cause trouble but didn’t have a choice anyway. After installing the v4.5 framework VS2012 worked again but as expected, I still got the same error message when opening projects targeting the v4.0 framework.

Running out of other options, I finally reinstalled VS2010. It took forever but in the end I was able to open all projects in VS2012.

So this is kind of a waste of space but if you cannot have your project target the v4.5 framework but need to target the v4.0 framework, you will need to have VS2010 installed additionally to VS2012 (even though you actually do not need VS2010).

If anybody has found a solution not requiring VS2010 to stay installed, please leave a comment. My hard disk space is running low and I’d love to be able to get rid of VS2010.

Windows 7: empty pages displayed in CHM file

When opening a CHM file downloaded from Internet on a Windows Vista or Windows 7 machine, the file may not render properly and just show empty pages. All you’ll see no matter which page you select is an error message saying that “Navigation to the webpage was canceled” e.g.:

Navigation to the webpage was canceled

The problem is that the file comes from another computer and is blocked. It’s strange because you actually get a security warning when opening the file and one would expect that if you open it anyway, everything should be fine. Here an example of such a security warning:

Open File - Security Warning

The solution is to unblock the file. In order to do it, do not open the file directly from the browser but save it to disk, then right click on the file, choose Properties and unblock the file:

CHM file properties - Unblock

Now, when you open the file, no security warning will be displayed and the contents will be displayed properly.

Note that you should only unblock files that you trust.

If you do not see an Unblock button, you have either already unblocked it and it doesn’t work anymore (not exactly sure when this happens) or you might have stored the file on a file system which doesn’t support the Unblock feature (not sure but it looks like it only works on NTFS).

You can also implicitly unblock the file by unchecking “Always ask before opening this file” in the security warning shown above.

So this whole behavior seems not to be very consistent but fixing it was pretty straight forward.

Update: It looks like on Windows 8, you can unblock files from a PowerShell using the following commandlet:

Unblock-File .\SshNet.Help.chm

 

CSS: Google Plus Like Buttons

I guess most web sites are now using CSS to create nice looking buttons without using background images. Google has done a nice job creating clean looking buttons. I’ll show in this article how you can easily create similar looking buttons.

First regarding why it makes sense to use only CSS to create buttons instead of using background images:

  • The browser does not need to load images. This makes the page loading process faster.
  • It makes it easier to create scalable buttons which look good no matter how long the label on the button.
  • You just need to adapt the CSS style in order to get different styles of buttons.

As far as I could see, Google seems to be using 4 types of buttons in Google Plus:

Add
Save
Add
Post comment

First we’ll style the first button as our default button (the one with the white background):

.google-plus-button {
    -moz-user-select: none;
    -ms-user-select: none;
    -webkit-user-select: none;
    background-color: #fff;
    border: 1px solid #d4d4d4;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
    -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
    -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
    color: #404040;
    cursor: default;
    display: inline-block;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    font-weight: bold;
    height: 28px;
    line-height: 28px;
    margin-right: 0;
    min-width: 54px;
    outline: 0 none;
    padding: 0 8px;
    position: relative;
    text-align: center;
    white-space: nowrap;
    word-wrap: break-word;
}

The user-select: none properties are used to prevent text selection (the browser doesn’t know it’s a button).
Also the rounded corners will be square in Internet Explorer 8 and lower as well as in Opera Mini. And the box shadows will be missing in these browsers too.

Also note that I’m using the default cursor for the button because it’s the way it is in Google Plus. But if you’d rather have the pointer cursor used for links, just replace:

cursor: default;

by:

cursor: pointer;

You might have noticed that the labels on the buttons look a little bit different than on Google Plus, because they use the Roboto font. If you want to use it, you’ll need to get it from Google Fonts. But I personally use Arial which is close enough and has the advantage of already being available pretty much on every machine without having to reference an external resource which can have an impact on page load time. Anyway, in order to use the Roboto font, add the following code to the <head> tag of your website:

<link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>

And replace:

font-family: Arial, Helvetica, sans-serif;

By:

font-family: Roboto, Arial, ​sans-serif;

The next step is to add some styles so that it actually feels like a button:

.google-plus-button:hover {
    background-color: #fff;
    background-image: -moz-linear-gradient(center top , transparent, transparent);
    border: 1px solid #b8b8b8;
    -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
    -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
    color: #404040;
}
.google-plus-button:active {
    background: none repeat scroll 0 0 #e5e5e5;
    border-right: 1px solid transparent;
    -webkit-box-shadow: 0 2px 0 #ddd inset;
    -moz-box-shadow: 0 2px 0 #ddd inset;
    box-shadow: 0 2px 0 #ddd inset;
    color: #262626;
}

Now that we have our basic white button, we can style the other buttons which will get the red, green and blue classes:

.google-plus-button.green {
    background-color: #53a93f;
    border: 1px solid transparent;
    color: #fff;
}
.google-plus-button.green:hover {
    background-color: #65b045;
    border-color: transparent transparent #4c8534;
    -webkit-box-shadow: 0 -1px 0 #4c8534 inset;
    -moz-box-shadow: 0 -1px 0 #4c8534 inset;
    box-shadow: 0 -1px 0 #4c8534 inset;
}
.google-plus-button.green:active {
    background: none repeat scroll 0 0 #3e802f;
    border-color: #2f6124 transparent transparent;
    -webkit-box-shadow: 0 1px 0 #2f6124 inset;
    -moz-box-shadow: 0 1px 0 #2f6124 inset;
    box-shadow: 0 1px 0 #2f6124 inset;
}

.google-plus-button.red {
    background-color: #d73d32;
    border: 1px solid transparent;
    color: #fff;
}
.google-plus-button.red:hover {
    background-color: #e74b37;
    border-color: transparent transparent #bd3d2a;
    -webkit-box-shadow: 0 -1px 0 #bd3d2a inset;
    -moz-box-shadow: 0 -1px 0 #bd3d2a inset;
    box-shadow: 0 -1px 0 #bd3d2a inset;
}
.google-plus-button.red:active {
    background-color: #be3e2e;
    border-color: #9a3323 transparent transparent;
    -webkit-box-shadow: 0 1px 0 #9a3323 inset;
    -moz-box-shadow: 0 1px 0 #9a3323 inset;
    box-shadow: 0 1px 0 #9a3323 inset;
}

.google-plus-button.blue {
    background-color: #427fed;
    border: 1px solid transparent;
    color: #fff;
}
.google-plus-button.blue:hover {
    background-color: #4285f4;
    border-color: transparent transparent #2f69c2;
    -webkit-box-shadow: 0 -1px 0 #2f69c2 inset;
    -moz-box-shadow: 0 -1px 0 #2f69c2 inset;
    box-shadow: 0 -1px 0 #2f69c2 inset;
}
.google-plus-button.blue:active {
    background: none repeat scroll 0 0 #2c56b1;
    border-color: #21448d transparent transparent;
    -webkit-box-shadow: 0 1px 0 #21448d inset;
    -moz-box-shadow: 0 1px 0 #21448d inset;
    box-shadow: 0 1px 0 #21448d inset;
}

And here’s how you can use the buttons (the following code creates the four buttons at the top of the page):

<div class="google-plus-button">Add</div>
<div class="google-plus-button blue">Save</div>
<div class="google-plus-button red">Add</div>
<div class="google-plus-button green">Post comment</div>

These buttons use the usual Google colors. But you can of course define colors which will better fit to the styles of your website but still provide the clean and polished look of the Google Plus buttons e.g.:

Google Plus Buttons other colors

Feel free to leave a comment if you spot a problem, have a suggestion how to improve them or just like them.

 

HTML5: Displaying the battery level

Note that this currently only works with Firefox. Support for Chrome and Internet Explorer is not yet available and it’s not yet known when it will be available.

The new Battery Status API allows you from a web page to access information about the battery status of the device rendering it. It is not only useful in order to show the current status but to implement battery status dependent logic e.g. increasing polling interval using Ajax or disabling animations in order to preserve the battery, or auto-saving in case the device goes out of power, prevent the user from performing long running operation which might not be able to finish because of the low remaining battery level.

First we’ll create the HTML and CSS in order to get an empty battery display looking like this:

The HTML code couldn’t be simpler. We just need a battery div:

<div id="battery"></div>

Now we need to display a border around the div and a smaller rectangle after it:

.battery:after {
    background-color: #fff;
    border: 2px solid #000;
    content: "";
    display: block;
    height: 16px;
    position: absolute;
    right: -6px;
    top: 6px;
    width: 6px;
}
.battery {
    background-color: #fff;
    border: 2px solid #000;
    height: 32px;
    margin-left: auto;
    margin-right: auto;
    position: relative;
    width: 100px;
}

Then we need to display a battery level within the battery display:

<div id="battery"><div id="battery-level"></div></div>

And we just need to add some CSS:

.battery .battery-level {
    background-color: #666;
    height: 100%;
}

By setting the width of .battery-level in pixels (or in percent which is the same since the element is 100 pixels wide) to the battery level in percents, we’ll get the right display:

Of course, one would expect our battery level display to show the level in a different color depending whether the battery is almost empty or not. So let’s introduce three CSS classes which will show the level in green, yellow or red:

Using the following CSS code:

.battery .battery-level.high {
    background-color: #66CD00;
}
.battery .battery-level.medium {
    background-color: #FCD116;
}
.battery .battery-level.low {
    background-color: #FF3333;
}

Before we move to the HTML5 part, let’s also display the battery level as text, by setting it as text on the battery-level element and by adding the following css rule:

.battery .battery-level {
    text-align: center;
}

It then looks like this:

10%
75%
95%

Now we’re almost done… All we need is what’s actually the main topic of this post: to get the battery level data using HTML5. For this we need to use the new Battery Status API.

The Battery Status API provides access the battery information through navigator.battery which implement the BatteryManager interface. This interface provides the following information:

  • whether the battery is currently charging
  • the charging time
  • the discharging time
  • the battery level

Additionally, it also provides events you can listen to:

  • onchargingchange
  • onchargingtimechange
  • ondischargingtimechange
  • onlevelchange

We will not use the events for now and just show the battery level when the page was loaded:

The JavaScript code to work with this API is pretty straight forward:

var battery = navigator.battery;
var level    = battery.level * 100;
var batteryLevel = jQuery('.battery .battery-level');
batteryLevel.css('width', level + '%');
batteryLevel.text(level + '%');
if (battery.charging) {
    batteryLevel.addClass('charging');
} else if (level > 50) {  
    batteryLevel.addClass('high');  
} else if (level >= 25 ) {  
    batteryLevel.addClass('medium');  
} else {  
    batteryLevel.addClass('low');  
}

If you want to update the battery level display as the battery charges and discharges:

Here’s the JavaScript code:

function updateBatteryDisplay(battery) {
	var level = battery.level * 100;
	var batteryLevel = jQuery('.battery .battery-level');
	batteryLevel.css('width', level + '%');
	batteryLevel.text(level + '%');
	if (battery.charging) {
	    batteryLevel.addClass('charging');
	    batteryLevel.removeClass('high');  
	    batteryLevel.removeClass('medium');  
	    batteryLevel.removeClass('low');  
	} else if (level > 50) {  
	    batteryLevel.addClass('high');  
	    batteryLevel.removeClass('charging');
	    batteryLevel.removeClass('medium');  
	    batteryLevel.removeClass('low');  
	} else if (level >= 25 ) {  
	    batteryLevel.addClass('medium');  
	    batteryLevel.removeClass('charging');
	    batteryLevel.removeClass('high');  
	    batteryLevel.removeClass('low');  
	} else {  
	    batteryLevel.addClass('low');  
	    batteryLevel.removeClass('charging');
	    batteryLevel.removeClass('high');  
	    batteryLevel.removeClass('medium');  
	}
}

var battery = navigator.battery;
updateBatteryDisplay(battery);
battery.onchargingchange = function () {
    updateBatteryDisplay(battery);
};
battery.onlevelchange = function () {
    updateBatteryDisplay(battery);
};

So the Battery Status API is a very powerful and useful API which is very easy to use. Now let’s hope it will soon be available in all major browsers !