2004年11月19日星期五

Cygwin: 搞定XFCE 4.2rc1

前两日搞定将xfce 4.2rc1(4.1.99.1)移植到cygwin的补丁,在原来4.2beta1(4.1.90)上做的,并没有改多少,但一些补丁修了一下。

因为搬家后在家里没有电脑用了,也就没有办法提供编译好的版本了,目前只有补丁,可从我的主页下载
xfce4-4.2rc1-cygwin-patches.zip

xffm还是没有做(在4.2beta1就没有做,因为它似乎越来越难移植了,可执行文件与共享库、插件之间代码分工混乱之极,我还是用我的rox吧,反正还有mc或者windows自己的文件管理工具).

xfce4-print和xfce4-mixer不能完全工作──虽然两者都可以编译通过。

2004年11月18日星期四

How to convert Friends.doc into a CHM file (1)

Part1: Friends.doc -> friends.htm -> friends-thin.htm

1. Open Friends.doc with MS Word and save it into a html file (friends.html). I used Office XP,
and due the garbage info added by M Word, the output file is about 28M!

2. Write a simple script (friends-diet.html) to get rid of the garbage attributes
generated by evil M word, include 'class', 'style' and 'lang' etc.
This would cut the size 75% off!
#!/bin/python

from sgmllib import SGMLParser
import htmlentitydefs
import os, sys

class FriendsDiet(SGMLParser):
def reset(self):
self.output=open("friends-thin.html", "w"[img]/images/wink.gif[/img]
SGMLParser.reset(self)

def unknown_starttag(self, tag, attrs):
if tag=='p':
self.output.write("
n"[img]/images/wink.gif[/img]

elif tag=='span' or tag=='o':
pass
elif tag=='o:SmartTagType' or tag=='SmartTagType':
print "Ignore",tag
pass
else:
strattrs=""
for key, value in attrs:
if (key!='class' and key!='style' and key!='lang' and key[0:5]!='xmlns'):
strattrs = strattrs + ' %s="%s"' % (key, value)

self.output.write("<%s%s>" % (tag, strattrs))

if tag=='body':
self.output.write('n')

def unknown_endtag(self, tag):
if tag!='span' and tag!='p' and tag[0:2]!='o:':
self.output.write("n" % tag)

def handle_data(self, text):
if text.strip()!='':
self.output.write(text+"n"[img]/images/wink.gif[/img]

def handle_charref(self, ref):
self.output.write("&#%s;" % ref)

def handle_entityref(self, ref):
semicolon=""
if htmlentitydefs.entitydefs.has_key(ref):
semicolon=";"
self.output.write("&%s%s" % (ref, semicolon))

if __name__=='__main__':
import sys
parser=FriendsDiet()
#fh=open(sys.argv[1], "r"[img]/images/wink.gif[/img]
fh=open("friends.htm", "r"[img]/images/wink.gif[/img]
content=fh.read()
parser.feed(content)
fh.close()
parser.close()

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月7日星期日

对Debian做了全面升级

昨天将debian做了一次全面升级,主要是将gnome升级到2.6。

感觉linux下的程序可用性好了很多:
  • mplayer可以播放mpeg4了,看X 档案没有问题了
  • wine支持xim了(后来发现早前安装的crossover也可以,看来很早就有了,原来没有注意到
  • openq也可以很容易得下载到编译后的版本,直接装在gaim-1.0.2上
  • firefox用起来很爽,不象原来mozilla那么慢,又比opera强,现在在windows和linux都用firefox了
  • d4x很稳定了,不象原来那样经常崩溃
不爽的地方:
  • gnome还是不太稳定,尤其是panel和nautilus,常常半天没有反应,不知道在做什么。然后过了好长时间又一起弹出来,有时还崩溃; nautilus还不如rox好用
  • gnome的音量控制老是说打不开设备,奇怪,beep-media-player用oss输出是没有任何问题的
另外自己编译了beep-media-player-0.9.7rc, gwhere, rox-2.1.4, leafpad-0.7.5
debian中gnome-commander还是for gnome-1.x的1.0.1版本,加了device后就崩溃,目前正在编译for gnome2的1.1.6
krusader也还是1.4版本,是否要编译最新的1.5版本看看再说,因为要搞一整套编译环境

BTW: Debian升级还是得会解决包冲突才行,有时因为一两个包的影响导致很多软件无法升级

搞定了GNOME下中文件名乱码的问题

Q1: gtk-2.4打开文件对话框对中文显示乱码,都是xxxxxx之类;beep-media-player的id3信息对话框显示的文件名也是乱码

A:设置G_FILENAME_ENCODING=GBK可以解决这个问题 (奇怪的是,我在Cygwin下没有设置这个也很正常,甚至CHARSET, LC_CTYPE都没有设置)


Q2: 上述问题是解决了。但通过gdm登录时,仍然出现乱码,在~/.bashrc和~/.bash_profile设置都不管用,/etc/bash.bashrc和/etc/profile也不好使
A: 查看了一下/etc/X11/Xsession.d/55gnome-session_gnomerc, 发现这个设置应该写在~/.gnomerc中

2004年11月6日星期六

Fw: Scripting your Delphi Application

"In this paper I'll show you how to use the Microsoft ActiveScripting technologies to achieve everything we've just mentioned. While there is more to these technologies than can be covered by a single paper, by the end of this paper you'll know more than enough to start planning how you can use this technology in your application."

Full story: http://www.delphidevelopers.com/learnbooks/Scripting_your_Delphi_Application.htm
PDF created by pdfFactory: Scripting Your Delphi Applications.pdf
AXS_FAQ: Microsoft Active Scripting Frequently Asked Questions

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; GError *error = NULL; + gchar *path = filename_from_utf8(path_req); pixbuf = gdk_pixbuf_new_from_file(path, &error); if (error) { diff -Nurp rox-2.1.2.orig/ROX-Filer/src/support.c rox-2.1.2/ROX-Filer/src/support.c --- rox-2.1.2.orig/ROX-Filer/src/support.c 2004-04-27 18:34:30.000000000 +0800 +++ rox-2.1.2/ROX-Filer/src/support.c 2004-10-11 17:20:42.000000000 +0800 @@ -1083,6 +1083,34 @@ void ensure_utf8(gchar **sp) } } +/* +void filename_from_utf8(gchar **pathp) +{ + gchar *foo = g_filename_from_utf8(*pathp, -1, NULL, NULL, NULL); + if (foo) { + *pathp = g_strdup(foo); + g_free(foo); + } +} */ + +gchar* filename_from_utf8(const gchar* path_u) +{ + gchar *foo = g_filename_from_utf8(path_u, -1, NULL, NULL, NULL); + if (foo) { + return foo; + } else + return g_strdup(path_u); +} + +gchar* filename_to_utf8(const gchar* path) +{

Powered by ScribeFire.