乐者为王

Do one thing, and do it well.

关于input[text]里的光标定位

当使用Tab键切换时,想把光标定位在input[text]的首部。在网上找了一些光标定位的资料发现大多数都是用createTextRange来实现的,而且都出自一个实例。可惜的是在Firefox下createTextRange无效。

后来在Firefox的开发者站点上发现有个setSelectionRange方法可以实现这样的功能。使用格式:

1
2
3
4
5
o.setSelectionRange(start, end);

o:为文本输入框对象
start:为字符串的起始位置
end:为字符串的末位置

尝试后发现并不能定位到文本首位,总是全选所有的文本内容,在后面加上获的焦点的命令也不管用。最后还是在国外的一个站点上找到了解决的办法。

下面的代码在Firefox下不能定位到首位,只能选中全部:

1
2
3
4
5
6
7
8
9
10
11
12
function setCaretPosition(aCtrl, aPos) {
    if (aCtrl.setSelectionRange) {
        aCtrl.setSelectionRange(aPos, aPos);
        aCtrl.focus();
    } else if (aCtrl.createTextRange) {
        var rng = aCtrl.createTextRange();
        rng.collapse(true);
        rng.moveStart('character', aPos);
        rng.moveEnd('character', aPos);
        rng.select();
    }
}

经过修改后的代码就可以适用于Firefox,IE,Opera的光标定位了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function setCaretPosition(aCtrl, aPos) {
    if (aCtrl.setSelectionRange) {
        setTimeout(function() {
            aCtrl.setSelectionRange(aPos, aPos);
            aCtrl.focus();
        }, 0);
    } else if (aCtrl.createTextRange) {
        var rng = aCtrl.createTextRange();
        rng.collapse(true);
        rng.moveStart('character', aPos);
        rng.moveEnd('character', aPos);
        rng.select();
    }
}

Ubuntu 8.10英文Locale下安装Fcitx中文输入法

系统装好后首先要做的就是安装中文输入法。在网上找了一些中文输入法的资料,最常用的是Fcitx和SCIM输入法。不过好像SCIM的问题比较多,而且据说Fcitx的功能上也要比SCIM强得多,所以决定采用Fcitx输入法。

卸载SCIM

为了避免安装中出现一些问题,在这之前先要卸载掉系统自带的SCIM输入法:

1
2
3
sudo apt-get remove --purge scim*  # 删除SCIM及其配置文件
sudo apt-get autoremove  # 删除被SCIM依赖的,不再使用的package
sudo apt-get install -f  # 尝试修正安装过程中出现的依赖性关系

注:也可以通过“新立得软件包管理器(Synaptic Package Manager)”来卸载SCIM。

安装Fcitx

下载最新的稳定的预编译包 http://www.fcitx.org/download/fcitx-3.4.2-bin.tar.bz2 ,解压到任意目录。启动命令行,进行该目录执行sudo ./fcitx.install进行安装(只是复制了几个文件到目标目录)。反安装也是在该目录下面执行sudo ./fcitx.uninstall(如果知道安装到哪了直接删除也行)。

因为要在英文Locale下启动Fcitx输入法,所以在/etc/X11/xinit/xinput.d/下新建一个文件en_US,文件内容如下:

1
2
3
4
5
6
7
XMODIFIERS="@im=fcitx"
XIM=fcitx
XIM_PROGRAM=/usr/bin/fcitx
XIM_ARGS=""
GTK_IM_MODULE=XIM
QT_IM_MODULE=XIM
DEPENDS="fcitx"

执行ls -l /etc/X11/xinit/xinput.d命令,输出以下内容:

1
2
3
4
5
6
7
8
9
10
11
total 24
drwxr-xr-x 2 root root 4096 2008-10-30 07:10 .
drwxr-xr-x 3 root root 4096 2008-10-30 07:03 ..
lrwxrwxrwx 1 root root   32 2008-11-05 00:31 all_ALL -> /etc/alternatives/xinput-all_ALL
-rw-r--r-- 1 root root 1152 2008-01-08 18:41 default
-rw-r--r-- 1 root root  601 2008-01-08 18:41 default-xim
-rw-r--r-- 1 root root  601 2008-01-08 18:41 en_US
-rw-r--r-- 1 root root  474 2008-01-08 18:41 none
-rw-r--r-- 1 root root  451 2008-10-27 05:54 scim-bridge
lrwxrwxrwx 1 root root   30 2008-11-05 00:31 th_TH -> /etc/alternatives/xinput-th_TH
-rw-r--r-- 1 root root  610 2008-01-08 18:41 th-xim

重启X Window后Fcitx正常启动,输入条位于屏幕顶端,但是按Ctrl+Space无法调出中文输入,用鼠标点小企鹅也不行。这时需要编辑/usr/lib/gtk-2.0/2.10.0/immodule-files.d/libgtk2.0-0.immodules文件,找到:

1
"xim" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh"

将之改成

1
"xim" "X Input Method" "gtk20" "/usr/share/locale" "en:ko:ja:th:zh"

使Xim在英文环境下也能启动。保存退出,重启X后中文输入就可以被正常调出了。

安装中文所需的Locale包

现在还有个问题就是输入法尾部出现乱码,输入条下的待选字也是乱码,即只显示一些小方框,如下图:

这是因为缺少中文Locale文件导致,需要安装两个中文Locale包。

1
2
sudo apt-get install language-pack-zh
sudo apt-get install language-pack-gnome-zh

或者,也可以将~/.fcitx/config中的:

1
显示字体(中)=*

改成

1
显示字体(中)=AR PL UMing CN  # 填你喜欢的中文字体

重新启动后就没有乱码了。

修改Ubuntu 8.10的sources.list

系统自带的软件源速度太慢,更新一次安装包竟然要4个多小时,决定换个快点的软件源。这里 http://wiki.ubuntu.org.cn/Template:8.10source 列出了选多的选择,我选择了最下面的台湾官方源。

1
2
3
4
5
6
7
8
9
10
deb http://tw.archive.ubuntu.com/ubuntu intrepid main restricted universe multiverse
deb http://tw.archive.ubuntu.com/ubuntu intrepid-security main restricted universe multiverse
deb http://tw.archive.ubuntu.com/ubuntu intrepid-updates main restricted universe multiverse
deb http://tw.archive.ubuntu.com/ubuntu intrepid-backports main restricted universe multiverse
deb http://tw.archive.ubuntu.com/ubuntu intrepid-proposed main restricted universe multiverse
deb-src http://tw.archive.ubuntu.com/ubuntu intrepid main restricted universe multiverse
deb-src http://tw.archive.ubuntu.com/ubuntu intrepid-security main restricted universe multiverse
deb-src http://tw.archive.ubuntu.com/ubuntu intrepid-updates main restricted universe multiverse
deb-src http://tw.archive.ubuntu.com/ubuntu intrepid-backports main restricted universe multiverse
deb-src http://tw.archive.ubuntu.com/ubuntu intrepid-proposed main restricted universe multiverse

首先备份sources.list

1
sudo cp /etc/apt/sources.list /etc/apt/sources.list.original

然后用vi打开sources.list,把上面列出的源添加进去:

1
sudo vi /etc/apt/sources.list

接着就是更新源:

1
sudo apt-get update

现在我们就可以更新已安装的软件包了:

1
apt-get upgrade

升级已安装的包为最新版本,不会安装新的或移除老的安装包。如果一个包因为改变了倚赖关系而需要安装一个新的包,那么它将不会被升级,会被标志为hold。建议使用“-u”选项,这样你就能看到哪些安装包将会被升级。

如何设置数据窗口中某行某列的背景颜色

假设数据窗口有多行数据,在修改某个Cell的数据后希望能将该Cell的背景色变成红色,代码该如何写呢?

要对某行某列的属性进行更改,可以使用modify函数。在对某行某列的属性进行改变时,你需要先判断当前行是否是被修改数据的那行,如果知道行号的话(例如在itemchanged事件中),你可以使用下面的代码:

1
dw_main.modify(ls_colname + "background.color = '0~tIf(getrow() = " + string(row) + ", 255, 16777215)'")

当然,你也可以这么写:

1
dw_main.modify(ls_colname + "background.color = '0~tIf(getrow() = currentrow(), 255, 16777215)'")

修复wxWidgets Wizard for Visual Studio 2005/2008中的一个bug

前面发布的wxWidgets Wizard for Visual Studio 2005/2008存在一个bug,安装在VS2008中后不能创建新的wxWidgets项目。原因是没有将wxAppWiz.vsz文件中VsWizardEngine的版本号改为9.0。现在做了一些修改,修改后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
procedure CurStepChanged(CurStep: TSetupStep);
var
    i: Integer;
    Signature: String;
    ConfigLine: String;
    ConfigFile: String;
    ConfigFileLines: TArrayOfString;
begin
    if CurStep = ssPostInstall then begin
        if (Pos('Visual Studio 9.0', ExpandConstant('{app}')) > 0) then begin
            Signature := 'Wizard=VsWizard.VsWizardEngine';
            ConfigFile := ExpandConstant('{app}\VCProjects\wxAppWiz.vsz');
            LoadStringsFromFile(ConfigFile, ConfigFileLines);
            for i := 0 to GetArrayLength(ConfigFileLines) - 1 do begin
                if (Pos(Signature, ConfigFileLines[i]) > 0) then begin
                    ConfigFileLines[i] := 'Wizard=VsWizard.VsWizardEngine.9.0'
                    SaveStringsToFile(ConfigFile, ConfigFileLines, False);
                    break;
                end;
            end;
        end;

        Signature := 'wxWidgets';
        ConfigLine := 'wxWidgets|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1043|70' + #13#10;
        ConfigFile := ExpandConstant('{app}\VCProjects\vc.vsdir');
        LoadStringsFromFile(ConfigFile, ConfigFileLines);
        for i := 0 to GetArrayLength(ConfigFileLines) - 1 do begin
            if (Pos(Signature, ConfigFileLines[i]) > 0) then abort;
        end;
        SaveStringToFile(ConfigFile, ConfigLine, True);
    end;
end;

代码下载:https://github.com/dohkoos/wxwizard

com.sybase.jdbc2.jdbc.SybSQLException: SQL Anywhere Error -143: Column '@p3' not found

数据库:Sybase ASA 10

在移植PB程序到Java程序时,碰到了如下的嵌入式SQL语句:

1
2
3
4
5
6
7
8
9
10
SELECT DISTINCT
    bhr_emp_job.emp_nbr,
    bhr_emp_job.cyr_nyr_flg,
    bhr_emp_job.pay_freq,
    bhr_emp_job.job_cd,
    bhr_emp_job.contr_non_std_flg,
    bhr_emp_job.pay_type
FROM bhr_emp_job
WHEN :as_cal_code <> ''
AND :as_cal_code = bhr_emp_job.cal_cd

转换后的SQL代码如下:

1
2
3
4
5
6
7
8
9
10
SELECT DISTINCT
    bhr_emp_job.emp_nbr,
    bhr_emp_job.cyr_nyr_flg,
    bhr_emp_job.pay_freq,
    bhr_emp_job.job_cd,
    bhr_emp_job.contr_non_std_flg,
    bhr_emp_job.pay_type
FROM bhr_emp_job
WHEN ? <> ''
AND ? = bhr_emp_job.cal_cd

结果在执行的时候出现了下面的异常:

1
2
3
4
5
6
7
8
9
10
11
<ERROR>openQuery in org.rsccc.dao.hrs4300.DHrs4300JobcopyDao when executing SELECT DISTINCT
    bhr_emp_job.emp_nbr,
    bhr_emp_job.cyr_nyr_flg,
    bhr_emp_job.pay_freq,
    bhr_emp_job.job_cd,
    bhr_emp_job.contr_non_std_flg,
    bhr_emp_job.pay_type
FROM bhr_emp_job
WHEN ? <> ''
AND ? = bhr_emp_job.cal_cd
com.sybase.jdbc2.jdbc.SybSQLException: SQL Anywhere Error -143: Column '@p3' not found

在Sybase站点上找到的相关资料是Column '%1' not found

Probable cause: You misspelled the name of a column, or the column you are looking for is in a different table.

想到在PB中是在填充变量值后再将SQL语句扔到数据库中执行,而移植后的Java程序中采用的是PreparedStatement来执行SQL语句,所以会出现Column not found的错误。解决方法是将?移到赋值符号的右边:

1
2
3
4
5
6
7
8
9
10
SELECT DISTINCT
    bhr_emp_job.emp_nbr,
    bhr_emp_job.cyr_nyr_flg,
    bhr_emp_job.pay_freq,
    bhr_emp_job.job_cd,
    bhr_emp_job.contr_non_std_flg,
    bhr_emp_job.pay_type
FROM bhr_emp_job
WHEN '' <> ?
AND bhr_emp_job.cal_cd = ?

在EGit-0.3.1中使用Compare With Git Revision

EGit是一个Eclipse环境下的Git客户端插件,EGit的0.3.1版本已经提供了Compare With Revision功能,只是还没有注册到plugin.xml中。所以要使用该功能的话,必须自己动手在ui包中的plugin.xml中添加一些代码,即下面的action部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<objectContribution
        adaptable="true"
        id="org.spearce.egit.ui.fileFolderContributions"
        objectClass="org.eclipse.core.resources.IResource">
    <filter name="projectPersistentProperty"
        value="org.eclipse.team.core.repository=org.spearce.egit.core.GitProvider">
    </filter>
    <action
        class="org.spearce.egit.ui.internal.actions.CompareWithRevisionAction"
        id="org.spearce.egit.ui.internal.actions.CompareWithRevisionAction"
        label="%CompareWithRevisionAction_label"
        menubarPath="compareWithMenu/compareWithGroup"
        overrideActionId="org.eclipse.team.ui.compareLocalHistory"
        tooltip="%CompareWithRevisionAction_tooltip" />
</objectContribution>

另外,还要将CompareWithRevisionAction.java中run方法里的super.action(action)注释掉,否则会报StackOverflowException。

1
2
public void run(IAction action) {
    // super.action(action);

Ubuntu 8.0.4下使用南京广电宽带

南京广电宽带提供了一个特殊的基于DHCP+(一个十分特殊的登录协议)的登录系统,只有依靠它提供的客户端才能登录宽带。客户端可以在 http://www.baron.com.cn/sihua/ 下载。

根据Linux客户端的readme文档知道:登录宽带需要系统已经安装了DHCP客户端软件包,并且已经把网卡配置为动态获取IP地址的模式。

1、检查网络配置

1
ifconfig -a

2、配置DHCP客户端

1
sudo vi /etc/network/interfaces

以下是我机器上interface里面的内容:

1
2
auto lo
iface lo inet loopback

在上述内容的后面添加下面的两条配置命令,然后保存退出。

1
2
iface eth0 inet dhcp
auto eth0

3、重启networking服务,使新的interfaces生效。

1
sudo /etc/init.d/networking restart

使用ifconfig eth0重新检查下网络配置,可以看到一些相应的设置都已经正确了,配置完成。

然后进入宽带客户端的目录~/racer,根据readme文档输入:

1
sudo ./ecou.sh start

这时会出现以下错误信息,这是因为在/usr/lib下没有共享库libpcap.so.0.8.3的缘故。

1
./racer: error while loading shared libraries: libpcap.so.0.8.3: cannot open shared object file: No such file or directory

切到/usr/lib目录,输入ls libpcap*,在我的机器上列出的是:

1
2
libpcap.so.0.8 -> libpcap.so.0.9.8
libpcap.so.0.9.8

输入命令sudo ln -s libpcap.so.0.9.8 libpcap.so.0.8.3,这时候的文件列表为:

1
2
3
libpcap.so.0.8 -> libpcap.so.0.9.8
libpcap.so.0.8.3 -> libpcap.so.0.9.8
libpcap.so.0.9.8

然后重新执行sudo ./ecou.sh start命令就可以上网了。

使用USB在ThinkPad X60上安装Ubuntu 8.04

昨天晚上开始在我的本本上安装Ubuntu 8.04。本本是80G的硬盘,自带有一个XP Home操作系统。现在我想把Ubuntu装在C盘下,也就是不要XP了,并且不想再保留ThinkPad出厂时用来做HPA的隐藏分区,因此可以给Ubuntu使用的主分区就有了四个。分区方案如下:

1
2
3
4
5
Device     Type  MountPoint  Size
/dev/sda1  ext3  /boot       197M
/dev/sda2  swap  /swap       1028M
/dev/sda3  ext3  /home       48800M
/dev/sda4  ext3  /           29997M

Linux至少需要两个分区,一个是根分区,一个是交换分区,这样还剩下两个主分区可以使用。因为/home相当于Windows系统中的My Documents,所以准备给它单独分个区。剩下的一个主分区就给/boot挂载点。分配单独的分区给/boot是有必要的,因为/boot包含了操作系统的内核和在启动系统过程中所要用到的文件,这样就算工作分区出了问题,只要这个分区没有问题,系统照样可以启动。

安装步骤:

  1. 准备一个至少1G优盘;
  2. 下载Ub8convert2.exe。运行这个文件,将会获得一个Ubuntu8目录;
  3. 下载ubuntu-8.04-desktop-i386.iso,将它放到Ubuntu8目录下;
  4. 运行Ubuntu8目录下的fixu8.bat脚本(注意:fixu.bat采用的是utf-8编码,需要重新编辑该文件中的盘符);
  5. 现在就可以使用U盘来安装Ubuntu了。

注意:如果内存小于512M,那么最好分配两倍内存容量的swap分区。否则只要2的n次方就可以了。

[SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property

使用Tomcat 6.0.16搭配Eclipse创建Dynamic Web Project后,在项目上按右键,选择Run As -> Run on Server方式启动Tomcat服务器。在Console工作台中就会出现如下的红色警告信息,让人不爽。

1
2
3
4
5
2008-6-4 21:49:00 org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:cont' did not find a matching property.
2008-6-4 21:49:00 org.apache.catalina.core.AprLifecycleListener init
2008-6-4 21:49:00 org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080

在网上查找答案,有的说将Tomcat的版本换成6.0.14就可以了;还有的说在建立Dynamic Web Project时把“Dynamic Web Module”选项后面的版本号由2.5改成2.4也行。不过这些回答好像都不能真正地解决问题。只能自己想办法了。

实际上出现SetPropertiesRule警告的原因是因为Tomcat在server.xml的Context节点中不支持source属性:

1
<Context docBase="xxx" path="/cont" source="org.eclipse.jst.j2ee.server:cont" />

解决方法是在Server的配置界面中选中“Publish module contexts to separate XML files”选项。