ChineseConversion: conditional compilation and OpenCC exception handling

This commit is contained in:
Zhe Wang 2015-10-25 21:54:38 +08:00
parent e905f3e318
commit a1986254d2
12 changed files with 219 additions and 85 deletions

View file

@ -35,11 +35,21 @@ And then invoke `qmake-qt4` and `make`:
In case when qmake-qt4 does not exist, try using `qmake` but make sure it is indeed from the Qt 4 installation.
Alternatively, you might want to load `goldendict.pro` file from within Qt Creator, especially on Windows.
### Building with Chinese conversion support
To add Chinese conversion support you need at first install libopencc-dev package:
sudo apt-get install libopencc-dev
Then pass `"CONFIG+=chinese_conversion_support"` to `qmake`
qmake "CONFIG+=chinese_conversion_support"
### Building with Zim dictionaries support
To add Zim and Slob formats support you need at first install lzma-dev package:
sudo apt-get liblzma-dev
sudo apt-get install liblzma-dev
Then pass `"CONFIG+=zim_support"` to `qmake`

View file

@ -2,10 +2,12 @@
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "chinese.hh"
#include <stdexcept>
#include <QCoreApplication>
#include <opencc/Export.hpp>
#include <opencc/SimpleConverter.hpp>
#include "folding.hh"
#include "gddebug.hh"
#include "transliteration.hh"
#include "utf8.hh"
@ -13,12 +15,13 @@ namespace Chinese {
class CharacterConversionDictionary: public Transliteration::BaseTransliterationDictionary
{
opencc::SimpleConverter converter;
opencc::SimpleConverter* converter;
public:
CharacterConversionDictionary( std::string const & id, std::string const & name,
QIcon icon, std::string const & openccConfig);
~CharacterConversionDictionary();
std::vector< gd::wstring > getAlternateWritings( gd::wstring const & )
throw();
@ -29,8 +32,20 @@ CharacterConversionDictionary::CharacterConversionDictionary( std::string const
QIcon icon_,
std::string const & openccConfig):
Transliteration::BaseTransliterationDictionary( id, name_, icon_, false ),
converter(openccConfig)
converter( NULL )
{
try {
converter = new opencc::SimpleConverter( openccConfig );
} catch ( std::runtime_error& e ) {
gdWarning( "CharacterConversionDictionary: failed to initialize OpenCC from config %s: %s\n",
openccConfig.c_str(), e.what() );
}
}
CharacterConversionDictionary::~CharacterConversionDictionary()
{
if ( converter != NULL )
delete converter;
}
std::vector< gd::wstring > CharacterConversionDictionary::getAlternateWritings( gd::wstring const & str )
@ -38,11 +53,22 @@ std::vector< gd::wstring > CharacterConversionDictionary::getAlternateWritings(
{
std::vector< gd::wstring > results;
gd::wstring folded = Folding::applySimpleCaseOnly( str );
gd::wstring result = Utf8::decode( converter.Convert( Utf8::encode( folded ) ) );
if ( converter != NULL ) {
gd::wstring folded = Folding::applySimpleCaseOnly( str );
std::string input = Utf8::encode( folded );
std::string output;
gd::wstring result;
if ( result != folded )
results.push_back( result );
try {
output = converter->Convert( input );
result = Utf8::decode( output );
} catch ( std::exception& ex ) {
gdWarning( "OpenCC: convertion failed %s\n", ex.what() );
}
if ( !result.empty() && result != folded )
results.push_back( result );
}
return results;
}

30
chineseconversion.cc Normal file
View file

@ -0,0 +1,30 @@
/* This file is (c) 2015 Zhe Wang <0x1997@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "chineseconversion.hh"
#include "ui_chineseconversion.h"
ChineseConversion::ChineseConversion(QWidget * parent, Config::Chinese const & cfg) :
QGroupBox(parent),
ui(new Ui::ChineseConversion)
{
ui->setupUi( this );
setChecked( cfg.enable );
ui->enableSCToTWConversion->setChecked( cfg.enableSCToTWConversion );
ui->enableSCToHKConversion->setChecked( cfg.enableSCToHKConversion );
ui->enableTCToSCConversion->setChecked( cfg.enableTCToSCConversion );
}
ChineseConversion::~ChineseConversion()
{
delete ui;
}
void ChineseConversion::getConfig( Config::Chinese & cfg ) const
{
cfg.enable = isChecked();
cfg.enableSCToTWConversion = ui->enableSCToTWConversion->isChecked();
cfg.enableSCToHKConversion = ui->enableSCToHKConversion->isChecked();
cfg.enableTCToSCConversion = ui->enableTCToSCConversion->isChecked();
}

28
chineseconversion.hh Normal file
View file

@ -0,0 +1,28 @@
/* This file is (c) 2015 Zhe Wang <0x1997@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef __CHINESE_CONVERSION_HH_INCLUDED__
#define __CHINESE_CONVERSION_HH_INCLUDED__
#include <QGroupBox>
#include "config.hh"
namespace Ui {
class ChineseConversion;
}
class ChineseConversion : public QGroupBox
{
Q_OBJECT
public:
ChineseConversion( QWidget * parent, Config::Chinese const & );
~ChineseConversion();
void getConfig( Config::Chinese & ) const;
private:
Ui::ChineseConversion *ui;
};
#endif // __CHINESE_CONVERSION_HH_INCLUDED__

66
chineseconversion.ui Normal file
View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChineseConversion</class>
<widget class="QGroupBox" name="ChineseConversion">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>689</width>
<height>128</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>GroupBox</string>
</property>
<property name="toolTip">
<string>Enable conversion between simplified and traditional Chinese characters</string>
</property>
<property name="title">
<string>Chinese Con&amp;version</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="enableSCToTWConversion">
<property name="toolTip">
<string>Enable conversion from simplified characters to traditional (Taiwan variant) characters</string>
</property>
<property name="text">
<string>SC to TC (Taiwan variant)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="enableSCToHKConversion">
<property name="toolTip">
<string>Enable conversion from simplified characters to traditional (Hong Kong variant) characters</string>
</property>
<property name="text">
<string>SC to TC (Hong Kong variant)</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="enableTCToSCConversion">
<property name="toolTip">
<string>Enable conversion from traditional characters to simplified characters</string>
</property>
<property name="text">
<string>TC to SC</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -137,6 +137,7 @@ Preferences::Preferences():
{
}
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
Chinese::Chinese():
enable( false ),
enableSCToTWConversion( true ),
@ -144,6 +145,7 @@ Chinese::Chinese():
enableTCToSCConversion( true )
{
}
#endif
Romaji::Romaji():
enable( false ),
@ -523,6 +525,7 @@ Class load() throw( exError )
applyBoolOption( c.transliteration.enableBelarusianTransliteration,
transliteration.namedItem( "enableBelarusianTransliteration" ) );
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
QDomNode chinese = transliteration.namedItem( "chinese" );
if ( !chinese.isNull() )
@ -532,6 +535,7 @@ Class load() throw( exError )
applyBoolOption( c.transliteration.chinese.enableSCToHKConversion, chinese.namedItem( "enableSCToHKConversion" ) );
applyBoolOption( c.transliteration.chinese.enableTCToSCConversion, chinese.namedItem( "enableTCToSCConversion" ) );
}
#endif
QDomNode romaji = transliteration.namedItem( "romaji" );
@ -1217,6 +1221,7 @@ void save( Class const & c ) throw( exError )
opt.appendChild( dd.createTextNode( c.transliteration.enableBelarusianTransliteration ? "1":"0" ) );
transliteration.appendChild( opt );
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
// Chinese
QDomElement chinese = dd.createElement( "chinese" );
@ -1237,6 +1242,7 @@ void save( Class const & c ) throw( exError )
opt = dd.createElement( "enableTCToSCConversion" );
opt.appendChild( dd.createTextNode( c.transliteration.chinese.enableTCToSCConversion ? "1":"0" ) );
chinese.appendChild( opt );
#endif
// Romaji

View file

@ -339,6 +339,7 @@ struct Hunspell
/// All the MediaWikis
typedef QVector< MediaWiki > MediaWikis;
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
/// Chinese transliteration configuration
struct Chinese
{
@ -360,6 +361,7 @@ struct Chinese
{ return ! operator == ( other ); }
};
#endif
/// Romaji transliteration configuration
struct Romaji
@ -393,7 +395,9 @@ struct Transliteration
bool enableGermanTransliteration;
bool enableGreekTransliteration;
bool enableBelarusianTransliteration;
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
Chinese chinese;
#endif
Romaji romaji;
bool operator == ( Transliteration const & other ) const
@ -401,7 +405,10 @@ struct Transliteration
enableGermanTransliteration == other.enableGermanTransliteration &&
enableGreekTransliteration == other.enableGreekTransliteration &&
enableBelarusianTransliteration == other.enableBelarusianTransliteration &&
chinese == other.chinese && romaji == other.romaji;
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chinese == other.chinese &&
#endif
romaji == other.romaji;
}
bool operator != ( Transliteration const & other ) const

View file

@ -473,13 +473,13 @@ CONFIG( no_epwing_support ) {
LIBS += -leb
}
CONFIG( no_chinese_conversion_support ) {
DEFINES += NO_CHINESE_CONVERSION_SUPPORT
}
!CONFIG( no_chinese_conversion_support ) {
HEADERS += chinese.hh
SOURCES += chinese.cc
CONFIG( chinese_conversion_support ) {
DEFINES += MAKE_CHINESE_CONVERSION_SUPPORT
FORMS += chineseconversion.ui
HEADERS += chinese.hh \
chineseconversion.hh
SOURCES += chinese.cc \
chineseconversion.cc
LIBS += -lopencc
}

View file

@ -35,7 +35,7 @@
#include "epwing.hh"
#endif
#ifndef NO_CHINESE_CONVERSION_SUPPORT
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
#include "chinese.hh"
#endif
@ -277,6 +277,7 @@ void loadDictionaries( QWidget * parent, bool showInitially,
///// We create transliterations syncronously since they are very simple
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
// Make Chinese conversion
{
vector< sptr< Dictionary::Class > > chineseDictionaries =
@ -285,6 +286,7 @@ void loadDictionaries( QWidget * parent, bool showInitially,
dictionaries.insert( dictionaries.end(), chineseDictionaries.begin(),
chineseDictionaries.end() );
}
#endif
// Make Romaji
{

View file

@ -7,9 +7,16 @@
#include <QStandardItemModel>
#include "gddebug.hh"
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
#include "chineseconversion.hh"
#endif
Sources::Sources( QWidget * parent, Config::Class const & cfg):
QWidget( parent ),
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chineseConversion( new ChineseConversion( this, cfg.transliteration.chinese ) ),
#endif
#if defined( Q_OS_WIN32 ) || defined( Q_OS_MAC )
textToSpeechSource( NULL ),
#endif
@ -93,10 +100,12 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg):
ui.enableGermanTransliteration->setChecked( trs.enableGermanTransliteration );
ui.enableGreekTransliteration->setChecked( trs.enableGreekTransliteration );
ui.enableBelarusianTransliteration->setChecked( trs.enableBelarusianTransliteration );
ui.enableChineseConversion->setChecked( trs.chinese.enable );
ui.enableSCToTWConversion->setChecked( trs.chinese.enableSCToTWConversion );
ui.enableSCToHKConversion->setChecked( trs.chinese.enableSCToHKConversion );
ui.enableTCToSCConversion->setChecked( trs.chinese.enableTCToSCConversion );
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
ui.transliterationLayout->addWidget(chineseConversion);
ui.transliterationLayout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
#endif
ui.enableRomaji->setChecked( trs.romaji.enable );
ui.enableHepburn->setChecked( trs.romaji.enableHepburn );
ui.enableNihonShiki->setChecked( trs.romaji.enableNihonShiki );
@ -353,10 +362,9 @@ Config::Transliteration Sources::getTransliteration() const
tr.enableGermanTransliteration = ui.enableGermanTransliteration->isChecked();
tr.enableGreekTransliteration = ui.enableGreekTransliteration->isChecked();
tr.enableBelarusianTransliteration = ui.enableBelarusianTransliteration->isChecked();
tr.chinese.enable = ui.enableChineseConversion->isChecked();
tr.chinese.enableSCToTWConversion = ui.enableSCToTWConversion->isChecked();
tr.chinese.enableSCToHKConversion = ui.enableSCToHKConversion->isChecked();
tr.chinese.enableTCToSCConversion = ui.enableTCToSCConversion->isChecked();
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chineseConversion->getConfig( tr.chinese );
#endif
tr.romaji.enable = ui.enableRomaji->isChecked();
tr.romaji.enableHepburn = ui.enableHepburn->isChecked();
tr.romaji.enableNihonShiki = ui.enableNihonShiki->isChecked();

View file

@ -16,6 +16,11 @@
#include "texttospeechsource.hh"
#endif
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
// Forward declaration
class ChineseConversion;
#endif
/// A model to be projected into the mediawikis view, according to Qt's MVC model
class MediaWikisModel: public QAbstractItemModel
{
@ -284,6 +289,10 @@ signals:
private:
Ui::Sources ui;
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
ChineseConversion *chineseConversion;
#endif
#if defined( Q_OS_WIN32 ) || defined( Q_OS_MAC )
TextToSpeechSource *textToSpeechSource;
#endif

View file

@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>8</number>
<number>0</number>
</property>
<property name="iconSize">
<size>
@ -633,7 +633,7 @@ in the future, or register on the site to get your own key.</string>
<attribute name="title">
<string>Transliteration</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<layout class="QVBoxLayout" name="transliterationLayout">
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
@ -721,64 +721,6 @@ in the future, or register on the site to get your own key.</string>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="enableChineseConversion">
<property name="toolTip">
<string>Enable conversion between simplified and traditional Chinese characters</string>
</property>
<property name="title">
<string>Chinese Conversion</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="3">
<widget class="QCheckBox" name="enableTCToSCConversion">
<property name="toolTip">
<string>Enable conversion from traditional characters to simplified characters</string>
</property>
<property name="text">
<string>TC to SC</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="enableSCToHKConversion">
<property name="toolTip">
<string>Enable conversion from simplified characters to traditional (Hong Kong variant) characters</string>
</property>
<property name="text">
<string>SC to TC (Hong Kong variant)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="enableSCToTWConversion">
<property name="toolTip">
<string>Enable conversion from simplified characters to traditional (Taiwan variant) characters</string>
</property>
<property name="text">
<string>SC to TC (Taiwan variant)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_13">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="enableRomaji">
<property name="toolTip">
@ -882,7 +824,7 @@ Not implemented yet in GoldenDict.</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>80</height>
<height>40</height>
</size>
</property>
</spacer>