2011年10月27日星期四

在网页中实现选择多个文件的对话框

IE(IE9以下)不支持File API,所以很难实现能够选择多个文件的对话框。
常用的实现选择多个文件的对话框的方法有两种:
1. 调用Flash插件选择文件,缺点是能得到文件名,得不到文件路径。
2. 调用ActiveX插件选择文件,缺点是需要设置为安全站点。
公司的网站已经设置为安全站点了,而我又需要知道文件的路径来生成缩略图,所以选择了第二种方法。
代码如下是:
    // 0x200    OFN_ALLOWMULTISELECT
    // 0x80000  OFN_EXPLORER    
    // 0x800    OFN_PATHMUSTEXIST
    // 0x4      OFN_HIDEREADONLY
    // 0x200000 OFN_LONGNAMES  
    // 0x1000   OFN_FILEMUSTEXIST
    var flags = 0x200|0x800|0x4|0x200000|0x1000|0x80000;   

    var dialog = new ActiveXObject('MSComDlg.CommonDialog');
    dialog.Filter = 'All files (*.*)|*.*| ';
    dialog.MaxFileSize = 260;
    dialog.Flags=flags; 
    dialog.ShowOpen();
    console.log(dialog.FileName.length, dialog.FileName.split(/\0/).length);

var flags = 0x200|0x800|0x4|0x200000|0x1000|0x80000;

dialog.FileName.split(/\0/)

很重要,这两句话浪费了我一天的时间。

0x200 保证可以选择多个文件

0x80000 保证可以让对话框看没关系,没有它,对话框为windows95以下的那些版本的文件选择对话框,很难看

dialog.FileName.split(/\0/)是最折腾我的,好不容易多选了,也好看了,可以返回的FileName是个字符串,将这个字符串打出来后显示的是文件的路径,不包括文件!!!最后我发现dialog.FileName.length远远大于,文件路径的长度,然后在网上查到有人用dialog.FileName.split(/\0/)

dialog.FileName的格式为文件路径\0文件一\0文件二\0文件三,所以无论调试还是将字符串打出来,都只能看到文件路径,坑爹啊!!!!!

2011年9月6日星期二

How to take picture in android mobile

我在Google上查找“android take picture”得到一堆帖子告诉你怎样自己写代码去拍照并存储。事实上我想调用系统的Activity去拍照,我需要的是系统的Activity拍照后告诉我图片存储路径即可。

实际上系统有个MediaStore中记录着这个Activity的名字 MediaStore.ACTION_IMAGE_CAPTURE

Google Code Search中查一下

MediaStore.java
/**
     * Standard Intent action that can be sent to have the camera application
     * capture an image and return it.
     * 

* The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. * If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap * object in the extra field. This is useful for applications that only need a small image. * If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri * value of EXTRA_OUTPUT. * @see #EXTRA_OUTPUT * @see #EXTRA_VIDEO_QUALITY */ public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";

SlideEditorActivity.java
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            //..............
            case MENU_TAKE_PICTURE:
                intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
                break;
            //....................
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch(requestCode) {
            //..............
            case REQUEST_CODE_TAKE_PICTURE:
                Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
            //....................

2011年8月21日星期日

How to implement syntax highlighter in javadoc

Javadoc don't support syntax highlighter, and this feature is important when make example of how to use the class.

We can and this feature by add a block of JavaScript.

1. Download syntaxhighlighter_3.0.83 to document root.
2. Add the javadoc comment as
/**
 * Class Description
 * {@docRoot}
   
   
   
   
   
      You java code here
   
*/ public class YouClass{}
3. It works now.

2011年8月10日星期三

在Google Calendar中创建联系人的农历生日

谷歌的日历中有“联系人的生日和活动”(添加->浏览有趣的日历->联系人的生日和活动),这个功能貌似很好,可惜不支持农历生日。

我做了一个联系人的生日,里面可以有农历生日,也是从Google Contacts中提取联系人的生日(包括农历生日)并把它添加到日历中。(http://contactsbirthday.appspot.com)

屏幕截图:
同步到Android手机后效果图



使用说明:
1. 在谷歌联系人中添加联系人的生日。
    如果只要阳历生日,则不用添加第二行。
    如果只要阴历生日,则保持第二行和第一行一致。
2. 访问我的google appenging网站http://contactsbirthday.appspot.com
    要求:(1)用户有googl帐号,并且登录。
                (2)用户授权访问自己的联系人信息。(你也可以建立自己站点,这样最安全,后面有源代码)
3. 授权成功后系统会自动redirect到http://contactsbirthday.appspot.com/ical/?email=xxx@xxx.xxx
    xxx@xxx.xxx是你的google帐号
4. 在谷歌日历中添加这个日历
5. 下载源代码这里,提取码:bx7n86tj   lunar.py是抄自这里作者提供的源代码中描述数据结构的注释不正确,我已经改正确了


2011年7月27日星期三

Singleton implementation in Python

def Singleton(cls):
    
    def delegate(*args, **keyargs):
        if hasattr(cls, 'instance') == False:
            cls.instance = cls(*args, **keyargs)
        return cls.instance    
    
    return delegate
    
@Singleton
class test:
    def __init__(self):
        self.attr = 'aaa'
        print('init test')

if __name__ == '__main__':
    a = test()
    b = test()
    print(a,b,a==b)
    print(a.attr, b.attr)
    a.attr = 'bbb'
    print(a.attr, b.attr)    
    b.attr = 'ccc'
    print(a.attr, b.attr)

2011年7月21日星期四

Extract metadata from xbox360 GOD directory

I have many xbox306 game and I want to share some to my friends (Note: I  use XBR system).
But I can't get game name from the directory.

Fortunately there a file in game folder whose name is GUID, we can extract game name and game icon from that file.

The game name is at position 1041, there are 2 pictures at the metadata file, 5914 and 22298.

I cann't get other metadata from this file, anyone who knowes please send me an email.

Here is the program I wrote in python to extract metadata from GOD directory.

How to use:
1. Extract the zip file.
2. Modify main.py (4th and 5th line)
sourceFolder = r'............\xbox360'
outpath = r'.........\out'
3. run metaExtractor.exe
4. Open gamelist.html in the output folder to see the game list.

Oralce Sum function in livelink

Found a big bug in livelink.

When excute oracle aggregate function SUM, livelink always truncate the value.

See this SQL
select sum(v)
from 
(
  select 1.01 v from dual
  union
  select 1.05 v from dual
)
pl/sql give 2.06 but livelink give 2.

The solution is (for livelink) convert decimal to string
select to_char(sum(v))
from 
(
select 1.01 v from dual
union
select 1.05 v from dual
)
It is very strange, isn't it?

2011年7月20日星期三

The dropdownl list default value issu in IE of jqGrid cell eding

The dropdownlist in jqGrid cell edit has an issue in IE.

Let's see what happens

In jqGrid js file
var oSv = options.value;
} else if (typeof options.value === 'object') {
    var oSv = options.value;
    for ( var key in oSv) {
        if (oSv.hasOwnProperty(key ) ){
            ov = document.createElement("option");
            ov.setAttribute("role","option");
            ov.value = key; ov.innerHTML = oSv[key];
            
            
            // this line set option to be selected and the selectedIndex is correct
            if (!msl &&  ( $.trim(key) == $.trim(vl) || $.trim(oSv[key]) == $.trim(vl)) ) { ov.selected ="selected"; }
                        
            
            if (msl && ($.inArray($.trim(oSv[key]),ovm)>-1 || $.inArray($.trim(key),ovm)>-1)) { ov.selected ="selected"; }
            elem.appendChild(ov);
        }
    }
}

// before this line the selectedIndex is correct
setAttributes(elem, options);
// but after this line the selectedIndex is incorrect
The problem must be setAttributes(elem, options);
function setAttributes(elm, atr) {
    var exclude = ['dataInit','dataEvents','dataUrl', 'buildSelect','sopt', 'searchhidden', 'defaultValue', 'attr'];
    $.each(atr, function(key, value){
        if($.inArray(key, exclude) === -1) {
            $(elm).attr(key,value);
        }
    });
    if(!atr.hasOwnProperty('id')) {
        $(elm).attr('id', $.jgrid.randId());
}
Notice this line
$(elm).attr(key,value);
The key is "value" and the value is "{RMB:'RMB', USD:'USD', EUR:'EUR', AUD: 'AUD', GBP:'GBP', SGD: 'SGD'}"

Here is the problem. We can add key "value" to exclude array.

Now the functions reads
function setAttributes(elm, atr) {
    var exclude = ['dataInit','dataEvents','dataUrl', 'buildSelect','sopt', 'searchhidden', 'defaultValue', 'attr'];
    $.each(atr, function(key, value){
        if($.inArray(key, exclude) === -1) {
            $(elm).attr(key,value);
        }
    });
    if(!atr.hasOwnProperty('id')) {
        $(elm).attr('id', $.jgrid.randId());
}
It works well now.