2006年12月27日 星期三

claws-mail vs thunderbird(3): 快捷键设置

claws-mail/sylpheed-claws利用了gtk提供的一个很好的特性: 将焦点移动到一个菜单项上,按下一个键,这个键就成了这个菜单项的快捷键(accelerator)。按Del键就可以删除这个快捷键

gtk程序可以设置~/.gtkrc-2.0文件获得这个功能:
gtk-can-change-accels = 1

GNOME程序可在gconf-editor中钩选如下选项
/desktop/gnome/interface/can-change-accels

但有些应用程序(比如claws-mail)不想依赖这些设置,自己打开了这个功能:
   gtk_settings_set_long_property(gtk_settings_get_default(),
"gtk-can-change-accels",
(glong)TRUE, "XProperty");

可惜thunderbird/icedove没有这个功能,也没有其它的设置快捷键的功能:-(

标签: , ,


2006年12月25日 星期一

升级到gaim-2.0beta,又降下来了

Debian testing中的gaim早升到了2.0beta版,但我一直没有升级,主要是原来在Windows下试用过,gaim-2.0中好像不能单独设置某个协议的状态,我没法单独将QQ或者MSN隐身。

这两天没啥事情,Torchwood也因为没有找到字幕没法看,干脆就来升级这个玩儿 :-)

先做了个备份

$ dpkg-repack gaim
$ dpkg-repack gaim-data
$ dpkg-repack openq

升级:

$ apt-get install gaim

没想到升级后gaim很不稳定,老崩溃。一小时后只能重新安装1.5了:

$ apt-get remove gaim
$ dpkg -i gaim_1.5*.deb openq*.deb

BTW: Debian简直太方便了 :-)

标签: ,


2006年7月15日 星期六

sylpheed-claws(gtk2)总算有了win32版

Here. (没错,目前还不是独立的,只是gpg4win的一部分)

自从切换到gtk2后,sylpheed-claws一直都没有纯win32版本,我本来好几次想来折腾,但既然cygwin版本用得挺好(除了必须得启个X server这点不爽之外)。

标签: ,


2006年6月18日 星期日

图片简易编辑软件: mtPaint

原来我说Linux下似乎没有一个简单的图片编辑软件,GIMP功能虽强但太bloated, 搞得我不得不翻出xv来用。xv其实功能不多,问题倒不少,而且界面操作起来怎么也不太方便。

昨天在gnomefiles上翻到一个mtPaint, 似乎正好可以填补这个空白。抓图、裁剪、缩放、旋转,以及胡乱画几笔,这些基本功能当然都有,锐化、柔化、模糊、浮雕这些简单的特效也有,而且居然支持层和动画!

P.S 在Windows上我用来做图片简单处理的软件是IrfanView,但它不能在上面画(比如画个红框,添点文字什么的),不过同时可以做图片浏览器。

标签: , ,


2006年5月28日 星期日

debian-installer有望使用新的gtk+-directfb

在framebuffer上构建图形界面也是越来越红火了,基于svgalib的肯定是越来越少了。gtk+本来有x11和win32两种front-end,后来见到一个gtk+-directfb,但当时仅仅算是个hacking,倒是debian胆子大,拿来做debian-installer的图形界面,不过也被限定了只能用gtk-2.09版本。

这个directfb front-end已经在合入了gtk+的2.10版本。但gtk+-2.10目前还没有进入debian,于是又有人提供了一份backport,使得可以在gtk+-2.8上使用directfb。

不过debian是否会采用,还没有定论。

PS: Debian Installer图形界面展示(Hiweed定制版)

标签: ,


2006年3月14日 星期二

dia总算出了一个新版本了

只看见了Windows版本,反倒是主页上没什么消息。不过反正也是Windows版本问题多一点,新版本稳定多了。(我倒多是在工作中才会要画些流程图, 所以用Windows版的, 在家里很少用这个.)

另外,Windows版本网站上也可以下载到源代码。

链接: 几个建模工具

标签: ,


2006年3月1日 星期三

geany: 微型IDE

UNIX下编程的人,常常都是用vi, cc和make来折腾,但如果你vi用得不熟悉,又不愿意用anjuta这样的大东西,不妨geany试试这个小玩意。

Geany is a small editor using GTK2 with basic features of an integrated development environment.
Some features:
- syntax highlighting
- code completion
- call tips
- many supported filetypes like C, C++, Java, PHP, HTML, DocBook, Perl, LaTeX, Bash
- symbol lists

标签: ,


2006年2月27日 星期一

又可以用OpenQ了(附win32版本)

网友poppyer针对OpenQ-0.3.2给出了补丁,解决了不让登录的问题(因为Tencent禁用了老登录接口),也解决了不能在Gaim-2.0上编译的问题。

这里应网友kexianbin的要求,编译了一个win32版本:

OpenQ-0.3.2 for Gaim-2.0.0beta2, win32版本

时间匆忙,目前只有DLL,放到plugins目录下即可。而笑脸等数据文件尚未打包进去(先可以从源代码自行提取,或者下载我以前提供的老版本)。

我以前在用gaim-1.5 + OpenQ-0.3.2,似乎要删除原来的帐号配置重新添加才行。

-----------------------------------------------------------

编译方法:

1. 先按gaim的win32编译说明编译gaim;

这里需要补充说明的是,并不需要安装cygwin,这里只是需要使用里面的一些常用命令,用tcl网站提供的msys + mingw包更方便。

另外要升级w32api,可以从mingw网站得到(www.mingw.org可能这边访问不了,但sf.net上的下载是可以的)。

2. 将OpenQ-0.3.2的代码解压,并用poppyer的补丁文件覆盖src目录下的文件; 在gaim-2.0的src/protocols下建立目录qq,将OpenQ的src下的文件移过去,然后将这个Makefile.mingw拷贝到该目录下

3. 编译

$ cd gaim-2.0.0beta2/src/protocols/qq

$ make -f Makefile.mingw

这样就可以得到libqq.dll,拷贝到gaim安装目录的plugins下即可;

4. 拷贝数据文件,拷贝pixmaps文件拷贝夹到gaim的安装目录就可以了。

也许你要问那个Makefile.mingw是怎样产生的,其实很简单,我把GG插件的Makefile.mingw拷贝了一份,然后将GG换成了QQ,再将源代码文件列表C_SRC改一下就行了。

--------------------------------------------------


User Comments
(no subject) [Reply]
bamanzi | 07 三月, 2006 16:14
这两天又看见了一个针对gaim-1.5的补丁,于是又做了一个gaim-1.5的版本,也放在上述位置
(no subject) [Reply]
kexianbin | 14 三月, 2006 01:23
prefs.xml内的pref name='ipfile' type='string' value=''/
(no subject) [Reply]
bamanzi | 14 三月, 2006 09:48
我后来比较过原来的prefs.xml和后来的prefs.xml,也发现只有ipfile不同。但认为这个东西应该没有影响,所以想不明白。另外gaim-2.0似乎没有让设置ipfile的地方了
(no subject) [Reply]
sha | 27 三月, 2006 17:48
我删除了perfs.xml中pref name='ipfile' type='string' value=''/ 加载openQ插件可以正常启动Gaim-2.0.
(no subject) [Reply]
aaron | 29 三月, 2006 09:28
hello ~~ 可以开发一下PSI的QQ插件吗?~win下的~~ http://psi-im.org/home
Re: aaron [Reply]
bamanzi | 29 三月, 2006 19:38
还是到某个论坛上去问问吧,在这里说肯定没有什么用
(no subject) [Reply]
aaron | 30 三月, 2006 16:55
还是到某个论坛上去问问吧,在这里说肯定没有什么用 某个论坛? 哪个论坛?~ 这个不是你开发的吗?~
Re: aaron [Reply]
bamanzi | 30 三月, 2006 22:16
兄台抬爱了,俺可没有那个本事。openq的主页是http://openq.linuxsir.org
(no subject) [Reply]
michael | 04 四月, 2006 12:41
老大gaim-1.5的版本在那里?
Re: michale [Reply]
bamanzi | 04 四月, 2006 21:43
这里: http://gaim.sourceforge.net/win32/
(no subject) [Reply]
everack | 01 八月, 2006 09:26
你好: 是不是这个补丁现在不可以用了啊? 我用gaim2.0b2加这个补丁不行啊.

标签: , ,


2005年9月30日 星期五

BMPx

XMMS2总让我感觉怪怪的,又是SCons又是Python, 还要SQLite, 还分server和client,不管它设计怎么样,我是没有找到以前XMMS(或者更以前的winamp)的感觉,而且到现在连个GUI都没有看到。

所以在freshmeat上看到BMPx这个项目,看来还是有人也这么想(并且会动手去做:-)。

标签: , ,


2005年9月23日 星期五

Windows也可用gaim同时登录MSN, QQ和Gtalk

下载了最新的GaimOpenQ的Windows版本, 安装很顺利, OpenQ跟gaim之间也没有版本兼容性问题。跑起来gtk也不象原来那么容易崩溃了(至少dia的windows版本很是让人不爽)。这下Windows也可以顺当地同时使用MSN, QQ和Gtalk了。

标签: , ,


2005年9月12日 星期一

NextStep-like theme for Gtk2


What do you think about it?

You can find it here: Gtk2-Step, Smooth-Step


标签: ,


2005年8月23日 星期二

Ridley: libgnome must die

The GTK+ developers have announced a new initiative called "Project Ridley." The idea is to get rid of a number of the small libraries which follow GNOME applications around, merging their functionality into the core GTK+ toolkit. The end result will likely be the GTK+-3.0 release. More information can be found in the announcement (click below) or on the Project Ridley wiki page.

希望这个项目的诞生可以减轻编译gnome平台的麻烦程度。

标签: ,


2005年7月30日 星期六

glib2,gtk2,pygtk2 reference in CHM format

I modified devhelp2chm a little, to workaround a problem I found when using gnochm to read the CHM files generated by it.

And updated two CHM files generated by it:
glib2/gtk2 gtk-2.6.8, glib-2.6.5, including FAQ and tutorial
(source: package libgtk2.0-doc, libglib2.0-doc)
pygtk2 reference pygtk2ref 2.6.0, and GtkSourceView, GtkSpell, GnomePrint, GnomePrintUI, GtkMozembed
(source: pygtk2 website)


----------------

How to build:

gtk2.chm:

apt-get install libglib2.0-doc libgtk2.0-doc
cd /usr/share/gtk-doc/html/
DIRS="gtk/ gdk/ gdk-pixbuf/ gtk-faq/ gtk-tutorial/ glib/ gobject/"
find $DIRS -name '*.devhelp.gz' | xargs gunzip
for d in $DIRS; do
(cd $d;
echo $d
for f in *.html; do
sed 's#/usr/share/gtk-doc/html/#../#' $f > $f.tmp
mv $f.tmp $f
done)
done
find $DIRS -name '*.devhelp | xargs ~/bin/devhelp2chm-v2.sh
-p gtk2 -T "GTK+ Reference Manual" -t gtk/index.html

...Then use HtmlHelp Workshop to build it.

pygtk2ref.chm

wget http://www.pygtk.org/dist/pygtk2reference.tbz2
tar jxf pygtk2reference.tbz2
find . -name '*.devhelp' | xargs ~/bin/devhelp2chm-v2.sh
-p pygtk2ref -T "PyGTK2 Reference" -t pygtk2reference/index.html

标签: , ,


2005年7月22日 星期五

My Cygwin Repository Updated

New:

Updated:


标签: ,


2005年5月25日 星期三

Disk Catalog类软件

我这人是个三脚猫,什么都喜欢玩一玩,GTK/GNOME, Cygwin, Delphi, Python...时间长了,也就搜集了不少东西,所以隔一段时间就把自己近期搜集的东西刻录成一张盘。但刻的盘多了,找东西就费劲了。这时就需要 Disk Catalog类软件。

在Windows下我觉得比较好用的这类软件是Where Is It。它可以支持多种方式提取文件描述:

- 从文件中提取描述信息信息,比如HTML文件的标题,MP3文件的歌名、演唱者、专辑名称,PDF的标题、主题和书签,M$ Office文档的标题
- 从files.bbs, 00index.txt, descript.ion等文件提取文件描述信息
- 从CDDB服务器提取CD里面歌曲的名称
- 从图片提取缩略图(thumbnails)
- 从压缩包类提取文件列表

另外它还提供了插件接口,网站上提供了不少扩展插件,用户也可以自己用Desc API来编写插件(还是Delphi写的!),我自己就写了用于CSDN index和Debian Package的插件。

在GNU/Linux上,也试用过一些(基本上只用过基于Gtk/Gnome的),觉得功能比较强一点的也就是gtktalog了。 gtktalog可以做到上面的功能1、4。对于功能1,它可以根据MIME类型调用一个命令行来获取文件的描述信息,而GNU/Linux下有丰富的命令行程序来做这个,比如对于rpm文件可以用rpm -qpi %s提取包的描述,这要比Where Is It的编程接口方便多了。

(不过gtktalog的MIME判断有点问题,比如对于Debian Package包,通过设置界面添加时,它根据.deb的后缀猜测(guess)出"application/x-deb",我配上对应的命令行 "dpkg-deb --info "之后却根本提取不到包的描述信息,调试之后发现MIME类型应该是"application/x-dpkg",并且在gtktalog设置界面上还不让你添加(说是MIME类型不合法),只能自己修改配置文件~/.gtktalog/gtktalog.cf搞定) 。

另外GWhere有时也用,虽然功能比较弱,但因为它只需要Gtk2,不需要Gnome库,所以在Windows和Cygwin上都可以编译成功,也就可以跨平台使用。

标签: , , ,


2005年5月24日 星期二

Gtk2 patch for gnome-commander-1.1.6

As Debian doesn't have the gnome2 version of gnome-commander, I have to build it by self.

But the problem is a function called _gtk_clist_create_cell_layout is used by the gnome2 version gnome-commander. The symbols started with an '_' are private symbols of gtk2, they should not be used by applications (in old days, these symbols are also exported by gtk2 on some distributions, but not debian).

I just found Mandrake provides this version of gcmd, thus I download the SRPM, and found the patch from it.

===================================================================
RCS file: /cvs/gnome/gnome-commander/src/gnome-cmd-clist.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnome-commander/src/gnome-cmd-clist.c 2004/01/08 20:11:28 1.3
+++ gnome-commander/src/gnome-cmd-clist.c 2004/05/03 18:20:18 1.4
@@ -226,6 +226,46 @@
}


+PangoLayout *
+my_gtk_clist_create_cell_layout (GtkCList *clist,
+ GtkCListRow *clist_row,
+ gint column)
+{
+ PangoLayout *layout;
+ GtkStyle *style;
+ GtkCell *cell;
+ gchar *text;
+
+ get_cell_style (clist, clist_row, GTK_STATE_NORMAL, column, &style,
+ NULL, NULL);
+
+
+ cell = &clist_row->cell[column];
+ switch (cell->type)
+ {
+ case GTK_CELL_TEXT:
+ case GTK_CELL_PIXTEXT:
+ text = ((cell->type == GTK_CELL_PIXTEXT) ?
+ GTK_CELL_PIXTEXT (*cell)->text :
+ GTK_CELL_TEXT (*cell)->text);
+
+ if (!text)
+ return NULL;
+
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (clist),
+ ((cell->type == GTK_CELL_PIXTEXT) ?
+ GTK_CELL_PIXTEXT (*cell)->text :
+ GTK_CELL_TEXT (*cell)->text));
+ pango_layout_set_font_description (layout, style->font_desc);
+
+ return layout;
+
+ default:
+ return NULL;
+ }
+}
+
+
static void
draw_row (GtkCList *clist,
GdkRectangle *area,
@@ -389,7 +429,7 @@

/* calculate real width for column justification */

- layout = _gtk_clist_create_cell_layout (clist, clist_row, i);
+ layout = my_gtk_clist_create_cell_layout (clist, clist_row, i);
if (layout)
{
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);

标签: , ,


2005年4月29日 星期五

GtkList/GtkListView的查找快捷键

一直以来,对于Gtk程序中的列表(GtkList, GtkCList或者GtkListView),总是不能通过按首字母跳转到相应项目上去,很是不爽。今天无意中敲到了Ctrl+F,发现居然有个小搜索框。

记得当初gtk-2.4要添加GtkFileChooser时,FootNotes上 对于界面原型中"用Ctrl-L打开一个路径输入框"这点争论了半天(但我找不到具体的URL了,也许是这个)。反对者的意见是这样不直观,不看文档的话谁会知道这个 快捷键呢,用户要跳转到某个目录只能一层一层地点; 支持者的意见是这样界面比较简洁,“我们为什么要做得象Windows一样呢?" 对于这个问题,我的意见是反对不显示出来。

回到刚才说的Ctrl+F,好在这个搜索框是直接现在在窗口上,不是一个模态的,还算好用(Firefox后来也改成了这样,而不是原来的Windows风格的对话框。这个搜索框的模态问题其实Jef Raskin在The Humane Interface里特别讲到过)。

P.S. 我将键盘上所有字母键和Ctrl的组合都按了一遍,想看看还有没有别的什么(答案是没有)。

又: 当初别人说KDE比GNOME好(至少是好用),我还跟他们争论一番,最近似乎没有太多底气了,尤其是放弃维护Cygwin GNOME 2.x以及前两天Slackware宣布移除GNOME之后。

标签: ,


2005年4月4日 星期一

Cygwin port of sylpheed-claws-gtk2-1.9.6cvs1

Here come the cygwin port sylpheed-claws-gtk2-1.9.6cvs1.

Only source patch available. Due to bandwidth limit, I can't upload the binary to my repository
now (Due to this reason I haven't updated it for serveral months :-(.
Now I have a lot of pending packages: xfce-4.2.0, rox-2.2, etc).

This patch was based on the source package provided by debian (experimental) , for its convenience, as it was preprocessed with autoconf/automake.

Usage:
$ tar zxvf sylpheed-claws-gtk2_1.0.1cvs1_orig.tar.gz $ patch -p1 -b < sylpheed-claws-gtk2-1.0.1cvs1-1.diff $ ./sylpheed-claws-gtk2-1.0.1cvs1-1.sh mkdirs patch config make install package

And I also uploaded the source patch for gtk1 version of 1.0.1.

标签: , ,


2005年3月21日 星期一

给Knoppix动态添加中文支持(4)

今日搞定几个我常用的gtk程序: gtk1的gtansgtktalog, gtk2的gqviewbeep-media-player

Chinese live extension for Knoppix - gqview, beep-media-player

本来还想加上我比较喜欢的rox的,但因为官方版本对非UTF-8的文件名支持不好(以前我胡乱弄了个补丁),所以没弄。
而且似乎Knoppix上也没有必要用这个文件管理器,除非打算在性能差的机器上不用KDE做桌面。

stardict没有搞成功,因为需要很多gnome的库,

BTW: 刚发现debian上似乎非得用LANGUAGE这个环境变量才能让程序文字生效,比如LANGUAGE=zh_CN beep-media-player。但我在Cygwin上从来都是只用LANG和LC_MESSAEGS的。



1. GQview 1.4.5

这个比较简单,不需要读取什么数据文件,只要将usr/bin/gqview拷贝到~/.dist/bin就可以了。

但Help菜单下的几个菜单项会读取/usr/share/doc/gqview/README,我替换成了/home/knoppix/.gqview/README(恰好一样长!),不过不做这一步也没有问题。

如果想要中文翻译,将/usr/share/locale/zh_CN/LC_MESSAGES/gqview.mo拷贝到~/.dist/下相应的目录即可。因为我们前几天已经做了mount --bind映射了

2. beep-media-player
Knoppix自带xmms, 但这个不如bmp好看,而且不用自己配置中文(只要有中文字体就可以了)——虽然xmms配置中文也不难

cp beep-media-player/usr/bin/beep-media-player $DESTDIR/usr/bin
perl -pi -e 's#/usr/share/bmp#./../share/bmp#g' $DESTDIR/usr/bin/beep-media-player #注1
# add a wrapper
cat <$DESTDIR/bin/beep-media-player
#!/bin/sh
cd `dirname $0`/../usr/bin
exec ./beep-media-player $*
EOF
chmod 755 $DESTDIR/bin/beep-media-player

#shared library required by bmp
cp beep-media-player/usr/lib/libbeep.so.2.0.0 $DESTDIR/lib
(cd $DESTDIR/lib && ln -s libbeep.so.2.0.0 libbeep.so.2 )
sudo ldconfig # is this really needed?

# data (glade,
rsync -Ha beep-media-player/usr/share/ $DESTDIR/usr/share/

# now the Skins dir. Let bmp share the same Skins with xmms
[ ! -d ~/.xmms/Skins ] && mkdir -p ~/.xmms/Skins
[ ! -d ~/.bmp/Skins ] && (cd ~/.bmp && ln -s ../.xmms/Skins .)

# now the Plugins dir.
[ ! -d ~/.bmp/Plugins ] && mkdir -p ~/.bmp/Plugins
rsync -Ha beep-media-player/usr/lib/bmp/ ~/.bmp/Plugins/ #注2

#1: 注意perl行的语句里面最后有个g,表示行内全部替换,前两天没有留意这个
#2: 这里将自带的插件也都放到~/.bmp/Plugins下。当然用相对路径替换掉/usr/lib/bmp也是可以的,这里只是为了说明有时也可以利用程序自己的功能(比如回头我们可以试试按这个思路给Knoppix自带的gaim添加QQ插件)

标签: , ,


2005年3月11日 星期五

GTK2 port of sylpheed-claws

从debian的experimental里面下载了sylpheed-claws-gtk2,在cygwin下顺利地编译通过。
运 行起来感觉相当不错,至少中文显示不用配置了,也可以编写新邮件了(我是说可以直接输入中文了,gtk1版本里它自己扩展的gtkstext控件不支持 XIM,我一直都是在别的程序里面输入了邮件内容再贴过去)。 唯 一的问题就是删除、移动邮件的时候速度有些慢,另外不是很稳定。

[@more@]
原 来就看见sylpheed-claws的主页上开始有gtk2版本的信 息了,但一直没有正式发过版本,都是cvs中取,我一向懒得自己去cvs里面折腾(除了原来搞rrafs时嫌它版本间隔太长就自己从cvs检版本),而且 又要autoconf, automake什么的,晕。

前两日看见debian-chinese邮件列表上有朋友在问sylpheed- claws的中文输入问题,居然是讲gtk2版本版本的,开始还以为他自己折腾的,没想到在debian的experimental里面看见已经有 sylpheed-claws-gtk2了。今天有点时间,将debian准备好的源代码包下载下来捣腾。本来以为编译会有很多新问题,先用make -i就出去吃饭去了,准备回来解决问题,没想到出奇地顺利,除了trayicon需要链接libX11之外,没有碰到什么问题。

迫不及待跑起来(先备份了gtk1版本的配置文件),先就留意到终端上输出
/home/glyoung/.sylpheed-gtk2/sylpheedrc: fopen: No such file or directory
看来它跟gtk1版本的配置文件(~/.sylpheed)是分开的,挺好。

接着居然出现一个配置向导,说是没有创建帐户。记得原来是没有这个的,也挺好。

设置邮箱为原来的邮箱位置,嘿,读取正常,邮件列表里中文标题显示也没有问题,打开一封中文邮件,显示正常,根本不需要自己再去配置字体。然后启动xorg-x11和xfce4,启动输入法,再重新运行,新建邮件,嘿嘿,可以输入中文了。

最后用zh_CN.gbk为locale试了一下,再截了一张图。

标签: ,


gtkpod又升级了(0.88发布)

前两天刚下载的0.87版本,今天就看见gnomefiles.org的最近更新上有gtkpod 0.88出现了。

ChangeLog上说开始支持iPod Shuffle了。可惜还是不支持Audiobooks。

另外我倒是很希望有歌词编辑功能: 单独一个窗口(非模态), 选中一首歌曲就可以在里面编辑歌词。
原来找到一个PodLyrics实在是不怎么样,还不如自己来写一个。

标签: ,


2005年3月8日 星期二

Grouping support of iPod

几天前在搭车时跟yoyo闲聊还说,iPod有一个地方很不爽,只能全盘随机(在Playlists入口上按播放键即可,并不一定要新版本提供的Shuffle Songs命令支持,个人觉得Shuffle更多地是一个概念,作为一个卖点),然后我就可能先听一首轻音乐,接着就是Nirvana的Grunge,然
后又是评书《隋唐演义》,张学友的《她来听我的演唱会》,Nick Drake的民谣,X
Files的声轨......怎么就不能让我选择只在古典音乐里面随机,或者只在摇滚里面随机......

今天折腾gtkpod,无意发现smart playlist编辑器里面有一个Grouping条件, 看着很象我要的东西。

仔细研究一下,果然。

但以前没有看到过啊?回头检查,发现ChangeLog里面有一条:

IMPROVEMENT: Support for iTunes' "checked", file descriptor (kind), and grouping fields

果然是新增的。

Powered by ScribeFire.

标签: ,


2005年3月5日 星期六

gtkpod总算支持smart playlist了

因为iTunes在不自动同步的方式下不能删除文件,所以自然地想起用gtkpod来删除。

但gtkpod不支持smart playlist这一点让我很是不爽,一用它,就都变成普通列表了。

今天检查gtkpod的新版本,发现gtkpod总算支持smart playlist




为了试验Audiobook功能,转换了《大长金》的第一集进去,果然可以记录停止位置,下次再接着来,但调整速率的功能却没有看到。

不管它,开始多弄几个上次。问题是刚才这个文件怎么删除? 还是用熟悉的gtkpod吧,它有删除文件的功能(XP系统重装过一次,其他的iPod工具都不在了,唯独cygwin里面的东西保存完好)。

但gtkpod不支持smart playlist这一点让我很是不爽,一用它,就都变成普通列表了。所以我每次都是先备份iTunesDB文件,然后用gtkpod来删除不需要的mp3,然后恢复iTunesDB, 再用iTunes来playlist删除里面的条目。

来到http://gtkpod.sourceforge.net,检查一下ChangeLog,嘿嘿,最新版本0.87里面已经有了smart playlist的支持!

编译, 运行,挺好,至少smart playlist都还在,而且读写iTunesDB的速度也比原来快了。


不过还有个问题,应该算iTunes或者iPod的: 我用gtkpod删除了一个Audiobook的文件,也在iTunes上从Playlist里面删除了对应条目,但打开iPod,从Audiobook进去还是有对应的条目信息在,当然是播放不了的(因为文件已经删除了),估计是添加m4b文件时iTunes又在什么地方写了东西进去。

BTW: 居然有一个专门讲smart playlists的网站: http://smartplaylists.com/
而且看了首页上的一篇文章我才知道原来smart playlist还可以将一些playlist组合起来,比如Ratings-weighted playlist一文提到的创建一个play higher rated songs more
often的playlist,唉,看来自己用了大半年的iPod,才发现自己根本就不会使用smart playlist.

标签: ,


2004年11月16日 星期二

gwhereviewer.py: 用PyGTK2写的gwhere数据文件查看工具

用PyGTK2写了一个gwhere的数据文件的查看工具。
gwhere是一个disk catalog工具,类似于gtktalog以及windows上的WhereIsIt。

我的远期目标是写一个完整的disk catalog工具,数据格式上兼容gwhere,但脚本的方式可以让我轻松地扩展description提取器。

下载脚本: gwhereviewer.py

在Cygwin上测试通过,但用纯win32版本的gtk+/pygtk时会崩溃,不知道为什么

标签: ,


2004年11月5日 星期五

Create a CHM file for PyGTK2 Tutorial

Document source: PyGTK2 Tutorial[1]
[1] http://www.pygtk.org/dist/pygtk2tutorial.tgz

The main problem is to parse the contents from index.html write then into a HHC file for MS HtmlHelp Workshop.

You can use this simple script to do this (see below)
pygtk-index2hhc.py pygtk2tut.hhc index.html


P.S:
As to the PyGTK2 Reference[2], you can download the devhelp index file[3], and then use my devhelp2chm.sh[4]to get the .HHP, .HHC and .HHK.
[2] http://www.pygtk.org/dist/pygtk2reference.tbz2
[3] http://www.moeraki.com/pygtkreference/pygtk2reference.devhelp.gz
[4] http://www.linuxeden.com/forum/blog/resserver.php?blogId=110848&resource=devhelp2chm.sh







#!env python from sgmllib import SGMLParser import htmlentitydefs from chmmaker import HHCWriter import os class ContentParser(SGMLParser): def __init__(self, outputfile): self.hhcwriter = HHCWriter(outputfile) self.hhcwriter.print_header() SGMLParser.__init__(self) def __del__(self): self.hhcwriter.print_footer() def reset(self): SGMLParser.reset(self) # some temp variables self.level=0 self.title = self.url = "" self.in_href = False def start_dd(self, attrs):
self.hhcwriter.hhcfile.write("&lt;UL&gt;")

def end_dd(self):
self.hhcwriter.hhcfile.write("
&lt;/UL&gt;")

def start_a(self, attrs): for attr in attrs: if attr[0].lower()=='href': self.in_href = True self.title = "" self.url = attr[1] break def end_a(self): if self.in_href and self.title and self.url: self.on_href(self.title.replace('"', ""), self.url) self.in_href = False self.title = self.url = "" def handle_data(self, text): self.title += text def handle_charref(self, ref): if self.in_href: self.title += "&#%(ref)s;" % locals() def handle_entityref(self, ref): if self.in_href: self.title += "&%(ref)s" % locals() if htmlentitydefs.entitydefs.has_key(ref): self.title += ";" def on_href(self, title, url): target=url if url[-3:]=='fig': target= "" if title and target: self.hhcwriter.add_topic(title, target) if __name__=='__main__': import sys if len(sys.argv)&lt;3: print "Usage: %s hhcfilename index.html" % sys.argv[0] sys.exit() trans=ContentParser(sys.argv[1]) fh=open(sys.argv[2], "r"[img]/images/wink.gif[/img] try: trans.feed(fh.read()) except: pass trans.close() fh.close()
# vim:expandtab softtabstop=4


Powered by ScribeFire.

标签: , ,


2004年11月3日 星期三

rox-2.1.2文件名UTF-8补丁

nautilus太笨重了; 新版本的xffm似乎比以前更难移至了; gnome-commander的gnome-1版本在没有FAM的情况下总需要手工刷新,gnome2也老是出问题。于是我开始沉下心来用rox。

但它似乎对于在中文文件名(应该是非ANSI字符)上有不少问题,比如对路径包含中文的话,加到书签里之后又无法跳过去,拷贝、移动、删除的时候老是报告路径找不到。

琢磨了一阵,基本上可以用了: rox对于文件名没有进行编码转换就直接交给了gtk2显示,但gtk2要求非ansi字符在显示时必须采用UTF-8编码。这个补丁可以修正这个问题,在Cygwin上和Linux都试过了,但在Cygwin上还不太稳定。

diff -Nurp rox-2.1.2.orig/ROX-Filer/src/action.c rox-2.1.2/ROX-Filer/src/action.c --- rox-2.1.2.orig/ROX-Filer/src/action.c 2004-01-22 04:03:16.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/action.c 2004-10-11 19:23:10.000000000 +0800 @@ -887,12 +887,14 @@ static void do_usage(const char *src_pat } /* dest_path is the dir containing src_path */ -static void do_delete(const char *src_path, const char *unused) +static void do_delete(const char *src_path_req, const char *unused) { struct stat info; gboolean write_prot; char *safe_path; + gchar *src_path = filename_from_utf8(src_path_req); + check_flags(); if (mc_lstat(src_path, &info)) @@ -994,10 +996,12 @@ static void do_eject(const char *path) /* path is the item to check. If is is a directory then we may recurse * (unless prune is used). */ -static void do_find(const char *path, const char *unused) +static void do_find(const char *path_req, const char *unused) { FindInfo info; + gchar *path = filename_from_utf8(path_req); + check_flags(); if (!quiet) @@ -1081,11 +1085,13 @@ static struct mode_change *nice_mode_com return retval; } -static void do_chmod(const char *path, const char *unused) +static void do_chmod(const char *path_req, const char *unused) { struct stat info; mode_t new_mode; + gchar *path = filename_from_utf8(path_req); + check_flags(); if (mc_lstat(path, &info)) @@ -1159,10 +1165,12 @@ static void do_chmod(const char *path, c } } -static void do_settype(const char *path, const char *unused) +static void do_settype(const char *path_req, const char *unused) { struct stat info; + gchar *path = filename_from_utf8(path_req); + check_flags(); if (mc_lstat(path, &info)) @@ -1257,8 +1265,9 @@ static const char *make_dest_path(const else leaf++; } + gchar *leaf_copy = filename_from_utf8(leaf); - return make_path(dir, leaf); + return make_path(dir, leaf_copy); } /* If action_leaf is not NULL it specifies the new leaf name */ @@ -1510,8 +1519,11 @@ static void do_move2(const char *path, c /* Copy path to dest. * Check that path not copied into itself. */ -static void do_copy(const char *path, const char *dest) +static void do_copy(const char *path_req, const char *dest_req) { + gchar *path = filename_from_utf8(path_req); + gchar *dest = filename_from_utf8(dest_req); + if (is_sub_dir(make_dest_path(path, dest), path)) printf_send(_("!ERROR: Can't copy object into itselfn")); else @@ -1524,8 +1536,11 @@ static void do_copy(const char *path, co /* Move path to dest. * Check that path not moved into itself. */ -static void do_move(const char *path, const char *dest) +static void do_move(const char *path_req, const char *dest_req) { + gchar *path = filename_from_utf8(path_req); + gchar *dest = filename_from_utf8(dest_req); + if (is_sub_dir(make_dest_path(path, dest), path)) printf_send( _("!ERROR: Can't move/rename object into itselfn")); @@ -1536,10 +1551,13 @@ static void do_move(const char *path, co } } -static void do_link(const char *path, const char *dest) +static void do_link(const char *path_req, const char *dest_req) { const char *dest_path; + gchar *path = filename_from_utf8(path_req); + gchar *dest = filename_from_utf8(dest_req); + check_flags(); dest_path = make_dest_path(path, dest); @@ -1566,6 +1584,7 @@ static void do_mount(const guchar *path, const char *argv[3] = {NULL, NULL, NULL}; char *err; + /* path = filename_from_utf8(path); */ check_flags(); argv[0] = mount ? "mount" : "umount"; diff -Nurp rox-2.1.2.orig/ROX-Filer/src/bookmarks.c rox-2.1.2/ROX-Filer/src/bookmarks.c --- rox-2.1.2.orig/ROX-Filer/src/bookmarks.c 2004-03-25 21:03:44.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/bookmarks.c 2004-10-11 16:58:26.000000000 +0800 @@ -380,8 +380,10 @@ static xmlNode *bookmark_find(const gcha same = strcmp(mark, path) == 0; xmlFree(path); - if (same) + if (same) { + printf("This path already in bookmark listn.", path); return node; + } } return NULL; @@ -410,10 +412,12 @@ static void bookmarks_add(GtkMenuItem *m bookmarks_add_dir(filer_window-&gt;sym_path); } -static void bookmarks_add_dir(const guchar *dir) +static void bookmarks_add_dir(const guchar *dir_req) { xmlNode *bookmark; + gchar *dir = filename_to_utf8(dir_req); + if (bookmark_find(dir)) return; @@ -439,8 +443,10 @@ static void bookmarks_activate(GtkMenuSh mark = gtk_label_get_text(label); } - if (strcmp(mark, filer_window-&gt;sym_path) != 0) - filer_change_to(filer_window, mark, NULL); + gchar *path = filename_from_utf8(mark); + + if (strcmp(path, filer_window-&gt;sym_path) != 0) + filer_change_to(filer_window, path, NULL); if (g_hash_table_lookup(fstab_mounts, filer_window-&gt;real_path) && !mount_is_mounted(filer_window-&gt;real_path, NULL, NULL)) { diff -Nurp rox-2.1.2.orig/ROX-Filer/src/display.c rox-2.1.2/ROX-Filer/src/display.c --- rox-2.1.2.orig/ROX-Filer/src/display.c 2004-04-27 18:34:30.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/display.c 2004-10-11 18:00:40.000000000 +0800 @@ -759,15 +759,24 @@ void display_update_view(FilerWindow *fi view-&gt;layout = NULL; } + gchar *u8 = filename_to_utf8(item-&gt;leafname); if (view-&gt;layout) { /* Do nothing */ } +#ifndef __CYGWIN__ else if (g_utf8_validate(item-&gt;leafname, -1, NULL)) { view-&gt;layout = gtk_widget_create_pango_layout( filer_window-&gt;window, item-&gt;leafname); } +#else /* on Cygwin(Windows), filenames should be in local charset, rather than UTF-8, */ + else if (g_utf8_validate(u8, -1, NULL)) + { + view-&gt;layout = gtk_widget_create_pango_layout( + filer_window-&gt;window, u8); + } +#endif else { PangoAttribute *attr; diff -Nurp rox-2.1.2.orig/ROX-Filer/src/dropbox.c rox-2.1.2/ROX-Filer/src/dropbox.c --- rox-2.1.2.orig/ROX-Filer/src/dropbox.c 2004-01-22 04:03:16.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/dropbox.c 2004-10-11 18:00:50.000000000 +0800 @@ -177,6 +177,7 @@ void drop_box_set_path(DropBox *drop_box gtk_widget_set_sensitive(drop_box-&gt;buttons, FALSE); } + ensure_utf8(&copy); gtk_label_set_text(GTK_LABEL(drop_box-&gt;label), copy); g_free(copy); } diff -Nurp rox-2.1.2.orig/ROX-Filer/src/filer.c rox-2.1.2/ROX-Filer/src/filer.c --- rox-2.1.2.orig/ROX-Filer/src/filer.c 2004-04-13 17:04:04.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/filer.c 2004-10-11 16:58:38.000000000 +0800 @@ -2102,10 +2102,12 @@ void filer_add_tip_details(FilerWindow * g_object_unref(info); } +#ifndef __CYGWIN__ /* TODO: use G_BROKEN_FILENAME/G_FILENAME_ENCODINGS ?? */ if (!g_utf8_validate(item-&gt;leafname, -1, NULL)) g_string_append(tip, _("This filename is not valid UTF-8. " "You should rename it.n")); +#endif } /* Return the selection as a text/uri-list. diff -Nurp rox-2.1.2.orig/ROX-Filer/src/menu.c rox-2.1.2/ROX-Filer/src/menu.c --- rox-2.1.2.orig/ROX-Filer/src/menu.c 2004-05-01 00:36:42.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/menu.c 2004-10-11 16:59:02.000000000 +0800 @@ -1024,7 +1024,7 @@ static void find(FilerWindow *filer_wind * both the current and new paths. * NOTE: This function unrefs 'image'! */ -static void savebox_show(const gchar *action, const gchar *path, +static void savebox_show(const gchar *action, const gchar *path_req, MaskedPixmap *image, SaveCb callback, GdkDragAction dnd_action) { @@ -1032,6 +1032,7 @@ static void savebox_show(const gchar *ac GtkWidget *check_relative = NULL; g_return_if_fail(image != NULL); + gchar *path = filename_to_utf8(path_req); savebox = gtk_savebox_new(action); gtk_savebox_set_action(GTK_SAVEBOX(savebox), dnd_action); @@ -1293,8 +1294,10 @@ void menu_show_options(gpointer data, gu } static gboolean new_directory_cb(GObject *savebox, - const gchar *initial, const gchar *path) + const gchar *initial, const gchar *path_req) { + gchar *path = filename_from_utf8(path_req); + if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO)) { report_error("mkdir: %s", g_strerror(errno)); @@ -1325,9 +1328,11 @@ static void new_directory(gpointer data, } static gboolean new_file_cb(GObject *savebox, - const gchar *initial, const gchar *path) + const gchar *initial, const gchar *path_req) { int fd; + + gchar *path = filename_from_utf8(path_req); fd = open(path, O_CREAT | O_EXCL, 0666); diff -Nurp rox-2.1.2.orig/ROX-Filer/src/pinboard.c rox-2.1.2/ROX-Filer/src/pinboard.c --- rox-2.1.2.orig/ROX-Filer/src/pinboard.c 2004-03-07 02:50:48.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/pinboard.c 2004-10-11 19:23:38.000000000 +0800 @@ -753,6 +753,7 @@ static void drag_backdrop_dropped(GtkWid radios = g_object_get_data(G_OBJECT(dialog), "rox-radios"); g_return_if_fail(radios != NULL); + /*gchar *path = filename_from_utf8(path_req); */ if (mc_stat(path, &info)) { delayed_error( @@ -2088,12 +2089,13 @@ static void create_pinboard_window(Pinbo } /* Load image 'path' and scale according to 'style' */ -static GdkPixmap *load_backdrop(const gchar *path, BackdropStyle style) +static GdkPixmap *load_backdrop(const gchar *path_req, BackdropStyle style) { GdkPixmap *pixmap; GdkPixbuf *pixbuf;