Saturday, September 10, 2011

Add Zoom Image Feature to Blogger

Recently Google's BLogger has been redesigned with much more new features. The original openness features are still available. Still I don't like the way in Blogger to resize images in narrow width so that it is hard to see. I understand that exploded image would distract the whole blog layout. Therefore, I have been thinking about adding a feature to zoom images in Blogger.

Last weekend I spent about whole day to find a suitable solution and enhanced it with my updates.  The strategy is based on jQuery and CSS. I found it in a blog in CSS Globe. It is really easy to use. Add a CSS and two script links to Blogger HTML settings first. After that it is ready for use.

For example, to add zoom feature to an image in blog, add class called as "zoom" to the image's parent anchor HTML tag:

<a class="zoom" href="test.png">
  <img src="test2.png" border="0" width="300">
</a>

It works great; however, there is one thing I found not perfect. In case of an image with narrow height, there is a big gap on the top in its zoomed image. I would like to let the zoom image auto-adjust its height: either to the image height to at most the height defined in the CSS.

Here are the steps to add my enhanced zoom feature to Blogger.

Update Blogger HTML Settings

The first thing to do is to update your Blogger HTML settings. It is recommended to backup your HTML settings before any changes.

Step 1. In your Blogger Dashboard, click Template and then Edit HTML

Step 2. Find your blog CSS sections. Those CSS definitions should be ended by

]]></b:skin>

Step 3. Copy and post the following CSS codes into your CSS sections before ]]></b:skin>

/*  following css for zoom effect is copied from
http://www.spiceupyourblog.com/2011/05/amazing-jquery-image-zoom-effect-for.html
*/

#easy_zoom{
  /* default width and height, those settings can be optionally set in
     anchor element attribute: zoomboxwidth and zoomboxheight */
  width:500px;
  height:400px;
  border:5px solid #eee;
  background:#fff;
  color:#333;
  position:fixed;
  top:35px;
  left:50%;
  overflow:hidden;
  -moz-box-shadow:0 0 10px #555;
  -webkit-box-shadow:0 0 10px #555;
  box-shadow:0 0 10px #555;
  /* vertical and horizontal alignment used for preloader text */
  line-height:400px;
  text-align:center;
}

The top and left values are the position of zoom box.  You adjust above top and left values for your blogger template.  The width and height values are default zoom box size.   You may change them according to your needs.

Step 4. Find the following piece of codes in your HTML template:

<head>

This is the end of head tag in your HTML template.

Step 5. Before the head tag, copy the following codes:

<!-- the following scripts for zoom effect are copied from 
http://www.spiceupyourblog.com/2011/05/amazing-jquery-image-zoom-effect-for.html
add class="zoom" in image a tag and it will have zoom effect!
 -->

<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js' type='text/javascript'/>
<script src='http://davidchu-javascript-libraries.googlecode.com/files/easyZoom1.1.js' type='text/javascript'/>
<script type='text/javascript'> 
$().ready(function() { 
  $(&#39;a.zoom&#39;).each(function(i) { 
    $(this).easyZoom();
  }); 
}); 
</script>

The above codes add links to jQuery library and my updated EasyZoom library to you blogger. The libraries contains a function easyZoom for any HTML anchor tag with class "zoom" to add mouse hover event, i.e., zoom effect to your images!

Step 6. Save your new HTML template.

You do this (6 steps) only once. Now it is ready for you add zoom feature to your blogs.

Edit Image in a Your Blog

Now you can add zoom effect to your images in your blog posts.  Normally, after your adding images to your posts, Blogger will add some HTML tags for your image.  You should simplify those tags like this:

<a class="zoom" href="test.png">
  <img src="test2.png" width="300" ...>
</a>

The key to enable zoom feature is to add "zoom" class in anchor or a HTML tag. Here ... are any other settings you may want to your image, for example, align to left, center or right, or border. The width attribute value is based on your blog layout, and you may change it for best result.

You only need to update your Blogger HTML once in above 6 steps.  To add zoom feature to your image, all you have to do is to enable HTML edit and to add "zoom" to your anchor tag for the image. Basic knowledge about HTML will be great help, but it is not required.  My recommendation is to learn some basic HTML and you will be able to enhance your blog with great self-satisfaction.

Examples


Here are some examples of images with zoomable feature. The first one is the log of jQuery without customized height. As you can see there is big gap in the zoom box:



and again with customized height to remove the gap:



John Resig is an application developer at Khan Aademy. He was a JavaScript tool developer for Modizlla Corporation. He is also the creator and lead developer of the jQuery JavaScript library.



jQuery is a crosse-brower JavaScript library designed to simplify the client-side scripting of HTML. It was released in January 2006 at BarCamp NYC by John Resig. Used by over 46% of the 10,000 most visited websites, jQuery is the most popular JavaScript library in use today.


Advanced Topics


This technique is based on jQuery library. jQuery is a great JavaScript library with a rich APIs to enhance HTML documents. One of great features is that jQuery let developers concentrate on codes without worrying various browsers. It just works.  Another feature is that jQuery is so tiny small. Developers can easily add features based this platform, just like this EasyZoom library.

In addition to jQuery library, you need to add this EasyZoom JavaScript library. I put my updated codes on Google Code Project.  It is an Open Source library. You can take it or modify for your needs. I'll keep my codes there forever, but if you concern its availability, you may move it to your site, your Google Code Project or any other places.

The logic of this zoom feature is based on JavaScript and CSS. JavaScript codes above will be loaded when your blog is opened first time. The codes will find all anchor HTML elements with class "zoom" and pass those elements to JavaScripts. The magic happens in the function call, where mouse hover event, a dynamic zoom box with image referenced in the anchor, and CSS style are created.

Another note about this is that this technique is based on two images in your blog. Blogger normally add them when you update an image. The image element is a smaller size image and it is displayed in your blog. Since the image is smaller, your blog loading process is faster. Anther image Blogger added is an image its parent anchor element, with large size image. It is only be loaded when the image is clicked. This image is used in the zoom box.

I may add additional features to this easy-zoom library. For example, add a caption for the zoomed image. The caption can be easily defined in your blog.

References

Read More...

Saturday, September 03, 2011

SQLPlus Debug and VIM Find/Replace

Yesterday I was asked to help to resolve some issues for a piece of PL/SQL codes, which was provided by our client support. I was working on only error issues, nothing related to its logic. I spent about 2 hours and finally almost got the script running OK (it was too late in the afternoon). Here are two notes about the work.

First, I needed to debug PL/SQL procedure codes. We were using SQL*Plus command console. For SQLPlus command codes; I saw that command prompt is used to print out messages, but I this command does not work in a block of procedure codes. Quickly I found the command which can be used for PL/SQL procedure debug. It is actually a very simple one, and I used this one long time ago. Here is my note on this again:

SET SERVEROUTPUT ON
dbms_sql.output.PUT_LINE('message');
...
SET SERVEROUTPUT OFF

The second note is about using VIM to add the about debug command dbms_sql.output.PUT_LINE in to codes. The reason I wanted to use VIM was that a block of similar codes are in a repeatedly pattern (the following codes are mock and simplified ones):

strDDL := 'create synonum ' || '&username' || '.AUsers for ' || '&newUser' || '.AUsers';
nCID := dbms_sql.open_cursor;
dbms_sql.parse(nCID, strDDL, dbms_sql.v7);
nCount := dbms_sql.execute(nCID);
dbms_sql.close_cursor(nCID);


strDDL := 'create synonum ' || '&username' || '.BUsers for ' || '&newUser' || '.BUsers';
nCID := dbms_sql.open_cursor;
dbms_sql.parse(nCID, strDDL, dbms_sql.v7);
nCount := dbms_sql.execute(nCID);
dbms_sql.close_cursor(nCID);

...

I did not want to manually type in the debug commands after the first one in each block. That's too tedious. I decided to use my gVIM (for Windows), using its power to get my codes just in one Find/Replace command. This can be done by grouping feature in Find/Replace command, since I wanted to use partial codes in the first line. I figured out the following VIM command:

:%s\(strDDL :=\)\(.*\);\n\(.*\n.*\n.*\n.*\)/\1\2;\rdbms_output.PUT_LINE(\2);\r\3/g

Notes on above command:


  • Replace command: %s/find/replace/g where g is for all.
  • In find section, use \(...\) to mark a group. In my above command, there are 3 groups and the 2nd ad 3rd groups will be reused in replacement section.
  • The group name used in replace section is reference by \#, such as \2 and \3.
  • The line break in find section is \n
  • The line break in replace section is \r


This is the result:

Read More...

Sunday, August 28, 2011

Open/Closed Principle: Delegate Example

In object-oriented programming, the open/closed principle is a very important principle. Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Recently I tried to summary some commonly used components in a serials of documents. I found that I have used delegate in my LogHelper class. This reminds me about my OCP.

I was not intended to use delegate as a way to extend my log feature. I was using it to avoid building a message string but not actually used for logging. I thought it will be nice to use a pointer to function which returns a string. So that the function would be called dynamically only if logging is enabled.

public delegate string GetMessage();

public static class LogHelper {

public void WriteMessage(
ILog log, string flag, GetMessage getMessage)
{
if (log != null && getMessage != null
&& log.IsLogSet(flag))
{
var msg = getMessage();
log.write(msg);
}
...
}


Here is an example of the usage:

LogHelper.WriteMessage(log, "d", delegate() {
return string.format("MyObject: {0}",
myObject.ToString());
};



As shown in above example, user can build a simple or complicated string for logging. Since the building codes are in a dynamic delegate. The delegate will only be called when the log flag "d" is enabled.

I think that my design of LogHelp class is a typical way to OCP. Here is another example to use the same method to enable indention and un-indention for messages:

class DataProcess {
private int m_indention = 0;

private void LogMsg(bool indent, GetMessage getMsg)
{
if ( getMsg == null )
{
return;
}

if (indent)
{
m_indention+= 2;
}
else if ( m_indention > 0 )
{
m_indention -= 2;
}
else
{
m_indention = 0;
}

LogHelper.WriteMessage(log, "d", delegate() {
return string.format("{0}MyObject: {1}",
new String(' ', m_indention),
getMsg());
};
}
...
}




Read More...

Sunday, August 21, 2011

Create Materialized View

This blog is about how to create a materialized view in SQL server database. By creating a materialized view, you can dramatically improve query performance. I learned this by my experience. Here are some key notes about the process.

Create a View



The first step you have to create a view. The first requirement for materialized view in SQL server is that a special WITH SCHEMABINDING has to be used for the view.
CREATE VIEW [dbo].[vMyView] WITH SCHEMABINDING
AS
SELECT rawid,
readingdate,
CAST(VALUE AS FLOAT) AS VALUE,
name
FROM dbo.myRawDataTable
WHERE ( VALUE IS NOT NULL )
AND ( Isnumeric(VALUE) = 1 )
AND Name LIKE '%my_pattern%'


The second requirement is to make sure there are any keys in the view. For example, you can include key column or combination of columns as a unique identifier. This key will be used to create INDEX for the view.

Add a Index



The materialized view actually holds a block of data with Index. This makes view fast for retrieving data. For example, for above view, a INDEX is created:

-- Create UNIQUE CLUSTERED index on the view
CREATE UNIQUE CLUSTERED INDEX IVW_vMyViewUniqueIndex
ON [vMyView] (rowid, name, readingdate)


The Index is created depending on your query. With this Index, you will see great performance improvement, specially again huge amount of data.

Use (NOEXPAND) in SQL Query



With above preparation, the view is ready for use. However, I noticed that a special option has to be used in SQL query in order to take advantage of the Indexed view, for example:

SELECT *
FROM [vMyView] (NOEXPAND);


This NOEXPAND has to be used in SQL Standard Server. In SQL Enterprise Edition Server, this is not required (but you have to pay big bucks).

Conclusion



Materialized View can improve SQL query performance dramatically, just like adding property Index to tables. The disadvantage is that the MV will take some disk spaces. You have to balance the weight in your real cases.

Read More...

Sunday, August 14, 2011

Finished Watching WWDC 2011 Videos

Today I finished watching all the WWDC 2011 videos. I spent most of after-work hours to watch those shows. It is good to get an overall view of all the technologies used in iOS 5, even some I may not use at all and some are hard to digest.

I also started to write my notes in Chinese about WWDC 2011 shows. However, the notes are far more behind my watching schedule. I could not keep up my notes with my watching progress, and eventually I decided to left go behind. Right now my notes are close to the end of 100 serials. They are still 200, 400 and 500 serials to be written. I think it is good review when I write notes, and I'll keep it up to the end.

Read More...

Monday, August 01, 2011

Updated to Xcode 4.1

Today I updated me Xcode to 4.1. It is a free version available from Apple store. That means you either have to have Snow Leopard or Lion if you want to get it. Before Lion's release it was $5.00 from Apple Store. I have not started my iOS development for a while since I have been kept watching WWDC 2011 videos. Right now I am in the half way through 400 sessions and only 500 serials in my schedule. It is really good to learn OS and iOS new features from those session videos.


The update of Xcode is 3GB+, almost as big as Lion. After the installation the Install Xcode app stays in Applications folder. I removed it from there after the installation (I made a copy of this package to my external HD). The following is the welcome window.


I'll have to squeeze time to go back to my development.

Read More...

Sunday, July 24, 2011

Code Formatter

Last week I was working on some T-SQL query codes. I remembered that I used PL/SQL developer tool to reformat my SQL codes by using Beautifier. I could not find similar tool in SQL Server Management Studio, at least for SSMS 2005/2008. I googled web to see if there is any tools available.

To my surprise, I found couple very nice web on-line tools called as code formatter. For example, Instant sQL Formatter is the tool I want. In addition to parse codes into a nice format, it also does basic syntax checking. The only thing is missing is the spaces for indention.

In addition to TSQL, I found several other web tools for code formatter:

Read More...

Sunday, July 17, 2011

Finished Watching WWDC 2011 Videos in -Halfway

In the past weeks, I have been in a fast-paced way to watch WWDC 2011 videos. Right now I have finished 100(App Frameworks), and 300(Developer Tools) serials. Still three sections left: 200(Core OS, 13), 400(Graphics, Media and Games, 24), and 500(Internet and Web, 19).

I have also made some nodes in my Chinese blogs about WWDC 2011.

WWDC exposed more detail changes in iOS and Mac OS with new framework and APIs. For example, full screen feature is a very nice thought designed bases on iOS. Windows have full screen since its start, Windows 3.0. However, Mac OS full screen has more support from its core internal. App's will receive many events such as willXXX and didXXX for full screen status. With those events, app developer can prepare UI for better user experience and usage. In terms of OS, the full screen has consistency UI for full screen such as enter, exist and keyboard shortcuts. Full screen apps flow fluently in Mac OS.

Another group of great features are auto-save and versions. Those features are backed by app with Cocoa new APIs. Basically, this is a repository for software source codes, but it has been expanded to Mac OS app. It will be up to app developer to implement the feature. Save and versions are integrate part of Mac OS. As one of Apple software engineering in one session about this topic said, what is if further of Mac OS Cocoa? It may be the long time Quit will be gone. Users will not need to take care apps in Mac OS. Since everything will be auto-saved, why should apps with those features stay in OS when they are not in use? This will greatly enhance the experience of using Mac with great resources releases by inactive apps.

Read More...

Sunday, July 10, 2011

Using DIV to layout side-by-side blocks

I often need to layout my contents in two blocks side-by-side, with left side block as a warning message as example. This can be done easily by using CSS and HTML. Here are the tips.

Example layout



First, let's look at the example layout. To visualize the side-by-side blocks, I added a border container, which can be removed.

First DIV block on the Left


When using percentages, you usually have to play around a bit to get things to look the same in IE, Safari, Chrome and Firefox.

Right block


This is a tutorial on how to use CSS to create a simple two column layout.

The styles for the blocks are defined in CSS classes in the <head> section of HTML.

This the end of 2 column side by side layout.


Define CSS classes



Define the following style classes in HTML head section:

<head>
...
<style type="text/css">
....
.boxLeft {
float:left;
width:20%;
border:1px solid;
padding: 1%;
margin:1% 0 1% 1%;}

.boxRight {
float:right;
margin: 1% 1% 1% 1%;
width:75%;}

.clear {
margin: 0;
padding: 0;
clear: both; }
...
</style>
...
</head>


Use CSS classes to layout 2-blocks side-by-side



With above CSS classe definitions, they can be used in the body section to layout 2 blocks of text side-by-side:

<body >
...
<!-- containner -->
<div style="border:2px solid;">
<!-- Left block -->
<div class="boxLeft" style="background:green">
<h2>First DIV block on the Left</h2>
<p>When using percentages, you usually have to play around a bit to get things to look the same in IE, Safari, Chrome and Firefox.</P>
</div>
<!-- end of left block-->
<!-- right block -->
<div class="boxRight" style="background:#dff">
<h2 >Right block</h2>
<p>This is a tutorial on how to use CSS to create a simple two column layout.</P>
<p>The styles for the blocks are defined in CSS classes in head section of HTML.</p>
</div><!-- end of box block -->
<div class="clear"></div>
</div><!-- container -->
<div>
<p>This the end of 2 column side by side layout.</p>
...

References

Read More...

Friday, July 01, 2011

No Overflow for a Simple Math Calculation

I watched WebBeat podcast one day in the last month. One video show got my attention: Explaining visual math in a simple way. I wrote a blog on my Chinese blog. It is very interesting to resolve a math multiply by visualization graphs. However, this method only applies to multiply of 2 digit numbers, and it becomes tedious when there carrier forward in the last and middle numbers.

This reminds me a long time puzzle problem: how to resolve overflow issue when the result of multiply of two integers is too big. I recall the traditional method of multiply algorithm and relate it to this visualization. Soon I realize that I could resolve the overflow issue by creating a small app. I gave it a try with Javascript and I got it worked out! I am very happy with the result. No more overflow no matter how big numbers they are!

Here is my Javascript function:

function v1timesv2(v1, v2) {
  var x = ''; // result
  var i = 0;
  var j = 0;
  var r;
  var r1;
  var r2;
  var k;
  var tempVal;
  var preTempVal = '';
  debug ('v1: ' + v1);
  debug ('v2: ' + v2);
  for (i= v2.length-1; i >= 0; i--) // v2
  {
    r2 = 0;
    tempVal = '';
    k = preTempVal.length;
    for (j=v1.length-1;j >=0; j--)  // v1
    {
      if ((k--) > 0)
      {
        r2 += Number(preTempVal[k]);
      }
      r = v1[j] * v2[i] + r2;
      r1 = r % 10;
      r2 = 0;
      if ( r > 9 )
      {
        r2 = (r - r1) / 10;
      }
      tempVal = r1 + tempVal;
    }
    if ( r > 9 )
    {
       tempVal = r2 + tempVal;
    }
    debug('intermediate calculated result: ' + tempVal);
    // Get the last char as result
    x = tempVal[tempVal.length - 1] + x;
    debug('intermediate result: ' + x);
    // Get the remaining as previous val
    if ( tempVal.length > 1 )
    {
      preTempVal = tempVal.substr(0, tempVal.length - 1);
    }
    else
    {
      preTempVal= '';
    }
    debug('== carry forward result: ' + preTempVal + ' ==' );
  }
  x = preTempVal + x;
  debug('>>final result:    ' + x);
  debug('>>verified result: ' + Number(v1) * Number(v2) + ' (' + v1 + ' x ' + v2 + ')');
  return x ;
}


This may not be the best codes. Please let me know if you can simplify my codes. Download my numberCalc.html and drop it to a browser. I challenge if you can break my codes with an overflow!


References


Read More...

Saturday, June 25, 2011

CoffeeScript and .Net Nancy Framework

Last week when I listened to my podcasts, two projects got my attention. The firs one is from HerdingCode podcast 114 about: Trevor Burnham on CoffeeScript. This is light language in clean syntax that can be compiled into JavaScripts, in one to one relationship.

The second one is from HansellMinutes on 6/16/2011: Nancy, Sinatra and Exposion of .Net Micro Web Framewor. The Nancy project was introduced on Nov 28th, 2010. The blog site Elegent Code posted a blog about this podcast as well on Jun 28, 2011.

Read More...

Thursday, June 23, 2011

WWDC 2011 Videos Available for Apple Developers

According to the news from AppleInsider, Apple released all the WWDC videos for Apple Mac OS and iOS developers. I went to the Apple Devleoper site and I started to download videos right away. There are about 110 videos in various categories. Based on OS X and iOS there are 155 contents.

The following image is one I used in my Chinese blog at creaders.net.



I have been anxiously expecting for those session videos for a while. Now I will be very busy to watch those videos, evenings and weekends. Last year I took months to finish all of WWDC 2010 videos, and I enjoyed watch them very much. Apple's OS and iOS technology are really very impressive.

References

Read More...

Friday, June 17, 2011

Edit Blogger HTML Settings

This is blog is technical detail I did in 2007. I wrote this technique long time ago. It is truth that this is only required to do only once. However, when I create another blogger account, I would like to repeat it again. Now I think it is better to take detail notes of steps so that I may need to reuse it again.

Here is the example I edited HTML for my Chinese blog.

Backup HTML


It is important to backup your Blogger HTML settings before doing any updates. Here is the place to find the HTML settings and make the complete copy of HTML before any updates.



Copy My CSS Settings


The following CSS codes are used by my blog. Insert the CSS definitions into header section. Here I copied it to end of </b:skin>

<b:skin><![CDATA[/*-----------------------------------------------
...
/* David Inserted styles */
/* Use these styles as class ID for a box for some blocks such as div, p */
.outlinebox {
  width: 435px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #666666;
  padding: 5px
  }

.outlineterminalbox {
  width: 850px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #C0C0C0;
  font-family:monospace, prestige;
  background-color: #080808;
  color: #FFFF00;
  padding: 5px
  }

.outlinebox4wrappercodes {
  width: 444px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #666666;
  margin: 0px auto;
  }

.outlineboxterminal4wrappercodes {
  width: 444px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #080808;
  color: yellow;
  margin: 0px auto;
  }

/* code settings with following 2 outline Withbackclr. Generated in VIM TOhtml cmd */
.Type { color: #60ff60; }
.Comment { color: #80a0ff; }
.Identifier { color: #40ffff; }
.PreProc { color: #ff80ff; }
.Constant { color: #ffa0a0; }
.Statement { color: #fbf204; }
.Special { color: #fb8000; }

.outlinebox4wrappercodesWithbackclr {
  width: 444px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #666666;
  margin: 0px auto;
  background-color: #000000;
  color: #cccccc;
  }

.outlineboxterminal4wrappercodesWithbackclr {
  width: 444px;
  border-width: 1px;        /* sets border width on all sides */
  border-style: solid;
  border-color: #080808;
  color: yellow;
  margin: 0px auto;
  background-color: #000000;
  color: #cccccc;
  }
 
.wrappercodes {
  width: 435px;
  padding: 5px;
  overflow: auto;
  }
 
.wrappercodesWithHeight {
  width: 435px;
  height: 300px;
  padding: 5px;
  overflow: auto;
  }

.wrappercodesWithHeightNowrap {
  width: 435px;
  height: 300px;
  padding: 5px;
  overflow: auto;
  white-space:nowrap;
  }

.nowrappercodes {
  width: 435px;
  padding: 5px;
  overflow: auto;
  white-space:nowrap;
  }

.nowrappercodesinner {
  width: auto;
  padding: 5px;
  overflow: auto;
  white-space:nowrap;
  }

.nowrappercodesWithHeight {
  width: 435px;
  height: 300px;
  padding: 5px;
  overflow: auto;
  white-space:nowrap;
  }
 
/* code style */
span.kwrd {
  color: rbg(0, 0, 255);
  }

span.defType {
  color: rgb(43, 145, 175);
  }
 
span.errorcode {
  color: rbg(255, 0, 0);
  }
 
span.highlight
{
color: white;
background-color: rgb(0, 100, 200);
}

/* Code Colors copied ccs from http://forums.asp.net/utility/colorcode.css for code colors */
/* Use asp.net forums on-line post to generate codes with these ccs class */

.coloredcode .cmt      { color: #00D502; }
.coloredcode .cmtg      { color: #666; }
.coloredcode .st           { color: #f00; }
.coloredcode .kwdt      { color: #666; }
.coloredcode .kwd      { color: #00f; }
.coloredcode .attr      { color: #f00; }
.coloredcode .attrv      { color: #00f; }
.coloredcode .ec           { color: #00f; }
.coloredcode .tag      { color: #800000; }
.coloredcode .dir    { color: #000; background: #FEFF22; }
.coloredcode .sel    { color: #800000; }
.coloredcode .val    { color: #00f; }
.coloredcode .unit      { color: #800000; }
.coloredcode .sqlcmt { color: #008080; }
.coloredcode .sqlkwd { color: #00f; }
.coloredcode .sqlkwd2 { color: #f0f; }
.coloredcode .sqlkwd3 { color: #999; }
.coloredcode .sqlkwd4 { color: #800000; }
.coloredcode .num      { color: #00f; }
.coloredcode .sqlst  { color: #008000;}
.coloredcode .classInterface { color: #1E90FF;}
.coloredcode b      { font-weight: normal; color: #008080; }
.coloredcode          { font-size: small !important; }
.row-set-descriptor {
  border-bottom: 1px solid #F60;
  border-bottom-style: solid;
  border-bottom-width: 1px;
  border-bottom-color: #F60;
  clear: left;
  color: #E55C00;
  font-size: 140%;
  margin: 0px 20px 0.5em 0px;
  margin-top: 0px;
  margin-right: 20px;
  margin-bottom: 0.5em;
  margin-left: 0px;
  padding: 1em 0px 0.2em 0em;
  padding-top: 1em;
  padding-right: 0px;
  padding-bottom: 
}

 /* End of Code Colors */
 /* End of David inserted styles */

]] > </b:skin>


Copy Scripts


Immediately after about </b:skin>, add Javascript codes.

<b:skin>
  ...
]] > </b:skin>
<script type='text/javascript'>
function toggleIt(id) {
  var post = document.getElementById(id);
  if (post.style.display != &#39;none&#39;) {
    post.style.display = &#39;none&#39;;
  }
  else {
    post.style.display = &#39;&#39;;
  }
}

function showFullPost(id) {
  var post = document.getElementById(id);
  var spans = post.getElementsByTagName(&#39;span&#39;);
  for (var i = 0; i != spans.length; i++) {
    if (spans[i].id == &quot;fullpost&quot;)
      spans[i].style.display = &#39;inline&#39;;
    if (spans[i].id == &quot;readmore&quot;)
      spans[i].style.display = &#39;none&#39;;
  }
}

function showFull(id) {
  var post = document.getElementById(id);
  var spans = post.getElementsByTagName(&#39;span&#39;);
  for (var i = 0; i != spans.length; i++) {
    if (spans[i].id == &quot;fullpost&quot;)
    spans[i].style.display = &#39;inline&#39;;
    if (spans[i].id == &quot;showlink&quot;)
      spans[i].style.display = &#39;none&#39;;
    if (spans[i].id == &quot;hidelink&quot;)
      spans[i].style.display = &#39;inline&#39;;
  }
}

function hideFull(id) {
  var post = document.getElementById(id);
  var spans = post.getElementsByTagName(&#39;span&#39;);
  for (var i = 0; i != spans.length; i++) {
    if (spans[i].id == &quot;fullpost&quot;)
      spans[i].style.display = &#39;none&#39;;
    if (spans[i].id == &quot;showlink&quot;)
      spans[i].style.display = &#39;inline&#39;;
    if (spans[i].id == &quot;hidelink&quot;)
      spans[i].style.display = &#39;none&#39;;
  }
  post.scrollIntoView(true);
}

function checkFull(id) {
  var post = document.getElementById(id);
  var spans = post.getElementsByTagName(&#39;span&#39;);
  var found = 0;
  for (var i = 0; i != spans.length; i++) {
    if (spans[i].id == &quot;fullpost&quot;)
      found = 1;
    if (spans[i].id == &quot;showlink&quot;)
      if (found == 0)
        spans[i].style.display = &#39;none&#39;;
  }
}
</script>



Insert Script Function Calls in Body Section


MODIFYING BLOG POSTS CODES

First find the line: <div class='post-header-line-1'/>

Insert the following codes after it:

<div class='post-body'>
  <b:if cond='data:blog.pageType == &quot;item&quot;'>
    <p><data:post.body/></p>
    <div style='clear: both;'/>
  <b:else/>
    <style>#fullpost {display:none;}</style>
    <p><data:post.body/></p>
    <span id='showlink'>
      <p>
        <a expr:onclick='&quot;javascript:showFull(\&quot;post-&quot; + data:post.id + &quot;\&quot;);&quot;'
        href='javascript:void(0);'>读详细内容(Read More)...</a>
      </p>
    </span>
    <span id='hidelink' style='display:none'>
      <p>
        <a expr:onclick='&quot;javascript:hideFull(\&quot;post-&quot; + data:post.id + &quot;\&quot;);&quot;'
        href='javascript:void(0);'>Collapse...</a>
      </p>
    </span>
    <script type='text/javascript'>
      checkFull(&quot;post-&quot; + &quot;<data:post.id/>&quot;);
    </script>
  </b:if>
</div>



NOTE: I found there is a duplicate post when the title of the post is clicked. The reason is that there is another div after the above codes:

<div class='post-body entry-content' expr:id='&quot;post-body-&quot; + data:post.id'>
  <data:post.body/>
  <div style='clear: both;'/> <!-- clear for photos floats -->
</div>



delete this section of div to avoid duplications.

NOTE: remove two tags: <div class="post-header"> ... </div> to avoid the content of post content in grey.

CODE FOR THE INCLUDABLE

Find the code: <b:includable id='feedLinksBody' var='links'>
Insert the following codes above it:

<b:includable id='PeekABooPost' var='post'>
  <div class='post uncustomized-post-template'>
    <table><tbody>
      <tr><td>
        <h3 class='post-title'><a expr:href='data:post.url'
        title='View this post only (comments visible).'><data:post.title/></a></h3>
      </td></tr>
      <tr><td>
        <a expr:onclick='&quot;javascript:toggleIt(\&quot;&quot; + data:post.id + &quot;\&quot;);&quot;'
          href='javascript:void(0)'
          style='text-decoration:none'
          title='Expand/collapse this post (comments not visible)'>[+/-] 显示内容(Show/Hide This Post).</a><br/>
        <a expr:href='data:post.url' target='_blank'>
          <i><font size='-2'>See/leave comments for this post in another window/tab.</font></i></a>
      </td></tr>
    </tbody></table>
    <div class='post-body' expr:id='data:post.id' style='display:none'>
       <p><data:post.body/></p>
       <div style='clear: both;'/>
    </div>
  </div>
</b:includable>
<b:includable id='feedLinksBoday' var='links'>



INCLUDE THE INCLUDABLE IN THE POSTS WIDGET

Find the code: <b:includable id='main' var='top'>
In this section find: <b:include data='post' name='post'/>
Change it to:

<b:if cond='data:blog.homepageUrl == data:blog.url'>
  <b:if cond='data:blog.pageType != &quot;item&quot;'>
    <b:include data='post' name='PeekABooPost'/>
  <b:else/>
    <b:include data='post' name='post'/>
  </b:if>
<b:else/>
  <b:include data='post' name='post'/>
</b:if>



Copy HTML Back to Blogger HTML Settings


After the change, copy the content of HTML from your local file back to blogger HTML settings.

REFERENCE

This feature of shrink and expend bloggs is based on this blog.

Read More...

Saturday, June 11, 2011

My SQL Query Questions

Last Friday I posted a SQL query question to SO. It was about get records between boundaries. Quickly I got several good answers.

I noticed one comment about performance issue by Piotr Auguscik:

U can use max/min to get value u need. Order by +top 1 isnt best way to get max value, what i can see in ur querys. To sort n items its O(n to power 2), getting max should be only O(n)


This is very interesting comment. I think about it, and I realize it is true. To sort a list of n items, it will take about n power of 2 by using bubble sort algorithm; while just to find out the max, it will do one loop of n at most. This is a very simple computer science concept. However, if it is an index column in the query table, I think that it should have no difference between TOP 1 + ORDER BY and MAX + GROUP BY.

Today I raised another question related to this issue again to SO. I got a very nice explanation and a tip to optimize the query and tip on how to turn on statistics on IO and TIME.

Here are queries:

SELECT
dv1.timestamp, dv1.value
FROM
myTable AS dv1
WHERE
dv1.value = @value
dv1.timestamp
BETWEEN (
SELECT TOP 1 dv2.timestamp
FROM myTable AS dv2
WHERE dv2.value = @value AND
dv2.timestamp < '@START_DATE'
ORDER BY dv2.timestamp DESC
)
AND (
SELECT TOP 1 dv3.timestamp
FROM myTable AS dv3
WHERE dv3.value = @value AND
dv3.timestamp < '@END_DATE'
ORDER BY dv3.timestamp ASC
)
ORDER BY dv1.timestamp

-- alternative way

SELECT
dv1.timestamp, dv1.value
FROM
myTable AS dv1
WHERE
dv1.value = @value
dv1.timestamp
BETWEEN (
SELECT MAX(dv2.timestamp)
FROM myTable AS dv2
WHERE dv2.value = @value
GROUP BY dv2.value
)
AND (
SELECT MIN(dv3.timestamp)
FROM myTable AS dv3
WHERE dv3.value = @value
GROUP BY dv3.value
)
ORDER BY dv1.timestamp

Read More...

Thursday, June 02, 2011

Use NET USE Command to Map Network Drive

Here is one senario about using network shared folders. One application requires a configuration file. The application has been used in our intranet environment with many users. Many users use the same configuration. It is preferable to put the configuration file on a shared network folder. I need to find a efficient way to let user be able to access to the file.

I use the following DOS command NET USE to dynamically allocate a network drive for the share one:

@IF EXIST \\remoteMachine\sharedFolder GOTO EXIT
@NET USE * \\remotemachine\sharedFolder pwd /user:userName /PERSISTENT:NO
:EXIT


In above codes, * is used to get next available drive letter for mapping. The key option is /PERSISTENT:NO. With this setting, the mapped drive will be released or not persistent after logout or reboot.

The main reason I use dynamic mapping is that I am not sure what network drive is available. It hard to find one no body in use. Since my application does accept UNC network full name, I don't care what network letter being assigned. In the configuration file, I use UNC network full name. Since the UNC name has been authenticated, it is as same as a drive letter for fast access.

Read More...

Sunday, May 22, 2011

Create Shortcut in C#

Last week I was working on a case to provide support for an application users. The application has two executables: one is app's main exe like app.exe and another one is for app's update like appUpdate.exe. For this update, we need to add a shortcut on clients machine desktop pointed to appUpdate.exe.

Like a typical shortcut, the one I need to put on client PCs has several settings: target, start in, run mode, icon and comments.



I tried to create a shortcut on my box first. Aftert that, I tried to copy this shortcut file (lnk) to a remote PC. It did not work. It seems that the lnk file some information are embedded in the file. When it is not in the machine where it was created. The machine name appears in the target.

I need a way to create a shortcut on fly. That's why I went to .net to create a simple console app do the job. This time SO helped me with an excellent open source library from a QA: ShellLink.cs. Within the source codes, there are actually two files I need: ShellLink.cs and FileIcon.cs. The library contains a wrapper class for Windows APIs. It is very straight forward.

The only change I made is to add a class level flag for any changes in shortcut properties. If any setter changes a value, this flag is true. Then I'll only save chances for the shortcut if any of properties are changed.

public class ShellLink : IDisposable {
private bool mChanged = false;
....
public string Target {
get { .... }
set { if (!value.Equals(Target)) {
mChanged = true;
....
}
....
}

Read More...

Sunday, May 15, 2011

Evernote Shared Link

Evernote is one of my favourite web services. I have taken a lots of notes about my programming experience and snip of codes. Recently Evernote announced that it adds public link to any private notes, as well as public ones. That's nice feature.

Here is one note I made last week about my experience to use console command to make to a network shared folder. With this tip, I can control the accessibility of sub folders. This node is from my public notebook: .Net

To test sharing of private note, here is my private note about Mac OS tip: Fix Failed Install.

Read More...