Apr 22, 2011

Default xmodmap for Lenovo ThinkPad R500

If you messed up your xmodmap key mapping like I did. Find below (collapsed) the default key mapping for a Lenovo ThinkPad R500.

keycode 0x09 = Escape  NoSymbol Escape
keycode 0x43 = F1  XF86_Switch_VT_1 F1  XF86_Switch_VT_1
keycode 0x44 = F2  XF86_Switch_VT_2 F2  XF86_Switch_VT_2
keycode 0x45 = F3  XF86_Switch_VT_3 F3  XF86_Switch_VT_3
keycode 0x46 = F4  XF86_Switch_VT_4 F4  XF86_Switch_VT_4
keycode 0x47 = F5  XF86_Switch_VT_5 F5  XF86_Switch_VT_5
keycode 0x48 = F6  XF86_Switch_VT_6 F6  XF86_Switch_VT_6
keycode 0x49 = F7  XF86_Switch_VT_7 F7  XF86_Switch_VT_7
keycode 0x4A = F8  XF86_Switch_VT_8 F8  XF86_Switch_VT_8
keycode 0x4B = F9  XF86_Switch_VT_9 F9  XF86_Switch_VT_9
keycode 0x4C = F10  XF86_Switch_VT_10 F10  XF86_Switch_VT_10
keycode 0x5F = F11  XF86_Switch_VT_11 F11  XF86_Switch_VT_11
keycode 0x60 = F12  XF86_Switch_VT_12 F12  XF86_Switch_VT_12
keycode 0x6F = Up  NoSymbol Up
keycode 0x4E = Scroll_Lock NoSymbol Scroll_Lock
keycode 0x6E = Home  NoSymbol Home
keycode 0x31 = grave  asciitilde grave  asciitilde
keycode 0x0A = 1  exclam  1  exclam
keycode 0x0B = 2  at  2  at
keycode 0x0C = 3  numbersign 3  numbersign
keycode 0x0D = 4  dollar  4  dollar
keycode 0x0E = 5  percent  5  percent
keycode 0x0F = 6  asciicircum 6  asciicircum
keycode 0x10 = 7  ampersand 7  ampersand
keycode 0x11 = 8  asterisk 8  asterisk
keycode 0x12 = 9  parenleft 9  parenleft
keycode 0x13 = 0  parenright 0  parenright
keycode 0x14 = minus  underscore minus  underscore
keycode 0x15 = equal  plus  equal  plus
keycode 0x16 = BackSpace NoSymbol BackSpace
keycode 0x6A = KP_Divide XF86_Ungrab KP_Divide XF86_Ungrab
keycode 0x61 = NoSymbol
keycode 0x63 = Hiragana NoSymbol Hiragana
keycode 0x4D = Num_Lock Pointer_EnableKeys Num_Lock Pointer_EnableKeys
keycode 0x70 = Prior  NoSymbol Prior
keycode 0x3F = KP_Multiply XF86_ClearGrab KP_Multiply XF86_ClearGrab
keycode 0x52 = KP_Subtract XF86_Prev_VMode KP_Subtract XF86_Prev_VMode
keycode 0x17 = Tab  ISO_Left_Tab Tab  ISO_Left_Tab
keycode 0x18 = q  Q  q  Q
keycode 0x19 = w  W  w  W
keycode 0x1A = e  E  e  E
keycode 0x1B = r  R  r  R
keycode 0x1C = t  T  t  T
keycode 0x1D = y  Y  y  Y
keycode 0x1E = u  U  u  U
keycode 0x1F = i  I  i  I
keycode 0x20 = o  O  o  O
keycode 0x21 = p  P  p  P
keycode 0x22 = bracketleft braceleft bracketleft braceleft
keycode 0x23 = bracketright braceright bracketright braceright
keycode 0x24 = Return  NoSymbol Return
keycode 0x6B = Print  Sys_Req  Print  Sys_Req
keycode 0x67 = NoSymbol
keycode 0x69 = Control_R NoSymbol Control_R
keycode 0x4F = KP_Home  KP_7  KP_Home  KP_7
keycode 0x50 = KP_Up  KP_8  KP_Up  KP_8
keycode 0x51 = KP_Prior KP_9  KP_Prior KP_9
keycode 0x56 = KP_Add  XF86_Next_VMode KP_Add  XF86_Next_VMode
keycode 0x42 = Caps_Lock NoSymbol Caps_Lock
keycode 0x26 = a  A  a  A
keycode 0x27 = s  S  s  S
keycode 0x28 = d  D  d  D
keycode 0x29 = f  F  f  F
keycode 0x2A = g  G  g  G
keycode 0x2B = h  H  h  H
keycode 0x2C = j  J  j  J
keycode 0x2D = k  K  k  K
keycode 0x2E = l  L  l  L
keycode 0x2F = semicolon colon  semicolon colon
keycode 0x30 = apostrophe quotedbl apostrophe quotedbl
keycode 0x33 = backslash bar  backslash bar
keycode 0x53 = KP_Left  KP_4  KP_Left  KP_4
keycode 0x54 = KP_Begin KP_5  KP_Begin KP_5
keycode 0x55 = KP_Right KP_6  KP_Right KP_6
keycode 0x32 = Shift_L  NoSymbol Shift_L
keycode 0x5E = less  greater  less  greater  bar  brokenbar
keycode 0x34 = z  Z  z  Z
keycode 0x35 = x  X  x  X
keycode 0x36 = c  C  c  C
keycode 0x37 = v  V  v  V
keycode 0x38 = b  B  b  B
keycode 0x39 = n  N  n  N
keycode 0x3A = m  M  m  M
keycode 0x3B = comma  less  comma  less
keycode 0x3C = period  greater  period  greater
keycode 0x3D = slash  question slash  question
keycode 0x3E = Shift_R  NoSymbol Shift_R
keycode 0x62 = Katakana NoSymbol Katakana
keycode 0x57 = KP_End  KP_1  KP_End  KP_1
keycode 0x58 = KP_Down  KP_2  KP_Down  KP_2
keycode 0x59 = KP_Next  KP_3  KP_Next  KP_3
keycode 0x6C = Alt_R  Meta_R  Alt_R  Meta_R
keycode 0x25 = Control_L NoSymbol Control_L
keycode 0x73 = End  NoSymbol End
keycode 0x40 = Alt_L  Meta_L  Alt_L  Meta_L
keycode 0x41 = space  NoSymbol space
keycode 0x71 = Left  NoSymbol Left
keycode 0x74 = Down  NoSymbol Down
keycode 0x75 = Next  NoSymbol Next
keycode 0x6D = Linefeed NoSymbol Linefeed
keycode 0x64 = Henkan_Mode NoSymbol Henkan_Mode
keycode 0x68 = KP_Enter NoSymbol KP_Enter
keycode 0x66 = Muhenkan NoSymbol Muhenkan
keycode 0x5A = KP_Insert KP_0  KP_Insert KP_0
keycode 0x5B = KP_Delete KP_Decimal KP_Delete KP_Decimal

clear Shift
clear Lock
clear Control
clear Mod1
clear Mod2
clear Mod3
clear Mod4
clear Mod5

add    Shift   = Shift_L Shift_R
add    Control = Control_L Control_R
add    Mod1    = Alt_L Alt_R 0x00CD
add    Mod2    = Num_Lock
add    Mod4    = Super_L Super_R 0x00CE 0x00CF
add    Mod5    = ISO_Level3_Shift Mode_switch
add    lock    = Caps_Lock

Oct 15, 2010

WPF DataGrid Controlling the Scrollbar

I just started with WPF controls and one of the issues I came through is controlling the scrollbar in WPF objects. In WPF you have logical and visual trees. To get the scrollbar, Microsoft recommendation is to go trough the tree to get the scroll bar. So find my implementation below.

/// Method to get scrollbar in a visual object
private static ScrollViewer GetScrollbar(DependencyObject dep)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
    {
        var child = VisualTreeHelper.GetChild(dep, i);
        if (child != null && child is ScrollViewer)
            return child as ScrollViewer;
        else
        {
            ScrollViewer sub = GetScrollbar(child);
            if (sub != null)
                return sub;
        }
    }
    return null;
}

ScrollViewer scrollView = GetScrollbar(myDataGrid);

It should work with other objects too, but I only tried with a WPF Datagrid.  I lost some time to figure out how to do this, hope it helps.

Sep 23, 2010

DataGridView Reentrant Error

The events on a datagridview seems to be unstable when there is a need to repopulate a datagridview within its events. It does makes sense as if you have a trigger on any change and to populate the grid, it can lead to an infinite loop. One of the errors I encountered was

System.InvalidOperationException was unhandled
Message="Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function."

In fact I had to repopulate the datagridview on CellEndEdit. I Googled a lot about it and found some solutions. I came up to something, which I am not sure is the most efficient one, but it works.

public delegate void InvokeDelegate();

private void datagrid_changed(object sender, EventArgs e)
{
    this.dataGridView.BeginInvoke(new InvokeDelegate(ModifyGrid));
}

private void ModifyGrid()
{
    // Method implemented to change datasource
}

Instead of modifying the datasource directly, I had to pass though a delegated called by BeginInvoke. It should work fine.

In WPF DataGrid it is as follows:

private void dataGridLines_RowEditEnding(object sender, EventArgs e)
{
    Dispatcher.BeginInvoke(new InvokeDelegate(InsertRow), null);
}

Sep 20, 2010

Dynamic Inline Styling

Microsoft Outlook 2007 and also the version 2010 are very bad at rendering HTML. They use Word to render HTML! There has been holly war on this issue but we have to deal with it for years to come.

Let me explain the problem briefly, emails in general requires inline styling as webmails like Gmail and Hotmail strips all stylesheet files. Outlook is the worst and needs table, so generally speaking if you want the email to appear correctly, the email must be done in tables with inline styling. When many websites are running on the same code, it is difficult to use the same email template for all sites. The quick solution would be to create a template for each one. But let me suggest another idea.

What I did was that the email template was made the same with classes, just as you would do for a site:
<table border="0" cellspacing="0" class="tableContent">{some content}</table>

Afterwards, the css file is not actually a css file, but a php file that contains an array, it will all make sense afterwards:
$style_email['class="tableContent"'] = 'style="font-family:tahoma, arial; font-size:11px; color:#222222;"';

All the styles are defined like that, then just do a str_replace, the $email_order contains the email template:
global $style_email;

//include default css
include (DEFAULT_CSS);

//overwrite some css if needed
if (file_exists (SITE_CSS)) {
    include (SITE_CSS);
}

foreach($style_email as $key=>$value) {
    $inline_email_template = str_replace($key, $value, $email_template);
}

It is pretty neat and works really well, you can continue further more, by including the default css first and then including the particular css and strip div and span tags. There you are, the email can be coded with class and it will be shown on all browsers.

Hello there!

Hello there! This is Kervin Ramen. I am tying out blogging experience with Blogger.