feat: add custom transliteration support

fix #661

i18n: add new translation entries
This commit is contained in:
YiFang Xiao 2023-05-13 19:56:09 +08:00 committed by xiaoyifang
parent 126e76ee62
commit c40d04ec5e
13 changed files with 308 additions and 49 deletions

View file

@ -321,6 +321,7 @@ HEADERS += \
src/dict/belarusiantranslit.hh \
src/dict/bgl.hh \
src/dict/bgl_babylon.hh \
src/dict/customtransliteration.hh \
src/dict/dictdfiles.hh \
src/dict/dictionary.hh \
src/dict/dictserver.hh \
@ -444,6 +445,7 @@ SOURCES += \
src/dict/belarusiantranslit.cc \
src/dict/bgl.cc \
src/dict/bgl_babylon.cc \
src/dict/customtransliteration.cpp \
src/dict/dictdfiles.cc \
src/dict/dictionary.cc \
src/dict/dictserver.cc \

78
icons/custom_trans.svg Normal file
View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="80mm"
height="80mm"
viewBox="0 0 80 80"
version="1.1"
id="svg3719"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="custom_trans.svg">
<defs
id="defs3713" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="120.57064"
inkscape:cy="-41.67205"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:snap-path-clip="true" />
<metadata
id="metadata3716">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-217)">
<path
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.39687496"
d="m 33.70856,224.20637 c -5.316199,-0.0564 -9.836205,4.52791 -10.189956,9.74338 -0.790812,4.8717 1.075112,10.70081 5.993313,12.62811 4.489041,1.88877 9.618135,1.01907 13.920081,-0.96583 -0.422346,-1.62315 1.167861,-6.01379 -1.498357,-4.94621 -3.480777,2.60283 -9.595874,3.72659 -12.445751,-0.41626 -1.530238,-2.15954 -1.096251,-4.08545 1.850276,-3.13779 4.167703,0 8.335407,0 12.50311,0 0.337287,-4.24134 -0.310857,-9.56519 -4.498174,-11.76672 -1.710531,-0.93822 -3.70736,-1.21241 -5.634542,-1.13868 z m -24.3481224,0.0683 c -2.3988668,0.0528 -4.7689465,0.5208 -7.0856125,1.11853 0.39741,1.64187 -1.1721015,5.91969 1.627803,4.77786 3.1464127,-1.00182 7.2072579,-2.2305 10.1063599,-0.0936 1.338747,1.53162 0.0152,2.21619 -1.615402,1.93322 -4.1869858,0.249 -9.8111574,0.89449 -11.52332637,5.44618 -1.55876091,4.07145 0.80840847,9.21939 5.24076577,10.06062 2.9219202,0.57861 6.0758826,-0.1248 8.4979266,-1.85415 -0.869688,2.40387 4.945562,1.86705 5.06636,0.68213 -0.219762,-5.50665 0.416142,-11.08346 -0.264327,-16.5548 -0.969959,-4.58943 -6.026799,-5.71042 -10.0505474,-5.51595 z m 25.0395554,4.39585 c 2.379309,-0.1827 4.409332,1.82295 4.409031,4.17494 -3.286169,-0.12555 -7.199928,0.24811 -10.104033,-0.18138 0.583402,-2.58227 3.092181,-4.24364 5.695002,-3.99356 z m -19.791041,12.16205 c -2.269782,1.78024 -6.1401881,3.15397 -8.5242816,0.96273 -1.4515078,-2.1855 0.5152927,-4.87712 2.9812122,-4.92528 1.8275114,-0.3654 3.7127424,-0.43008 5.5430694,-0.58214 0,1.5149 0,3.02979 0,4.54469 z"
id="flowRoot3737"
inkscape:connector-curvature="0" />
<path
style="opacity:0.16000001;fill:none;stroke:#000000;stroke-width:0.08470525;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 17.968378,288.74079 c 5.582397,5.63147 7.214394,-6.69887 10.911473,-9.63963 10.2118,-15.97494 20.423601,-31.94988 30.635401,-47.92482 -5.582397,-5.63147 -7.214394,6.69886 -10.911473,9.63962 -10.2118,15.97494 -20.423601,31.94989 -30.635401,47.92483 z"
id="path3747"
inkscape:connector-curvature="0" />
<path
style="opacity:0.35100002;fill:#008000;stroke-width:0.08039484"
d="m 73.535794,234.68528 c -20.160369,20.16037 -40.320738,40.32074 -60.481107,60.48111 -2.315868,-4.32228 -13.14241197,-8.64456 -8.724202,-12.96684 19.924665,-19.92467 39.849333,-39.84934 59.774,-59.774 2.208014,3.85268 11.970496,8.52965 9.431309,12.25973 z"
id="rect4560"
inkscape:connector-curvature="0" />
<path
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.39687496"
d="m 62.133934,264.44911 c -2.648141,-0.0924 -5.223681,1.43511 -7.065462,2.92384 -3.752192,-3.96202 -9.917165,-3.08929 -14.692305,-1.92616 -1.280394,0.41338 -1.422758,5.41435 0.254424,5.16241 3.266727,-1.1128 7.345458,-2.48199 10.528816,-0.42478 0.969908,1.02901 1.115318,3.08476 -0.751117,2.55487 -4.21569,0.2399 -9.841512,0.31268 -12.006243,4.68576 -1.851998,3.95019 0.310816,9.2426 4.709013,10.22651 3.99796,1.04614 8.36116,-0.69852 11.2435,-3.1967 4.242971,4.55231 11.466513,4.01462 16.692782,1.60377 0.689526,-1.00141 1.222422,-5.43712 -0.539501,-5.33532 -3.392392,2.2694 -8.659129,3.9536 -12.129492,0.78599 -1.127275,-1.21581 -1.579693,-2.89656 -1.656489,-4.5191 5.070749,0 10.141497,0 15.212247,0 0.35156,-4.24654 -0.465075,-9.5427 -4.786527,-11.54038 -1.54605,-0.77187 -3.298924,-1.03874 -5.013646,-1.00071 z m 0.456561,4.47337 c 2.227552,-0.15883 4.08147,1.64951 4.271058,3.80132 -3.299028,0 -6.598047,0 -9.897071,0 0.622586,-2.49269 3.120128,-4.02705 5.626013,-3.80132 z m -10.85748,8.34987 c 0.05806,1.20044 0.240061,2.39939 0.608493,3.54552 -2.307495,1.95899 -6.307106,3.41412 -8.917286,1.2914 -1.346148,-1.94676 0.245948,-4.56116 2.573484,-4.59662 1.808274,-0.30441 4.282874,-0.68409 5.735309,-0.2403 z"
id="flowRoot5099"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

@ -5264,6 +5264,21 @@ based on English phonology</source>
<source>Hiragana Japanese syllabary</source>
<translation></translation>
</message>
<message>
<location filename="../src/ui/sources.ui" line="835"/>
<source>Custom transliteration</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/sources.ui" line="844"/>
<source>This only applied in search phrase, with each line represent a transliteration,semicolon seperated. For example, ae;æ,users can input ae to represent æ in the target word.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/sources.ui" line="854"/>
<source>ae;æ #this is an example</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/sources.ui" line="681"/>
<source>Transliteration</source>

View file

@ -88,5 +88,6 @@
<file>icons/mdict-bg.png</file>
<file>icons/old-arrow.png</file>
<file>icons/old-downarrow.png</file>
<file>icons/custom_trans.svg</file>
</qresource>
</RCC>

View file

@ -3,20 +3,19 @@
#include "config.hh"
#include "folding.hh"
#include "wstring_qt.hh"
#include <QDir>
#include <QFile>
#include <QtXml>
#include "gddebug.hh"
#include <stdint.h>
#ifdef Q_OS_WIN32
#include "shlobj.h"
//this is a windows header file.
#include <Shlobj.h>
#endif
#include <stdint.h>
#include "atomic_rename.hh"
#include "utils.hh"
#include <QStandardPaths>
@ -699,6 +698,14 @@ Class load()
applyBoolOption( c.transliteration.romaji.enableHiragana, romaji.namedItem( "enableHiragana" ) );
applyBoolOption( c.transliteration.romaji.enableKatakana, romaji.namedItem( "enableKatakana" ) );
}
QDomNode customtrans = transliteration.namedItem( "customtrans" );
if ( !customtrans.isNull() )
{
applyBoolOption( c.transliteration.customTrans.enable, customtrans.namedItem( "enable" ) );
c.transliteration.customTrans.context = customtrans.namedItem( "context" ).toElement().text() ;
}
}
QDomNode lingua = root.namedItem("lingua");
@ -1478,6 +1485,18 @@ void save( Class const & c )
opt = dd.createElement( "enableKatakana" );
opt.appendChild( dd.createTextNode( c.transliteration.romaji.enableKatakana ? "1":"0" ) );
romaji.appendChild( opt );
//custom transliteration
QDomElement customtrans = dd.createElement( "customtrans" );
transliteration.appendChild( customtrans );
opt = dd.createElement( "enable" );
opt.appendChild( dd.createTextNode( c.transliteration.customTrans.enable ? "1":"0" ) );
customtrans.appendChild( opt );
opt = dd.createElement( "context" );
opt.appendChild( dd.createTextNode( c.transliteration.customTrans.context ) );
customtrans.appendChild( opt );
}
{

View file

@ -15,10 +15,6 @@
#include "ex.hh"
#include <QLocale>
#ifdef Q_OS_WIN
#include <QRect>
#endif
/// GoldenDict's configuration
namespace Config {
@ -508,6 +504,23 @@ struct Chinese
};
struct CustomTrans
{
bool enable = false;
QString context;
bool operator==( CustomTrans const & other ) const
{
return enable == other.enable && context == other.context;
}
bool operator!=( CustomTrans const & other ) const
{
return !operator==( other );
}
};
/// Romaji transliteration configuration
struct Romaji
{
@ -540,16 +553,20 @@ struct Transliteration
bool enableGermanTransliteration;
bool enableGreekTransliteration;
bool enableBelarusianTransliteration;
CustomTrans customTrans;
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
Chinese chinese;
#endif
Romaji romaji;
bool operator == ( Transliteration const & other ) const
{ return enableRussianTransliteration == other.enableRussianTransliteration &&
enableGermanTransliteration == other.enableGermanTransliteration &&
enableGreekTransliteration == other.enableGreekTransliteration &&
enableBelarusianTransliteration == other.enableBelarusianTransliteration &&
bool operator==( Transliteration const & other ) const
{
return enableRussianTransliteration == other.enableRussianTransliteration
&& enableGermanTransliteration == other.enableGermanTransliteration
&& enableGreekTransliteration == other.enableGreekTransliteration
&& enableBelarusianTransliteration == other.enableBelarusianTransliteration
&& customTrans == other.customTrans &&
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chinese == other.chinese &&
#endif

View file

@ -0,0 +1,58 @@
#include "customtransliteration.hh"
#include "dictionary.hh"
namespace CustomTranslit {
CustomTransTable::CustomTransTable( const QString & content_ )
{
parse( content_ );
}
void CustomTransTable::parse( const QString & content )
{
QTextStream stream( content.toUtf8() );
while ( !stream.atEnd() ) {
auto line = stream.readLine();
auto hashPos = line.indexOf( '#' );
if ( hashPos > -1 ) {
line = line.left( hashPos );
}
auto parts = line.split( ';', Qt::SkipEmptyParts );
if ( parts.size() != 2 ) {
continue;
}
//check part length, normally they should all with length<=2
bool validState = true;
for ( auto & part : parts ) {
if ( part.trimmed().length() > 2 ) {
validState = false;
break;
}
}
if ( !validState ) {
continue;
}
ins(parts[0].toUtf8(),parts[1].toUtf8());
}
}
std::vector< sptr< Dictionary::Class > > makeDictionaries( Config::CustomTrans const & cusTran )
{
std::vector< sptr< Dictionary::Class > > result;
if(cusTran.enable){
static CustomTranslit::CustomTransTable t0(cusTran.context);
result.push_back( std::make_shared<Transliteration::TransliterationDictionary>( "custom-transliteration-dict",
QCoreApplication::translate( "CustomTranslit", "custom transliteration" ).toUtf8().data(),
QIcon( ":/icons/custom_trans.svg" ), t0, false ) );
}
return result;
}
}

View file

@ -0,0 +1,26 @@
#ifndef CUSTOMTRANSLITERATION_HH
#define CUSTOMTRANSLITERATION_HH
#include <vector>
#include "transliteration.hh"
// Support for Belarusian transliteration
namespace CustomTranslit {
class CustomTransTable: public Transliteration::Table
{
public:
CustomTransTable() = default;
explicit CustomTransTable( const QString & content );
private:
void parse( const QString & content );
};
std::vector< sptr< Dictionary::Class > > makeDictionaries( Config::CustomTrans const & );
}
#endif // CUSTOMTRANSLITERATION_HH

View file

@ -12,6 +12,7 @@
#include "dict/hunspell.hh"
#include "dictdfiles.hh"
#include "dict/romaji.hh"
#include "dict/customtransliteration.hh"
#include "dict/russiantranslit.hh"
#include "dict/german.hh"
#include "dict/greektranslit.hh"
@ -212,7 +213,7 @@ void loadDictionaries( QWidget * parent, bool showInitially,
#endif
addDicts(Romaji::makeDictionaries( cfg.transliteration.romaji ));
addDicts(CustomTranslit::makeDictionaries( cfg.transliteration.customTrans));
// Make Russian transliteration
if ( cfg.transliteration.enableRussianTransliteration )

View file

@ -12,9 +12,7 @@ namespace Romaji {
using std::vector;
vector< sptr< Dictionary::Class > > makeDictionaries( Config::Romaji const & )
;
vector< sptr< Dictionary::Class > > makeDictionaries( Config::Romaji const & );
}
#endif

View file

@ -113,6 +113,9 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg):
ui.enableHiragana->setChecked( trs.romaji.enableHiragana );
ui.enableKatakana->setChecked( trs.romaji.enableKatakana );
ui.enableCustomTransliteration->setChecked( trs.customTrans.enable );
ui.customTransliteration->setPlainText( trs.customTrans.context );
ui.linguaEnabled->setChecked(lingua.enable);
ui.linguaLangCode->setText(lingua.languageCodes);
@ -369,6 +372,9 @@ Config::Transliteration Sources::getTransliteration() const
tr.romaji.enableHiragana = ui.enableHiragana->isChecked();
tr.romaji.enableKatakana = ui.enableKatakana->isChecked();
tr.customTrans.enable = ui.enableCustomTransliteration->isChecked();
tr.customTrans.context = ui.customTransliteration->toPlainText();
return tr;
}

View file

@ -1502,19 +1502,6 @@ download page.</string>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -1526,8 +1513,17 @@ download page.</string>
<layout class="QVBoxLayout" name="verticalLayout_21">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Favorites saving interval. If set to 0 Favorites will be saved only during exit.</string>
</property>
@ -1545,6 +1541,12 @@ download page.</string>
</item>
<item>
<widget class="QLabel" name="label_18">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>minutes</string>
</property>
@ -1563,7 +1565,7 @@ download page.</string>
</widget>
</item>
<item>
<spacer name="verticalSpacer_15">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>

View file

@ -33,7 +33,7 @@
</property>
<widget class="QWidget" name="filesTab">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/folders.svg</normaloff>:/icons/folders.svg</iconset>
</attribute>
<attribute name="title">
@ -96,7 +96,7 @@
</widget>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/folder-sound.svg</normaloff>:/icons/folder-sound.svg</iconset>
</attribute>
<attribute name="title">
@ -152,7 +152,7 @@
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/icon32_hunspell.png</normaloff>:/icons/icon32_hunspell.png</iconset>
</attribute>
<attribute name="title">
@ -220,7 +220,7 @@ of the appropriate groups to use them.</string>
</widget>
<widget class="QWidget" name="mediaWikisTab">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/icon32_wiki.png</normaloff>:/icons/icon32_wiki.png</iconset>
</attribute>
<attribute name="title">
@ -279,7 +279,7 @@ of the appropriate groups to use them.</string>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/internet.svg</normaloff>:/icons/internet.svg</iconset>
</attribute>
<attribute name="title">
@ -343,7 +343,7 @@ of the appropriate groups to use them.</string>
</widget>
<widget class="QWidget" name="dictdTab">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/network.svg</normaloff>:/icons/network.svg</iconset>
</attribute>
<attribute name="title">
@ -399,7 +399,7 @@ of the appropriate groups to use them.</string>
</widget>
<widget class="QWidget" name="tab_6">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/programs.svg</normaloff>:/icons/programs.svg</iconset>
</attribute>
<attribute name="title">
@ -458,7 +458,7 @@ of the appropriate groups to use them.</string>
</widget>
<widget class="QWidget" name="tab_lingua">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/lingualibre.svg</normaloff>:/icons/lingualibre.svg</iconset>
</attribute>
<attribute name="title">
@ -526,7 +526,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
</widget>
<widget class="QWidget" name="tab_5">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/forvo.png</normaloff>:/icons/forvo.png</iconset>
</attribute>
<attribute name="title">
@ -674,7 +674,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="icon">
<iconset>
<iconset resource="../../resources.qrc">
<normaloff>:/icons/transliteration.png</normaloff>:/icons/transliteration.png</iconset>
</attribute>
<attribute name="title">
@ -692,7 +692,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
<string>Greek transliteration</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../icons/flags.qrc">
<normaloff>:/flags/gr.png</normaloff>:/flags/gr.png</iconset>
</property>
</widget>
@ -703,7 +703,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
<string>Russian transliteration</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../icons/flags.qrc">
<normaloff>:/flags/ru.png</normaloff>:/flags/ru.png</iconset>
</property>
</widget>
@ -714,7 +714,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
<string>German transliteration</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../icons/flags.qrc">
<normaloff>:/flags/de.png</normaloff>:/flags/de.png</iconset>
</property>
</widget>
@ -725,7 +725,7 @@ Full list of availiable languages can be found &lt;a href=&quot;https://linguali
<string>Belarusian transliteration</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../../icons/flags.qrc">
<normaloff>:/flags/by.png</normaloff>:/flags/by.png</iconset>
</property>
</widget>
@ -827,6 +827,39 @@ Not implemented yet in GoldenDict.</string>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<widget class="QGroupBox" name="enableCustomTransliteration">
<property name="title">
<string>Custom transliteration</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<widget class="QLabel" name="label_21">
<property name="text">
<string>This only applied in search phrase, with each line represent a transliteration,semicolon seperated. For example, ae;æ,users can input ae to represent æ in the target word.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="customTransliteration">
<property name="placeholderText">
<string>ae;æ #this is an example</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
@ -857,6 +890,9 @@ Not implemented yet in GoldenDict.</string>
<tabstop>removeSoundDir</tabstop>
<tabstop>paths</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../../icons/flags.qrc"/>
<include location="../../resources.qrc"/>
</resources>
<connections/>
</ui>