BLOG > Zaurus / ARM > 修正了Justreader 2.0k在pdaXrom上的Bug
修正了Justreader 2.0k在pdaXrom上的Bug
文章信息
关键字:pda;zaurus;justreader
本文版本:4
最后修改于 2007-03-09 11:51:25
Justreader是一款非常棒的电子书阅读软件,它是一个基于QT3的应用程序。在pdaXrom上,不知道是因为QT的兼容问题还是什么别的原因,导致了Justreader有一部分功能不能正常使用。例如,无法设置颜色和控制键等等,给使用上带来了诸多的不便。
幸好Justreader是一个开源软件,我下载了它的源代码,仔细研究,折腾了三天,终于被我修正了这些Bug,并重新编译打包,做了个改进版出来给大家使用。在这个新的版本里(我称之为Justreader 2.0k-fiX版,大写的X表示是针对X环境下使用的改进),还应ccpaging的要求,增加了在进度栏显示翻页时时间的小功能。因为这个家伙,经常全屏看书太投入,结果忘了时间,哈哈。
看看这个fiX版的 改变吧:
修正了无法打开中文文件名的PDB文件的Bug
打开StreamPalm*.cpp文件,一共有五个,找到它们的 openFile() 方法,在里面都可以看到有这样一行代码:
C代码:
在这里latin1会丢弃UTF-8的中文字符,所以导致了无法打开中文文件名的PDB文件。把这些文件里的openFile方法里的这一句都改成
C代码:
这样就能解决问题啦。
修正了无法设置/保存颜色设定和键盘控制的Bug
颜色设定的问题比较多,第一是原来根本无法显示颜色选择框。仔细分析代码后,发现Justreader的颜色选择框是使用了自定义的继承了QComboBox的ColorComboBox类。打开ColorComboBox.cpp文件,可以发现这样一段代码:
C代码:
经过分析,发现是因为QT无法获得默认字体的大小,导致变量x为0,而在下面的程序段,绘制ColorComboBox有时要依靠x来计算大小的(乘法),这就导致了无法画出正常大小的ColorComboBox。
由于Zaurus设备的分辨率是固定的,我们大可在这里设定固定的x的值,我把它设置成了默认字体的大小16。把代码改成这样,颜色选择框就能正常显示了
C代码:
修改完了不显示颜色选择框的问题,但是发现,即使我们选择了新的颜色,确定后也不会生效。同样,我们设置了新的控制键也不会生效。这两个问题很是怪。开始的时候,我怀疑是保存设定的函数的问题,但后来发现,在SettingsDlg.cpp中的保存设定的函数有保存这些信息的部分。后来想到,为什么通用设之中的信息可以保存,而这两个使用自定义的继承于QComboBox控件的设定的信息就不能保存了呢?问题一定出在这两个控件的代码中。
还是以颜色设定为例,打开ColorComboBox.cpp,看这段代码:
C代码:
看到 connect(this,SIGNAL(activated(int)),this,SLOT(setColor(int))); 这一句了吗?这一句是说明,注册一个事件:当我们选择一个新的颜色时,调用setColor()方法,把我们选择的新的颜色赋予public的属性color。而在保存设置信息时,原来的代码是通过color这个属性来得到新的颜色值的。
经过我的测试,问题就出在这里。不知道为什么,可能是QT的兼容原因,这个事件并未如愿的在系统中注册成功,或者是在实际操作时,即使我们选择了新的颜色,也未能触发这个事件。因此color属性无法得到最新的颜色值,当我们确定保存设置时,通过color属性得到的还是旧的颜色值。
看来使用connect注册事件的方法是行不通了。如果我们不使用connect要如何做work around呢?ColorComboBox是继承于QComboBox的,QCombox有currentItem()这样一个方法可以得到目前的ComboBox中被选中项目的索引。我们可以在保存属性时利用这个方法,得到索引值,然后再通过索引值,查询ColorComboBox中的颜色数组,得到颜色值。
很方便的,我们在ColorComboBox中新增这样的一个方法:
C代码:
输入索引值,返回QColor类型的颜色值。别忘了,新增方法要到头文件ColorCOmboBox.h中去注册哦。
然后,我们修改SettingsDlg.cpp保存设定的那一段,让它通过我们的这个新方法来取的颜色值。
打开SettingsDlg.cpp,找到SettingsDlg::acceptChanges()方法,这就是保存设定的地方,我以背景色为例来说明如何修改。
找到保存背景色的代码,原来是这样的:
C代码:
可以看到原来是通过color属性来获得颜色值的,color属性本应该在每次修改颜色时触发事件,通过ColorComboBox的setColor()方法被修改,但是上面我们说到,不知什么原因,事件并未触发,所以color就一直是原来的颜色值,所以就会表现为修改的内容并未生效。
我们这样改写代码,通过当前的索引值(这是由QComboBox继承而来的方法,经测试有效)从我们新增的getColor()方法获取颜色值。
C代码:
保存其他的颜色设定的代码也同样做类似的修改。
修改完成后,颜色设定不能保存的问题就得到了解决。
键盘控制的问题也是类似,同样是因为connect注册事件实效导致。也作类似的修改就可以解决了,在此就不再赘述。
新增了在进度条显示翻页时的时间的功能
ccpaging是个爱书之人(电子书),否则怎么会提出这样的需求呢,呵呵。这个东西应该也不是很难,在Frame.cpp中找到了绘制ProgressBar的代码。
找到Frame::printPage()方法,在里面有这样一段代码:
C代码:
这就是判断如果打开了显示进度条的开关,则绘制两种形式的进度条(页数或百分比)。我们在其中插入获得时间和显示时间的代码。把这段代码修改成这样:
C代码:
修改成这样后,记得还要修改头文件Frame.h哦,因为这里我们用到了一个QString类型的变量timeStr,别忘了在头文件里注册一下:)。
全部修改完成后,重新编译,就得到了这个修正版的Justreader 2.0k-fiX啦!
我编译后已经打包了,大家如果需要的话可以在这里下载,直接用软件包安装器或者使用ipkg install 安装就可以使用了:),有什么问题也可以反馈给我哦。
幸好Justreader是一个开源软件,我下载了它的源代码,仔细研究,折腾了三天,终于被我修正了这些Bug,并重新编译打包,做了个改进版出来给大家使用。在这个新的版本里(我称之为Justreader 2.0k-fiX版,大写的X表示是针对X环境下使用的改进),还应ccpaging的要求,增加了在进度栏显示翻页时时间的小功能。因为这个家伙,经常全屏看书太投入,结果忘了时间,哈哈。
看看这个fiX版的 改变吧:
- 修正了无法打开中文文件名的PDB文件的Bug(这个是在网上看来的前人的修正方法,不过那家伙没有编译,我顺便把它改了)
- 修正了无法设置/保存颜色设定的Bug
- 修正了无法设置/保存键盘控制设定的Bug
- 新增了在进度条显示翻页时的时间的功能
修正了无法打开中文文件名的PDB文件的Bug
打开StreamPalm*.cpp文件,一共有五个,找到它们的 openFile() 方法,在里面都可以看到有这样一行代码:
C代码:
- strncpy(plucker_file, (filepath+"\0").latin1(), (filepath+"\0").length() + 1);
在这里latin1会丢弃UTF-8的中文字符,所以导致了无法打开中文文件名的PDB文件。把这些文件里的openFile方法里的这一句都改成
C代码:
- qstrcpy(plucker_file, QTextCodec::codecForName( "UTF-8" )->fromUnicode(filepath));
这样就能解决问题啦。
修正了无法设置/保存颜色设定和键盘控制的Bug
颜色设定的问题比较多,第一是原来根本无法显示颜色选择框。仔细分析代码后,发现Justreader的颜色选择框是使用了自定义的继承了QComboBox的ColorComboBox类。打开ColorComboBox.cpp文件,可以发现这样一段代码:
C代码:
- QFont defaultFont = QApplication::font();
- int x = defaultFont.pixelSize();
- setMaximumWidth(x * 8);
- //setFixedSize(64,24);
经过分析,发现是因为QT无法获得默认字体的大小,导致变量x为0,而在下面的程序段,绘制ColorComboBox有时要依靠x来计算大小的(乘法),这就导致了无法画出正常大小的ColorComboBox。
由于Zaurus设备的分辨率是固定的,我们大可在这里设定固定的x的值,我把它设置成了默认字体的大小16。把代码改成这样,颜色选择框就能正常显示了
C代码:
- QFont defaultFont = QApplication::font();
- //int x = defaultFont.pixelSize();
- int x = 16;
- setMaximumWidth(x * 8);
- //setFixedSize(64,24);
修改完了不显示颜色选择框的问题,但是发现,即使我们选择了新的颜色,确定后也不会生效。同样,我们设置了新的控制键也不会生效。这两个问题很是怪。开始的时候,我怀疑是保存设定的函数的问题,但后来发现,在SettingsDlg.cpp中的保存设定的函数有保存这些信息的部分。后来想到,为什么通用设之中的信息可以保存,而这两个使用自定义的继承于QComboBox控件的设定的信息就不能保存了呢?问题一定出在这两个控件的代码中。
还是以颜色设定为例,打开ColorComboBox.cpp,看这段代码:
C代码:
- ColorComboBox::ColorComboBox(QWidget *parent, const char *name)
- : QComboBox(parent, name)
- {
- maxColors = sizeof(colorArray) / sizeof(colorArray[0]);
- colorArray[0] = Qt::black;
- colorArray[1] = Qt::white;
- colorArray[2] = Qt::darkGray;
- colorArray[3] = Qt::gray;
- colorArray[4] = Qt::lightGray;
- colorArray[5] = Qt::red;
- colorArray[6] = Qt::green;
- colorArray[7] = Qt::blue;
- colorArray[8] = Qt::cyan;
- colorArray[9] = Qt::magenta;
- colorArray[10] = Qt::yellow;
- colorArray[11] = Qt::darkRed;
- colorArray[12] = Qt::darkGreen;
- colorArray[13] = Qt::darkBlue;
- colorArray[14] = Qt::darkCyan;
- colorArray[15] = Qt::darkMagenta;
- colorArray[16] = Qt::darkYellow;
- QFont defaultFont = QApplication::font();
- //int x = defaultFont.pixelSize();
- int x = 16;
- setMaximumWidth(x * 8);
- //setFixedSize(64,24);
- for (int i = 0;i<maxColors;i++)
- {
- QPixmap p(x * 8, x, -1);
- p.fill(colorArray[i]);
- insertItem(p,i);
- }
- connect(this, SIGNAL(activated(int)), this, SLOT(setColor(int)));
- }
- void ColorComboBox::setColor(int i)
- {
- color = colorArray[i];
- }
看到 connect(this,SIGNAL(activated(int)),this,SLOT(setColor(int))); 这一句了吗?这一句是说明,注册一个事件:当我们选择一个新的颜色时,调用setColor()方法,把我们选择的新的颜色赋予public的属性color。而在保存设置信息时,原来的代码是通过color这个属性来得到新的颜色值的。
经过我的测试,问题就出在这里。不知道为什么,可能是QT的兼容原因,这个事件并未如愿的在系统中注册成功,或者是在实际操作时,即使我们选择了新的颜色,也未能触发这个事件。因此color属性无法得到最新的颜色值,当我们确定保存设置时,通过color属性得到的还是旧的颜色值。
看来使用connect注册事件的方法是行不通了。如果我们不使用connect要如何做work around呢?ColorComboBox是继承于QComboBox的,QCombox有currentItem()这样一个方法可以得到目前的ComboBox中被选中项目的索引。我们可以在保存属性时利用这个方法,得到索引值,然后再通过索引值,查询ColorComboBox中的颜色数组,得到颜色值。
很方便的,我们在ColorComboBox中新增这样的一个方法:
C代码:
- QColor ColorComboBox::getColor(int i)
- {
- return colorArray[i];
- }
输入索引值,返回QColor类型的颜色值。别忘了,新增方法要到头文件ColorCOmboBox.h中去注册哦。
然后,我们修改SettingsDlg.cpp保存设定的那一段,让它通过我们的这个新方法来取的颜色值。
打开SettingsDlg.cpp,找到SettingsDlg::acceptChanges()方法,这就是保存设定的地方,我以背景色为例来说明如何修改。
找到保存背景色的代码,原来是这样的:
C代码:
- config.colors.bgColor = bgColorComboBox->color;
可以看到原来是通过color属性来获得颜色值的,color属性本应该在每次修改颜色时触发事件,通过ColorComboBox的setColor()方法被修改,但是上面我们说到,不知什么原因,事件并未触发,所以color就一直是原来的颜色值,所以就会表现为修改的内容并未生效。
我们这样改写代码,通过当前的索引值(这是由QComboBox继承而来的方法,经测试有效)从我们新增的getColor()方法获取颜色值。
C代码:
- //config.colors.bgColor = bgColorComboBox->color;
- config.colors.bgColor = bgColorComboBox->getColor(bgColorComboBox->currentItem());
保存其他的颜色设定的代码也同样做类似的修改。
修改完成后,颜色设定不能保存的问题就得到了解决。
键盘控制的问题也是类似,同样是因为connect注册事件实效导致。也作类似的修改就可以解决了,在此就不再赘述。
新增了在进度条显示翻页时的时间的功能
ccpaging是个爱书之人(电子书),否则怎么会提出这样的需求呢,呵呵。这个东西应该也不是很难,在Frame.cpp中找到了绘制ProgressBar的代码。
找到Frame::printPage()方法,在里面有这样一段代码:
C代码:
- if (progressBarVisible)
- {
- painter->setPen(progressBarTextColor);
- painter->setFont(QFont("helvetica", progressBarHeight, QFont::Bold, FALSE));
- painter->fillRect(0,height - progressBarHeight, width*progressBarPercent / 100, progressBarHeight, progressBarFgColor);
- painter->fillRect(width * progressBarPercent / 100, height -progressBarHeight, width - width * progressBarPercent / 100,progressBarHeight, progressBarBgColor);
- if (progressBarPercentShow)
- {
- painter->drawText(width/2 - 10,height - 1,QString().setNum(progressBarPercent) + "%");
- } else {
- painter->drawText(width/2 - 10,height - 1,QString().setNum(progressBarPage) + " ( "+QString().setNum(progressBarPages)+" )");
- }
- }
这就是判断如果打开了显示进度条的开关,则绘制两种形式的进度条(页数或百分比)。我们在其中插入获得时间和显示时间的代码。把这段代码修改成这样:
C代码:
- if (progressBarVisible)
- {
- //利用tm struct获得系统的时间,精确到秒,并格式化成字符串
- time_t now;
- struct tm *timenow;
- time(&now);
- timenow = localtime(&now);
- timeStr = QString().setNum(1900 + timenow->tm_year) + "-" + QString().setNum(1 + timenow->tm_mon).rightJustify(2,'0') + "-" + QString().setNum(timenow->tm_mday).rightJustify(2,'0') + " " + QString().setNum(timenow->tm_hour).rightJustify(2,'0') + ":" + QString().setNum(timenow->tm_min).rightJustify(2,'0') + ":" + QString().setNum(timenow->tm_sec).rightJustify(2,'0');
- ////
- painter->setPen(progressBarTextColor);
- painter->setFont(QFont("helvetica", progressBarHeight, QFont::Bold, FALSE));
- painter->fillRect(0,height - progressBarHeight, width*progressBarPercent / 100, progressBarHeight, progressBarFgColor);
- painter->fillRect(width * progressBarPercent / 100, height - progressBarHeight, width - width * progressBarPercent / 100, progressBarHeight, progressBarBgColor);
- if (progressBarPercentShow)
- {
- //显示的进度值位置前移20pixel
- //painter->drawText(width/2 - 10,height - 1,QString().setNum(progressBarPercent) + "%");
- painter->drawText(width/2 - 30,height - 1,QString().setNum(progressBarPercent) + "%");
- ////
- } else {
- //显示的进度值位置前移20pixel
- //painter->drawText(width/2 - 10,height - 1,QString().setNum(progressBarPage) + " ( " + QString().setNum(progressBarPages) + " )");
- painter->drawText(width/2 - 30,height - 1,QString().setNum(progressBarPage) + " ( " + QString().setNum(progressBarPages) + " )");
- ////
- }
- //在右侧显示时间
- painter->drawText(width-140,height - 1, timeStr);
- ////
- }
修改成这样后,记得还要修改头文件Frame.h哦,因为这里我们用到了一个QString类型的变量timeStr,别忘了在头文件里注册一下:)。
全部修改完成后,重新编译,就得到了这个修正版的Justreader 2.0k-fiX啦!
我编译后已经打包了,大家如果需要的话可以在这里下载,直接用软件包安装器或者使用ipkg install 安装就可以使用了:),有什么问题也可以反馈给我哦。
日历
| 年 月 | ||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
| 29 | 30 | 31 | 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 | 1 | 2 |
日志分类
搜索日志
订阅我的日志
友情链接
[做人要厚道,看帖要回帖,点击发表评论]
显示评论
隐藏评论
评论列表
发布于 2007-03-08 22:47:22 |



