summaryrefslogtreecommitdiffstats
path: root/tools/linguist/linguist
diff options
context:
space:
mode:
Diffstat (limited to 'tools/linguist/linguist')
-rw-r--r--tools/linguist/linguist/about.ui223
-rw-r--r--tools/linguist/linguist/finddialog.cpp183
-rw-r--r--tools/linguist/linguist/finddialog.h68
-rw-r--r--tools/linguist/linguist/images/accelerator.pngbin0 -> 782 bytes
-rw-r--r--tools/linguist/linguist/images/appicon.pngbin0 -> 1936 bytes
-rw-r--r--tools/linguist/linguist/images/book.pngbin0 -> 825 bytes
-rw-r--r--tools/linguist/linguist/images/d_accelerator.pngbin0 -> 487 bytes
-rw-r--r--tools/linguist/linguist/images/d_book.pngbin0 -> 557 bytes
-rw-r--r--tools/linguist/linguist/images/d_doneandnext.pngbin0 -> 457 bytes
-rw-r--r--tools/linguist/linguist/images/d_editcopy.pngbin0 -> 526 bytes
-rw-r--r--tools/linguist/linguist/images/d_editcut.pngbin0 -> 800 bytes
-rw-r--r--tools/linguist/linguist/images/d_editpaste.pngbin0 -> 610 bytes
-rw-r--r--tools/linguist/linguist/images/d_fileopen.pngbin0 -> 406 bytes
-rw-r--r--tools/linguist/linguist/images/d_filesave.pngbin0 -> 267 bytes
-rw-r--r--tools/linguist/linguist/images/d_next.pngbin0 -> 446 bytes
-rw-r--r--tools/linguist/linguist/images/d_nextunfinished.pngbin0 -> 522 bytes
-rw-r--r--tools/linguist/linguist/images/d_phrase.pngbin0 -> 290 bytes
-rw-r--r--tools/linguist/linguist/images/d_prev.pngbin0 -> 425 bytes
-rw-r--r--tools/linguist/linguist/images/d_prevunfinished.pngbin0 -> 542 bytes
-rw-r--r--tools/linguist/linguist/images/d_print.pngbin0 -> 595 bytes
-rw-r--r--tools/linguist/linguist/images/d_punctuation.pngbin0 -> 356 bytes
-rw-r--r--tools/linguist/linguist/images/d_redo.pngbin0 -> 465 bytes
-rw-r--r--tools/linguist/linguist/images/d_s_check_danger.pngbin0 -> 270 bytes
-rw-r--r--tools/linguist/linguist/images/d_s_check_obs.pngbin0 -> 220 bytes
-rw-r--r--tools/linguist/linguist/images/d_s_check_off.pngbin0 -> 348 bytes
-rw-r--r--tools/linguist/linguist/images/d_s_check_on.pngbin0 -> 220 bytes
-rw-r--r--tools/linguist/linguist/images/d_searchfind.pngbin0 -> 501 bytes
-rw-r--r--tools/linguist/linguist/images/d_undo.pngbin0 -> 471 bytes
-rw-r--r--tools/linguist/linguist/images/doneandnext.pngbin0 -> 532 bytes
-rw-r--r--tools/linguist/linguist/images/editcopy.pngbin0 -> 491 bytes
-rw-r--r--tools/linguist/linguist/images/editcut.pngbin0 -> 649 bytes
-rw-r--r--tools/linguist/linguist/images/editpaste.pngbin0 -> 864 bytes
-rw-r--r--tools/linguist/linguist/images/fileopen.pngbin0 -> 681 bytes
-rw-r--r--tools/linguist/linguist/images/filesave.pngbin0 -> 328 bytes
-rw-r--r--tools/linguist/linguist/images/next.pngbin0 -> 541 bytes
-rw-r--r--tools/linguist/linguist/images/nextunfinished.pngbin0 -> 649 bytes
-rw-r--r--tools/linguist/linguist/images/pagecurl.pngbin0 -> 1247 bytes
-rw-r--r--tools/linguist/linguist/images/phrase.pngbin0 -> 366 bytes
-rw-r--r--tools/linguist/linguist/images/prev.pngbin0 -> 542 bytes
-rw-r--r--tools/linguist/linguist/images/prevunfinished.pngbin0 -> 725 bytes
-rw-r--r--tools/linguist/linguist/images/print.pngbin0 -> 766 bytes
-rw-r--r--tools/linguist/linguist/images/punctuation.pngbin0 -> 502 bytes
-rw-r--r--tools/linguist/linguist/images/redo.pngbin0 -> 592 bytes
-rw-r--r--tools/linguist/linguist/images/s_check_danger.pngbin0 -> 326 bytes
-rw-r--r--tools/linguist/linguist/images/s_check_obs.pngbin0 -> 245 bytes
-rw-r--r--tools/linguist/linguist/images/s_check_off.pngbin0 -> 439 bytes
-rw-r--r--tools/linguist/linguist/images/s_check_on.pngbin0 -> 235 bytes
-rw-r--r--tools/linguist/linguist/images/searchfind.pngbin0 -> 843 bytes
-rw-r--r--tools/linguist/linguist/images/splash.pngbin0 -> 31939 bytes
-rw-r--r--tools/linguist/linguist/images/undo.pngbin0 -> 572 bytes
-rw-r--r--tools/linguist/linguist/images/whatsthis.xpm24
-rw-r--r--tools/linguist/linguist/linguist.icnsbin0 -> 47620 bytes
-rw-r--r--tools/linguist/linguist/linguist.icobin0 -> 10134 bytes
-rw-r--r--tools/linguist/linguist/linguist.pro109
-rw-r--r--tools/linguist/linguist/linguist.rc1
-rw-r--r--tools/linguist/linguist/linguist_de.ts993
-rw-r--r--tools/linguist/linguist/linguist_fr.ts993
-rw-r--r--tools/linguist/linguist/listviews.cpp350
-rw-r--r--tools/linguist/linguist/listviews.h135
-rw-r--r--tools/linguist/linguist/main.cpp89
-rw-r--r--tools/linguist/linguist/msgedit.cpp834
-rw-r--r--tools/linguist/linguist/msgedit.h244
-rw-r--r--tools/linguist/linguist/phrase.cpp189
-rw-r--r--tools/linguist/linguist/phrase.h74
-rw-r--r--tools/linguist/linguist/phrasebookbox.cpp244
-rw-r--r--tools/linguist/linguist/phrasebookbox.h84
-rw-r--r--tools/linguist/linguist/phraselv.cpp171
-rw-r--r--tools/linguist/linguist/phraselv.h83
-rw-r--r--tools/linguist/linguist/printout.cpp182
-rw-r--r--tools/linguist/linguist/printout.h126
-rw-r--r--tools/linguist/linguist/simtexth.cpp239
-rw-r--r--tools/linguist/linguist/simtexth.h64
-rw-r--r--tools/linguist/linguist/statistics.ui259
-rw-r--r--tools/linguist/linguist/statistics.ui.h53
-rw-r--r--tools/linguist/linguist/trwindow.cpp2071
-rw-r--r--tools/linguist/linguist/trwindow.h237
76 files changed, 8322 insertions, 0 deletions
diff --git a/tools/linguist/linguist/about.ui b/tools/linguist/linguist/about.ui
new file mode 100644
index 0000000..b2fb6b4
--- /dev/null
+++ b/tools/linguist/linguist/about.ui
@@ -0,0 +1,223 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>AboutDialog</class>
+<comment>*********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*********************************************************************</comment>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>AboutDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>640</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Qt Linguist</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>PixmapLabel1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>splash.png</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>versionLabel</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved.</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Qt Commercial Edition license holders: This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Qt Open Source Edition users: This program is licensed to you under the terms of the GNU General Public License Version 2. For details, see the file LICENSE.GPL that came with this software distribution.&lt;/p&gt;&lt;p&gt;The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.&lt;/p&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="wordwrap" stdset="0">
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>PushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>PushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>AboutDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">init()</slot>
+ <slot access="protected">destroy()</slot>
+</slots>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/tools/linguist/linguist/finddialog.cpp b/tools/linguist/linguist/finddialog.cpp
new file mode 100644
index 0000000..385bd31
--- /dev/null
+++ b/tools/linguist/linguist/finddialog.cpp
@@ -0,0 +1,183 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* TRANSLATOR FindDialog
+
+ Choose Edit|Find from the menu bar or press Ctrl+F to pop up the
+ Find dialog
+*/
+
+#include "finddialog.h"
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+
+FindDialog::FindDialog( bool replace, QWidget *parent, const char *name,
+ bool modal )
+ : QDialog( parent, name, modal )
+{
+ sourceText = 0;
+
+ led = new QLineEdit( this, "find line edit" );
+ QLabel *findWhat = new QLabel( led, tr("Fi&nd what:"), this, "find what" );
+ QLabel *replaceWith = 0;
+ QPushButton *findNxt = new QPushButton( tr("&Find Next"), this,
+ "find next" );
+ findNxt->setDefault( TRUE );
+ connect( findNxt, SIGNAL(clicked()), this, SLOT(emitFindNext()) );
+ QPushButton *cancel = new QPushButton( tr("Cancel"), this, "cancel find" );
+ connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) );
+
+ QVBoxLayout *bl = new QVBoxLayout( 6, "find button layout" );
+ bl->addWidget( findNxt );
+
+ matchCase = new QCheckBox( tr("&Match case"), this, "find match case" );
+ matchCase->setChecked( FALSE );
+
+ if ( replace ) {
+ QWhatsThis::add( this, tr("This window allows you to search and replace"
+ " some text in the translations.") );
+
+ red = new QLineEdit( this, "replace line edit" );
+ replaceWith = new QLabel( red, tr("Replace &with:"), this,
+ "replace with" );
+ setTabOrder( led, red );
+
+ QPushButton *replace = new QPushButton( tr("&Replace"), this,
+ "replace" );
+ connect( replace, SIGNAL(clicked()), this, SLOT(emitReplace()) );
+ QPushButton *replaceAll = new QPushButton( tr("Replace &All"), this,
+ "replace all" );
+ connect( replaceAll, SIGNAL(clicked()), this, SLOT(emitReplaceAll()) );
+ setTabOrder( findNxt, replace );
+ setTabOrder( replace, replaceAll );
+ setTabOrder( replaceAll, cancel );
+
+ QWhatsThis::add( replace, tr("Click here to replace the next occurrence"
+ " of the text you typed in.") );
+ QWhatsThis::add( replaceAll, tr("Click here to replace all occurrences"
+ " of the text you typed in.") );
+
+ bl->addWidget( replace );
+ bl->addWidget( replaceAll );
+
+ QGridLayout *gl = new QGridLayout( this, 4, 3, 11, 11,
+ "find outer layout" );
+ gl->addWidget( findWhat, 0, 0 );
+ gl->addWidget( led, 0, 1 );
+ gl->addWidget( replaceWith, 1, 0 );
+ gl->addWidget( red, 1, 1 );
+ gl->addMultiCellWidget( matchCase, 2, 2, 0, 1 );
+ gl->addMultiCell( bl, 0, 3, 3, 3 );
+ } else {
+ QWhatsThis::add( this, tr("This window allows you to search for some"
+ " text in the translation source file.") );
+
+ sourceText = new QCheckBox( tr("&Source texts"), this,
+ "find in source texts" );
+ sourceText->setChecked( TRUE );
+ translations = new QCheckBox( tr("&Translations"), this,
+ "find in translations" );
+ translations->setChecked( TRUE );
+ comments = new QCheckBox( tr("&Comments"), this, "find in comments" );
+ comments->setChecked( TRUE );
+
+ QWhatsThis::add( sourceText, tr("Source texts are searched when"
+ " checked.") );
+ QWhatsThis::add( translations, tr("Translations are searched when"
+ " checked.") );
+ QWhatsThis::add( comments, tr("Comments and contexts are searched when"
+ " checked.") );
+
+ QVBoxLayout *cl = new QVBoxLayout( 6, "find checkbox layout" );
+
+ QGridLayout *gl = new QGridLayout( this, 3, 4, 11, 11,
+ "find outer layout" );
+ gl->addWidget( findWhat, 0, 0 );
+ gl->addMultiCellWidget( led, 0, 0, 1, 2 );
+ gl->addWidget( matchCase, 1, 2 );
+ gl->addMultiCell( bl, 0, 2, 3, 3 );
+ gl->addMultiCell( cl, 1, 2, 0, 1 );
+ gl->setColStretch( 0, 0 );
+ gl->addColSpacing( 1, 40 );
+ gl->setColStretch( 2, 1 );
+ gl->setColStretch( 3, 0 );
+
+ cl->addWidget( sourceText );
+ cl->addWidget( translations );
+ cl->addWidget( comments );
+ cl->addStretch( 1 );
+ }
+
+ QWhatsThis::add( led, tr("Type in the text to search for.") );
+
+ QWhatsThis::add( matchCase, tr("Texts such as 'TeX' and 'tex' are"
+ " considered as different when checked.") );
+ QWhatsThis::add( findNxt, tr("Click here to find the next occurrence of the"
+ " text you typed in.") );
+ QWhatsThis::add( cancel, tr("Click here to close this window.") );
+
+ bl->addWidget( cancel );
+ bl->addStretch( 1 );
+
+ resize( 400, 1 );
+ setMaximumHeight( height() );
+
+ led->setFocus();
+}
+
+void FindDialog::emitFindNext()
+{
+ int where;
+ if ( sourceText != 0 )
+ where = ( sourceText->isChecked() ? SourceText : 0 ) |
+ ( translations->isChecked() ? Translations : 0 ) |
+ ( comments->isChecked() ? Comments : 0 );
+ else
+ where = Translations;
+ emit findNext( led->text(), where, matchCase->isChecked() );
+}
+
+void FindDialog::emitReplace()
+{
+ emit replace( led->text(), red->text(), matchCase->isChecked(), FALSE );
+}
+
+void FindDialog::emitReplaceAll()
+{
+ emit replace( led->text(), red->text(), matchCase->isChecked(), TRUE );
+}
diff --git a/tools/linguist/linguist/finddialog.h b/tools/linguist/linguist/finddialog.h
new file mode 100644
index 0000000..5d06e8e
--- /dev/null
+++ b/tools/linguist/linguist/finddialog.h
@@ -0,0 +1,68 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef FINDDIALOG_H
+#define FINDDIALOG_H
+
+#include <qdialog.h>
+
+class QCheckBox;
+class QLineEdit;
+
+class FindDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ enum { SourceText = 0x1, Translations = 0x2, Comments = 0x4 };
+
+ FindDialog( bool replace, QWidget *parent = 0, const char *name = 0, bool modal = FALSE );
+
+signals:
+ void findNext( const QString& text, int where, bool matchCase );
+ void replace( const QString& before, const QString& after, bool matchCase, bool all );
+
+private slots:
+ void emitFindNext();
+ void emitReplace();
+ void emitReplaceAll();
+
+private:
+ QLineEdit *led;
+ QLineEdit *red;
+ QCheckBox *sourceText;
+ QCheckBox *translations;
+ QCheckBox *comments;
+ QCheckBox *matchCase;
+};
+
+#endif
diff --git a/tools/linguist/linguist/images/accelerator.png b/tools/linguist/linguist/images/accelerator.png
new file mode 100644
index 0000000..173adb4
--- /dev/null
+++ b/tools/linguist/linguist/images/accelerator.png
Binary files differ
diff --git a/tools/linguist/linguist/images/appicon.png b/tools/linguist/linguist/images/appicon.png
new file mode 100644
index 0000000..90e143b
--- /dev/null
+++ b/tools/linguist/linguist/images/appicon.png
Binary files differ
diff --git a/tools/linguist/linguist/images/book.png b/tools/linguist/linguist/images/book.png
new file mode 100644
index 0000000..dd850ab
--- /dev/null
+++ b/tools/linguist/linguist/images/book.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_accelerator.png b/tools/linguist/linguist/images/d_accelerator.png
new file mode 100644
index 0000000..eaa2be6
--- /dev/null
+++ b/tools/linguist/linguist/images/d_accelerator.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_book.png b/tools/linguist/linguist/images/d_book.png
new file mode 100644
index 0000000..b61d611
--- /dev/null
+++ b/tools/linguist/linguist/images/d_book.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_doneandnext.png b/tools/linguist/linguist/images/d_doneandnext.png
new file mode 100644
index 0000000..e3a3fe1
--- /dev/null
+++ b/tools/linguist/linguist/images/d_doneandnext.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_editcopy.png b/tools/linguist/linguist/images/d_editcopy.png
new file mode 100644
index 0000000..578b591
--- /dev/null
+++ b/tools/linguist/linguist/images/d_editcopy.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_editcut.png b/tools/linguist/linguist/images/d_editcut.png
new file mode 100644
index 0000000..8d50ae0
--- /dev/null
+++ b/tools/linguist/linguist/images/d_editcut.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_editpaste.png b/tools/linguist/linguist/images/d_editpaste.png
new file mode 100644
index 0000000..78cab10
--- /dev/null
+++ b/tools/linguist/linguist/images/d_editpaste.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_fileopen.png b/tools/linguist/linguist/images/d_fileopen.png
new file mode 100644
index 0000000..ddbd33d
--- /dev/null
+++ b/tools/linguist/linguist/images/d_fileopen.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_filesave.png b/tools/linguist/linguist/images/d_filesave.png
new file mode 100644
index 0000000..5d1476d
--- /dev/null
+++ b/tools/linguist/linguist/images/d_filesave.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_next.png b/tools/linguist/linguist/images/d_next.png
new file mode 100644
index 0000000..f455e1f
--- /dev/null
+++ b/tools/linguist/linguist/images/d_next.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_nextunfinished.png b/tools/linguist/linguist/images/d_nextunfinished.png
new file mode 100644
index 0000000..c2b06ec
--- /dev/null
+++ b/tools/linguist/linguist/images/d_nextunfinished.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_phrase.png b/tools/linguist/linguist/images/d_phrase.png
new file mode 100644
index 0000000..acdd253
--- /dev/null
+++ b/tools/linguist/linguist/images/d_phrase.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_prev.png b/tools/linguist/linguist/images/d_prev.png
new file mode 100644
index 0000000..a68fe54
--- /dev/null
+++ b/tools/linguist/linguist/images/d_prev.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_prevunfinished.png b/tools/linguist/linguist/images/d_prevunfinished.png
new file mode 100644
index 0000000..ce956a7
--- /dev/null
+++ b/tools/linguist/linguist/images/d_prevunfinished.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_print.png b/tools/linguist/linguist/images/d_print.png
new file mode 100644
index 0000000..b2791a7
--- /dev/null
+++ b/tools/linguist/linguist/images/d_print.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_punctuation.png b/tools/linguist/linguist/images/d_punctuation.png
new file mode 100644
index 0000000..8eebab8
--- /dev/null
+++ b/tools/linguist/linguist/images/d_punctuation.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_redo.png b/tools/linguist/linguist/images/d_redo.png
new file mode 100644
index 0000000..6e993cc
--- /dev/null
+++ b/tools/linguist/linguist/images/d_redo.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_s_check_danger.png b/tools/linguist/linguist/images/d_s_check_danger.png
new file mode 100644
index 0000000..3fadeb1
--- /dev/null
+++ b/tools/linguist/linguist/images/d_s_check_danger.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_s_check_obs.png b/tools/linguist/linguist/images/d_s_check_obs.png
new file mode 100644
index 0000000..4836e2f
--- /dev/null
+++ b/tools/linguist/linguist/images/d_s_check_obs.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_s_check_off.png b/tools/linguist/linguist/images/d_s_check_off.png
new file mode 100644
index 0000000..58f7fb6
--- /dev/null
+++ b/tools/linguist/linguist/images/d_s_check_off.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_s_check_on.png b/tools/linguist/linguist/images/d_s_check_on.png
new file mode 100644
index 0000000..4836e2f
--- /dev/null
+++ b/tools/linguist/linguist/images/d_s_check_on.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_searchfind.png b/tools/linguist/linguist/images/d_searchfind.png
new file mode 100644
index 0000000..e85e33f
--- /dev/null
+++ b/tools/linguist/linguist/images/d_searchfind.png
Binary files differ
diff --git a/tools/linguist/linguist/images/d_undo.png b/tools/linguist/linguist/images/d_undo.png
new file mode 100644
index 0000000..22ac97f
--- /dev/null
+++ b/tools/linguist/linguist/images/d_undo.png
Binary files differ
diff --git a/tools/linguist/linguist/images/doneandnext.png b/tools/linguist/linguist/images/doneandnext.png
new file mode 100644
index 0000000..1cf8888
--- /dev/null
+++ b/tools/linguist/linguist/images/doneandnext.png
Binary files differ
diff --git a/tools/linguist/linguist/images/editcopy.png b/tools/linguist/linguist/images/editcopy.png
new file mode 100644
index 0000000..804c98c
--- /dev/null
+++ b/tools/linguist/linguist/images/editcopy.png
Binary files differ
diff --git a/tools/linguist/linguist/images/editcut.png b/tools/linguist/linguist/images/editcut.png
new file mode 100644
index 0000000..a911482
--- /dev/null
+++ b/tools/linguist/linguist/images/editcut.png
Binary files differ
diff --git a/tools/linguist/linguist/images/editpaste.png b/tools/linguist/linguist/images/editpaste.png
new file mode 100644
index 0000000..1938141
--- /dev/null
+++ b/tools/linguist/linguist/images/editpaste.png
Binary files differ
diff --git a/tools/linguist/linguist/images/fileopen.png b/tools/linguist/linguist/images/fileopen.png
new file mode 100644
index 0000000..3005290
--- /dev/null
+++ b/tools/linguist/linguist/images/fileopen.png
Binary files differ
diff --git a/tools/linguist/linguist/images/filesave.png b/tools/linguist/linguist/images/filesave.png
new file mode 100644
index 0000000..c137165
--- /dev/null
+++ b/tools/linguist/linguist/images/filesave.png
Binary files differ
diff --git a/tools/linguist/linguist/images/next.png b/tools/linguist/linguist/images/next.png
new file mode 100644
index 0000000..4b29ff4
--- /dev/null
+++ b/tools/linguist/linguist/images/next.png
Binary files differ
diff --git a/tools/linguist/linguist/images/nextunfinished.png b/tools/linguist/linguist/images/nextunfinished.png
new file mode 100644
index 0000000..9892b65
--- /dev/null
+++ b/tools/linguist/linguist/images/nextunfinished.png
Binary files differ
diff --git a/tools/linguist/linguist/images/pagecurl.png b/tools/linguist/linguist/images/pagecurl.png
new file mode 100644
index 0000000..2d3f2ff
--- /dev/null
+++ b/tools/linguist/linguist/images/pagecurl.png
Binary files differ
diff --git a/tools/linguist/linguist/images/phrase.png b/tools/linguist/linguist/images/phrase.png
new file mode 100644
index 0000000..d7dfcb5
--- /dev/null
+++ b/tools/linguist/linguist/images/phrase.png
Binary files differ
diff --git a/tools/linguist/linguist/images/prev.png b/tools/linguist/linguist/images/prev.png
new file mode 100644
index 0000000..4e3556c
--- /dev/null
+++ b/tools/linguist/linguist/images/prev.png
Binary files differ
diff --git a/tools/linguist/linguist/images/prevunfinished.png b/tools/linguist/linguist/images/prevunfinished.png
new file mode 100644
index 0000000..a3bed54
--- /dev/null
+++ b/tools/linguist/linguist/images/prevunfinished.png
Binary files differ
diff --git a/tools/linguist/linguist/images/print.png b/tools/linguist/linguist/images/print.png
new file mode 100644
index 0000000..cc083ed
--- /dev/null
+++ b/tools/linguist/linguist/images/print.png
Binary files differ
diff --git a/tools/linguist/linguist/images/punctuation.png b/tools/linguist/linguist/images/punctuation.png
new file mode 100644
index 0000000..849d4a9
--- /dev/null
+++ b/tools/linguist/linguist/images/punctuation.png
Binary files differ
diff --git a/tools/linguist/linguist/images/redo.png b/tools/linguist/linguist/images/redo.png
new file mode 100644
index 0000000..abdad26
--- /dev/null
+++ b/tools/linguist/linguist/images/redo.png
Binary files differ
diff --git a/tools/linguist/linguist/images/s_check_danger.png b/tools/linguist/linguist/images/s_check_danger.png
new file mode 100644
index 0000000..7005304
--- /dev/null
+++ b/tools/linguist/linguist/images/s_check_danger.png
Binary files differ
diff --git a/tools/linguist/linguist/images/s_check_obs.png b/tools/linguist/linguist/images/s_check_obs.png
new file mode 100644
index 0000000..b171b2a
--- /dev/null
+++ b/tools/linguist/linguist/images/s_check_obs.png
Binary files differ
diff --git a/tools/linguist/linguist/images/s_check_off.png b/tools/linguist/linguist/images/s_check_off.png
new file mode 100644
index 0000000..cf45bc0
--- /dev/null
+++ b/tools/linguist/linguist/images/s_check_off.png
Binary files differ
diff --git a/tools/linguist/linguist/images/s_check_on.png b/tools/linguist/linguist/images/s_check_on.png
new file mode 100644
index 0000000..b5238f7
--- /dev/null
+++ b/tools/linguist/linguist/images/s_check_on.png
Binary files differ
diff --git a/tools/linguist/linguist/images/searchfind.png b/tools/linguist/linguist/images/searchfind.png
new file mode 100644
index 0000000..3f369fd
--- /dev/null
+++ b/tools/linguist/linguist/images/searchfind.png
Binary files differ
diff --git a/tools/linguist/linguist/images/splash.png b/tools/linguist/linguist/images/splash.png
new file mode 100644
index 0000000..8e80718
--- /dev/null
+++ b/tools/linguist/linguist/images/splash.png
Binary files differ
diff --git a/tools/linguist/linguist/images/undo.png b/tools/linguist/linguist/images/undo.png
new file mode 100644
index 0000000..839a823
--- /dev/null
+++ b/tools/linguist/linguist/images/undo.png
Binary files differ
diff --git a/tools/linguist/linguist/images/whatsthis.xpm b/tools/linguist/linguist/images/whatsthis.xpm
new file mode 100644
index 0000000..e45dc26
--- /dev/null
+++ b/tools/linguist/linguist/images/whatsthis.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char *magick[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 3 1",
+" c None",
+"o c #000000000000",
+"a c #000000008000",
+/* pixels */
+"o aaaaa ",
+"oo aaa aaa ",
+"ooo aaa aaa",
+"oooo aa aa",
+"ooooo aa aa",
+"oooooo a aaa",
+"ooooooo aaa ",
+"oooooooo aaa ",
+"ooooooooo aaa ",
+"ooooo aaa ",
+"oo ooo ",
+"o ooo aaa ",
+" ooo aaa ",
+" ooo ",
+" ooo ",
+" ooo "};
diff --git a/tools/linguist/linguist/linguist.icns b/tools/linguist/linguist/linguist.icns
new file mode 100644
index 0000000..f51565e
--- /dev/null
+++ b/tools/linguist/linguist/linguist.icns
Binary files differ
diff --git a/tools/linguist/linguist/linguist.ico b/tools/linguist/linguist/linguist.ico
new file mode 100644
index 0000000..2816c7c
--- /dev/null
+++ b/tools/linguist/linguist/linguist.ico
Binary files differ
diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro
new file mode 100644
index 0000000..da4d782
--- /dev/null
+++ b/tools/linguist/linguist/linguist.pro
@@ -0,0 +1,109 @@
+TEMPLATE = app
+LANGUAGE = C++
+CONFIG += qt warn_on
+
+
+SOURCES += finddialog.cpp \
+ main.cpp \
+ msgedit.cpp \
+ phrase.cpp \
+ phrasebookbox.cpp \
+ phraselv.cpp \
+ printout.cpp \
+ simtexth.cpp \
+ trwindow.cpp \
+ listviews.cpp \
+ ../shared/metatranslator.cpp
+HEADERS += finddialog.h \
+ msgedit.h \
+ phrase.h \
+ phrasebookbox.h \
+ phraselv.h \
+ printout.h \
+ trwindow.h \
+ listviews.h \
+ ../shared/metatranslator.h
+
+
+TRANSLATIONS = linguist_de.ts \
+ linguist_fr.ts
+
+DEFINES += QT_INTERNAL_XML
+include( ../../../src/qt_professional.pri )
+
+DESTDIR = ../../../bin
+TARGET = linguist
+
+
+LIBS += -L$$QT_BUILD_TREE/lib -lqassistantclient
+
+win32:RC_FILE = linguist.rc
+
+mac {
+ staticlib:CONFIG -= global_init_link_order #yuck
+ RC_FILE = linguist.icns
+}
+
+PROJECTNAME = Qt Linguist
+
+target.path=$$bins.path
+INSTALLS += target
+
+linguisttranslations.files = *.qm
+linguisttranslations.path = $$translations.path
+INSTALLS += linguisttranslations
+
+phrasebooks.path=$$data.path/phrasebooks
+phrasebooks.files = ../phrasebooks/*
+INSTALLS += phrasebooks
+FORMS = about.ui \
+ statistics.ui
+IMAGES = images/accelerator.png \
+ images/book.png \
+ images/s_check_danger.png \
+ images/s_check_obs.png \
+ images/s_check_off.png \
+ images/s_check_on.png \
+ images/d_s_check_danger.png \
+ images/d_s_check_obs.png \
+ images/d_s_check_off.png \
+ images/d_s_check_on.png \
+ images/d_accelerator.png \
+ images/d_book.png \
+ images/d_doneandnext.png \
+ images/d_editcopy.png \
+ images/d_editcut.png \
+ images/d_editpaste.png \
+ images/d_fileopen.png \
+ images/d_filesave.png \
+ images/d_next.png \
+ images/d_nextunfinished.png \
+ images/d_prev.png \
+ images/d_prevunfinished.png \
+ images/d_phrase.png \
+ images/d_print.png \
+ images/d_punctuation.png \
+ images/d_redo.png \
+ images/d_searchfind.png \
+ images/d_undo.png \
+ images/doneandnext.png \
+ images/editcopy.png \
+ images/editcut.png \
+ images/editpaste.png \
+ images/punctuation.png \
+ images/fileopen.png \
+ images/filesave.png \
+ images/appicon.png \
+ images/next.png \
+ images/nextunfinished.png \
+ images/pagecurl.png \
+ images/phrase.png \
+ images/prev.png \
+ images/prevunfinished.png \
+ images/print.png \
+ images/redo.png \
+ images/searchfind.png \
+ images/splash.png \
+ images/undo.png \
+ images/whatsthis.xpm
+INCLUDEPATH += ../shared
diff --git a/tools/linguist/linguist/linguist.rc b/tools/linguist/linguist/linguist.rc
new file mode 100644
index 0000000..865e021
--- /dev/null
+++ b/tools/linguist/linguist/linguist.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "linguist.ico"
diff --git a/tools/linguist/linguist/linguist_de.ts b/tools/linguist/linguist/linguist_de.ts
new file mode 100644
index 0000000..06d818b
--- /dev/null
+++ b/tools/linguist/linguist/linguist_de.ts
@@ -0,0 +1,993 @@
+<!DOCTYPE TS><TS>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file &apos;LICENSE.GPL&apos; that came with this software distribution. If you did not get the file, send email to info@trolltech.com.&lt;/p&gt;
+&lt;p&gt;The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>EditorPage</name>
+ <message>
+ <source>Source text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <comment>Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog</comment>
+ <message>
+ <source>Fi&amp;nd what:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Find Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Match case</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to search and replace some text in the translations.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace &amp;with:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Replace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to replace the next occurrence of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to replace all occurrences of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to search for some text in the translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Source texts</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translations</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source texts are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translations are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Comments and contexts are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type in the text to search for.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Texts such as &apos;TeX&apos; and &apos;tex&apos; are considered as different when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to find the next occurrence of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to close this window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MessageEditor</name>
+ <message>
+ <source>bell</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>backspace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>new page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>new line</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>carriage return</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>tab</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases and guesses:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This whole panel allows you to view and edit the translation of some source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This area shows the source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This area shows a comment that may guide you, and the context in which the text occurs.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is where you can enter or modify the translation of some source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Guess</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Guess (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageCurl</name>
+ <message>
+ <source>Next unfinished phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Previous unfinished phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PhraseBookBox</name>
+ <comment>Go to Phrase &gt; Edit Phrase Book... The dialog that pops up is a PhraseBookBox.</comment>
+ <message>
+ <source>S&amp;ource phrase:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translation:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Definition:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;New Phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Remove Phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to add, modify, or delete phrases in a phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is the phrase in the source language.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is the phrase in the target language corresponding to the source phrase.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is a definition for the source phrase.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to add the phrase to the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to remove the phrase from the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to save the changes made.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to close this window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot save phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PhraseLV</name>
+ <comment>The phrase list in the right panel of the main window (with Source phrase, Target phrase, and Definition in its header) is a PhraseLV object.</comment>
+ <message>
+ <source>(New Phrase)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is a list of phrase entries relevant to the source text. Each phrase is supplemented with a suggested translation and a definition.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;&lt;u&gt;%1:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%2&lt;/p&gt;&lt;p&gt;&lt;u&gt;%3:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%4&lt;/p&gt;&lt;p&gt;&lt;u&gt;%5:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%6&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Definition</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TrWindow</name>
+ <comment>This is the application&apos;s main window.</comment>
+ <message>
+ <source>Context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MOD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This panel lists the source contexts.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This panel lists the source texts. Items that violate validation rules are marked with a warning.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Loading...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 source phrase(s) loaded.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot open &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt translation source (*.ts)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File saved.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot save &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt message files for released applications (*.qm)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Context: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>finished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>unresolved</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>obsolete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing... (page %1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing completed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search wrapped.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot find the string &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt phrase books (*.qph)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create New Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>A file called &apos;%1&apos; already exists. Please choose another name.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrase book created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 phrase(s) loaded.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you want to save &apos;%1&apos;?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist by Trolltech</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No phrase to translate.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No untranslated phrases left.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;alidation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Open...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+O</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save &amp;As...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Release...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Print...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+P</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Re&amp;cently opened files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Redo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cu&amp;t</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+V</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+A</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Find...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+F</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Find &amp;Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Replace...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+H</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Prev Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+K</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Next Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+L</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>P&amp;rev</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Shift+K</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ne&amp;xt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Shift+L</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done and &amp;Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Enter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Return</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Begin from Source</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;New Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+N</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Open Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Close Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Edit Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Print Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Accelerators</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Ending Punctuation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Phrase Matches</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Revert Sorting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Display guesses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Vie&amp;ws</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Toolbars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Manual</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;What&apos;s This?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open a Qt translation source file (TS file) for editing.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save changes made to this Qt translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save changes made to this Qt translationsource file into a new file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a Qt message file suitable for released applications from the current message file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print a list of all the phrases in the current Qt translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close this window and exit.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo the last editing operation performed on the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Redo an undone editing operation performed on the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the selected translation text to the clipboard and deletes it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the selected translation text to the clipboard.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Paste the clipboard text into the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the whole translation text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for some text in the translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Continue the search where it was left.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for some text in the translation source file and replace it by another text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a new phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open a phrase book to assist translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle validity checks of accelerators.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle validity checks of ending punctuation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle checking that phrase suggestions are used.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sort the items back in the same order as in the message file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set whether or not to display translation guesses.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display the manual for %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display information about %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display information about the Qt toolkit by Trolltech.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter What&apos;s This? mode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copies the source text into the translation field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the next item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the previous item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the next unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the previous unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Marks this item as done and moves to the next unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Validation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Redo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cut</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Find</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Prev</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Prev Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Next Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done and Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerators</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Punctuation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>What&apos;s This?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot read from phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close this phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow you to add, modify, or delete phrases of this phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print the entries of the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerator possibly superfluous in translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerator possibly missing in translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation does not end with the same punctuation as the source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>A phrase book suggestion for &apos;%1&apos; was ignored.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tools/linguist/linguist/linguist_fr.ts b/tools/linguist/linguist/linguist_fr.ts
new file mode 100644
index 0000000..06d818b
--- /dev/null
+++ b/tools/linguist/linguist/linguist_fr.ts
@@ -0,0 +1,993 @@
+<!DOCTYPE TS><TS>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file &apos;LICENSE.GPL&apos; that came with this software distribution. If you did not get the file, send email to info@trolltech.com.&lt;/p&gt;
+&lt;p&gt;The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>EditorPage</name>
+ <message>
+ <source>Source text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <comment>Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog</comment>
+ <message>
+ <source>Fi&amp;nd what:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Find Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Match case</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to search and replace some text in the translations.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace &amp;with:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Replace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to replace the next occurrence of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to replace all occurrences of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to search for some text in the translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Source texts</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translations</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source texts are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translations are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Comments and contexts are searched when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type in the text to search for.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Texts such as &apos;TeX&apos; and &apos;tex&apos; are considered as different when checked.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to find the next occurrence of the text you typed in.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to close this window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MessageEditor</name>
+ <message>
+ <source>bell</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>backspace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>new page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>new line</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>carriage return</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>tab</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases and guesses:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This whole panel allows you to view and edit the translation of some source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This area shows the source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This area shows a comment that may guide you, and the context in which the text occurs.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is where you can enter or modify the translation of some source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Guess</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Guess (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageCurl</name>
+ <message>
+ <source>Next unfinished phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Previous unfinished phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PhraseBookBox</name>
+ <comment>Go to Phrase &gt; Edit Phrase Book... The dialog that pops up is a PhraseBookBox.</comment>
+ <message>
+ <source>S&amp;ource phrase:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translation:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Definition:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;New Phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Remove Phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This window allows you to add, modify, or delete phrases in a phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is the phrase in the source language.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is the phrase in the target language corresponding to the source phrase.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is a definition for the source phrase.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to add the phrase to the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to remove the phrase from the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to save the changes made.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click here to close this window.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot save phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PhraseLV</name>
+ <comment>The phrase list in the right panel of the main window (with Source phrase, Target phrase, and Definition in its header) is a PhraseLV object.</comment>
+ <message>
+ <source>(New Phrase)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This is a list of phrase entries relevant to the source text. Each phrase is supplemented with a suggested translation and a definition.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;p&gt;&lt;u&gt;%1:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%2&lt;/p&gt;&lt;p&gt;&lt;u&gt;%3:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%4&lt;/p&gt;&lt;p&gt;&lt;u&gt;%5:&lt;/u&gt;&amp;nbsp;&amp;nbsp;%6&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Source phrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Definition</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TrWindow</name>
+ <comment>This is the application&apos;s main window.</comment>
+ <message>
+ <source>Context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MOD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This panel lists the source contexts.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This panel lists the source texts. Items that violate validation rules are marked with a warning.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Loading...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 source phrase(s) loaded.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot open &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt translation source (*.ts)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File saved.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot save &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt message files for released applications (*.qm)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Context: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>finished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>unresolved</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>obsolete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing... (page %1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing completed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Printing aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search wrapped.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot find the string &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt phrase books (*.qph)
+All files (*)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create New Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>A file called &apos;%1&apos; already exists. Please choose another name.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrase book created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 phrase(s) loaded.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you want to save &apos;%1&apos;?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Qt Linguist by Trolltech</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No phrase to translate.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No untranslated phrases left.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>V&amp;alidation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Open...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+O</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save &amp;As...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Release...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Print...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+P</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Re&amp;cently opened files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Redo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cu&amp;t</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+V</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+A</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Find...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+F</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Find &amp;Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Replace...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+H</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Prev Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+K</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Next Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+L</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>P&amp;rev</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Shift+K</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ne&amp;xt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Shift+L</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done and &amp;Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Enter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Return</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Begin from Source</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;New Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+N</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Open Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Close Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Edit Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Print Phrase Book...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Accelerators</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Ending Punctuation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Phrase Matches</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Revert Sorting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Display guesses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Vie&amp;ws</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Toolbars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Manual</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;What&apos;s This?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open a Qt translation source file (TS file) for editing.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save changes made to this Qt translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save changes made to this Qt translationsource file into a new file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a Qt message file suitable for released applications from the current message file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print a list of all the phrases in the current Qt translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close this window and exit.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo the last editing operation performed on the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Redo an undone editing operation performed on the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the selected translation text to the clipboard and deletes it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the selected translation text to the clipboard.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Paste the clipboard text into the translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select the whole translation text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for some text in the translation source file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Continue the search where it was left.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for some text in the translation source file and replace it by another text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a new phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open a phrase book to assist translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle validity checks of accelerators.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle validity checks of ending punctuation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toggle checking that phrase suggestions are used.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sort the items back in the same order as in the message file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set whether or not to display translation guesses.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display the manual for %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display information about %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display information about the Qt toolkit by Trolltech.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter What&apos;s This? mode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copies the source text into the translation field.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the next item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the previous item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the next unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Moves to the previous unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Marks this item as done and moves to the next unfinished item.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Validation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open Phrase Book</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Redo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cut</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Find</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Prev</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Prev Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Next Unfinished</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Done and Next</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerators</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Punctuation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Phrases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>What&apos;s This?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot read from phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close this phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Allow you to add, modify, or delete phrases of this phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print the entries of the phrase book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create phrase book &apos;%1&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerator possibly superfluous in translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Accelerator possibly missing in translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translation does not end with the same punctuation as the source text.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>A phrase book suggestion for &apos;%1&apos; was ignored.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tools/linguist/linguist/listviews.cpp b/tools/linguist/linguist/listviews.cpp
new file mode 100644
index 0000000..6bf67fd
--- /dev/null
+++ b/tools/linguist/linguist/listviews.cpp
@@ -0,0 +1,350 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "listviews.h"
+
+#include <qpainter.h>
+
+static const int Text0MaxLen = 150;
+static const int Text1MaxLen = 150;
+
+/*
+ LVI implementation
+*/
+
+static QString rho( int n )
+{
+ QString s;
+ s.sprintf( "%.10d", n );
+ return s;
+}
+
+int LVI::count = 0;
+
+LVI::LVI( QListView * parent, QString text )
+ : QListViewItem( parent, text )
+{
+ setText( 0, rho(count++) );
+}
+
+LVI::LVI( QListViewItem * parent, QString text )
+ : QListViewItem( parent, text )
+{
+ setText( 0, rho(count++) );
+}
+
+/*
+ This is a cut-down version of QListViewItem::paintCell() -
+ it is needed to produce the effect we want on obsolete items
+ */
+void LVI::drawObsoleteText( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align )
+{
+ QListView * lv = listView();
+ int marg = lv ? lv->itemMargin() : 1;
+ int r = marg;
+ p->fillRect( 0, 0, width, height(), cg.brush( QColorGroup::Base ) );
+ if ( isSelected() && (column==0 || listView()->allColumnsShowFocus()) )
+ p->fillRect( r - marg, 0, width - r + marg, height(),
+ cg.brush( QColorGroup::Highlight ) );
+
+ // Do the ellipsis thingy
+ QString t = text( column );
+ QString tmp;
+ int i = 0;
+ if ( p->fontMetrics().width( t ) > width ) {
+ tmp = "...";
+ while ( p->fontMetrics().width( tmp + t[i] ) < width )
+ tmp += t[ i++ ];
+ tmp.remove( (uint)0, 3 );
+ if ( tmp.isEmpty() )
+ tmp = t.left( 1 );
+ tmp += "...";
+ t = tmp;
+ }
+ if ( isSelected() )
+ p->setPen( lv->palette().disabled().highlightedText() );
+ else
+ p->setPen( lv->palette().disabled().text() );
+
+ if ( !t.isEmpty() ) {
+ p->drawText( r, 0, width-marg-r, height(),
+ align | AlignVCenter | SingleLine, t );
+ }
+
+}
+
+int LVI::compare( QListViewItem *other, int column, bool ascending ) const
+{
+ QString thisKey = key( column, ascending );
+ QString otherKey = other->key( column, ascending );
+
+ if ( thisKey.contains('&') || otherKey.contains('&') ) {
+ QString nicerThisKey = thisKey;
+ QString nicerOtherKey = otherKey;
+
+ nicerThisKey.replace( "&", "" );
+ nicerOtherKey.replace( "&", "" );
+
+ int delta = nicerThisKey.localeAwareCompare( nicerOtherKey );
+ if ( delta != 0 )
+ return delta;
+ }
+ return thisKey.localeAwareCompare( otherKey );
+}
+
+static QString fixEllipsis( const QString & str, int len )
+{
+ QString shortened = str.simplifyWhiteSpace();
+ if ( (int) shortened.length() > len ) {
+ QString dots = TrWindow::tr( "..." );
+ shortened.truncate( len - dots.length() );
+ shortened.append( dots );
+ }
+ return shortened;
+}
+
+/*
+ MessageLVI implementation
+*/
+MessageLVI::MessageLVI( QListView *parent,
+ const MetaTranslatorMessage & message,
+ const QString& text, const QString& comment,
+ ContextLVI * c )
+ : LVI( parent ), m( message ), tx( text ), com( comment ), ctxt( c )
+{
+ if ( m.translation().isEmpty() ) {
+ QString t = "";
+ m.setTranslation( t );
+ }
+ setText( 1, fixEllipsis( text, Text0MaxLen ) );
+ fini = TRUE;
+ d = FALSE;
+
+ if( m.type() == MetaTranslatorMessage::Unfinished )
+ setFinished( FALSE );
+}
+
+void MessageLVI::updateTranslationText()
+{
+ setText( 2, fixEllipsis( m.translation(), Text1MaxLen ) );
+}
+
+void MessageLVI::paintCell( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align )
+{
+ if ( column == 0 ) {
+ int x = (width/2) - TrWindow::pxOn->width()/2;
+ int y = (height()/2) - TrWindow::pxOn->height()/2;
+
+ int marg = listView() ? listView()->itemMargin() : 1;
+ int r = marg;
+
+ if ( isSelected() )
+ p->fillRect( r - marg, 0, width - r + marg, height(),
+ cg.brush( QColorGroup::Highlight ) );
+ else
+ p->fillRect( 0, 0, width, height(),
+ cg.brush( QColorGroup::Base ) );
+
+ if ( m.type() == MetaTranslatorMessage::Unfinished && danger() )
+ p->drawPixmap( x, y, *TrWindow::pxDanger );
+ else if ( m.type() == MetaTranslatorMessage::Finished )
+ p->drawPixmap( x, y, *TrWindow::pxOn );
+ else if ( m.type() == MetaTranslatorMessage::Unfinished )
+ p->drawPixmap( x, y, *TrWindow::pxOff );
+ else if ( m.type() == MetaTranslatorMessage::Obsolete )
+ p->drawPixmap( x, y, *TrWindow::pxObsolete );
+ } else {
+ if ( m.type() == MetaTranslatorMessage::Obsolete )
+ drawObsoleteText( p, cg, column, width, align );
+ else
+ QListViewItem::paintCell( p, cg, column, width, align );
+ }
+}
+
+
+void MessageLVI::setTranslation( const QString& translation )
+{
+ m.setTranslation( translation );
+}
+
+void MessageLVI::setFinished( bool finished )
+{
+ if ( !fini && finished ) {
+ m.setType( MetaTranslatorMessage::Finished );
+ repaint();
+ ctxt->decrementUnfinishedCount();
+ } else if ( fini && !finished ) {
+ m.setType( MetaTranslatorMessage::Unfinished );
+ repaint();
+ ctxt->incrementUnfinishedCount();
+ }
+ fini = finished;
+}
+
+void MessageLVI::setDanger( bool danger )
+{
+ if ( !d && danger ) {
+ ctxt->incrementDangerCount();
+ repaint();
+ } else if ( d && !danger ) {
+ ctxt->decrementDangerCount();
+ repaint();
+ }
+ d = danger;
+}
+
+QString MessageLVI::context() const
+{
+ return QString( m.context() );
+}
+
+MetaTranslatorMessage MessageLVI::message() const
+{
+ return m;
+}
+
+/*
+ ContextLVI implementation
+*/
+ContextLVI::ContextLVI( QListView *lv, const QString& context )
+ : LVI( lv ), com( "" )
+{
+ messageItems.setAutoDelete( TRUE );
+
+ unfinishedCount = 0;
+ dangerCount = 0;
+ obsoleteCount = 0;
+ itemCount = 0;
+ setText( 1, context );
+}
+
+void ContextLVI::instantiateMessageItem( QListView * lv, MessageLVI * i )
+{
+ itemCount++;
+ appendMessageItem( lv, i );
+}
+
+void ContextLVI::appendMessageItem( QListView * lv, MessageLVI * i )
+{
+ lv->takeItem( i );
+ messageItems.append( i );
+}
+
+void ContextLVI::updateStatus()
+{
+ QString s;
+ s.sprintf( "%d/%d", itemCount - unfinishedCount - obsoleteCount,
+ itemCount - obsoleteCount );
+ setText( 2, s );
+}
+
+void ContextLVI::paintCell( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align )
+{
+ if ( column == 0 ) {
+ int x = (width/2) - TrWindow::pxOn->width()/2;
+ int y = (height()/2) - TrWindow::pxOn->height()/2;
+
+ int marg = listView() ? listView()->itemMargin() : 1;
+ int r = marg;
+
+ if ( isSelected() )
+ p->fillRect( r - marg, 0, width - r + marg, height(),
+ cg.brush( QColorGroup::Highlight ) );
+ else
+ p->fillRect( 0, 0, width, height(),
+ cg.brush( QColorGroup::Base ) );
+
+ if ( isContextObsolete() )
+ p->drawPixmap( x, y, *TrWindow::pxObsolete );
+ else if ( unfinishedCount == 0 )
+ p->drawPixmap( x, y, *TrWindow::pxOn );
+ else
+ p->drawPixmap( x, y, *TrWindow::pxOff );
+
+ } else {
+ if ( isContextObsolete() )
+ drawObsoleteText( p, cg, column, width, align );
+ else
+ QListViewItem::paintCell( p, cg, column, width, align );
+ }
+}
+
+void ContextLVI::appendToComment( const QString& x )
+{
+ if ( !com.isEmpty() )
+ com += QString( "\n\n" );
+ com += x;
+}
+
+void ContextLVI::incrementUnfinishedCount()
+{
+ if ( unfinishedCount++ == 0 )
+ repaint();
+}
+
+void ContextLVI::decrementUnfinishedCount()
+{
+ if ( --unfinishedCount == 0 )
+ repaint();
+}
+
+void ContextLVI::incrementDangerCount()
+{
+ if ( dangerCount++ == 0 )
+ repaint();
+}
+
+void ContextLVI::decrementDangerCount()
+{
+ if ( --dangerCount == 0 )
+ repaint();
+}
+
+void ContextLVI::incrementObsoleteCount()
+{
+ if ( obsoleteCount++ == 0 )
+ repaint();
+}
+
+bool ContextLVI::isContextObsolete()
+{
+ return (obsoleteCount == itemCount);
+}
+
+QString ContextLVI::fullContext() const
+{
+ return comment().stripWhiteSpace();
+}
diff --git a/tools/linguist/linguist/listviews.h b/tools/linguist/linguist/listviews.h
new file mode 100644
index 0000000..f843aa3
--- /dev/null
+++ b/tools/linguist/linguist/listviews.h
@@ -0,0 +1,135 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef LISTVIEWS_H
+#define LISTVIEWS_H
+
+#include "msgedit.h"
+
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qregexp.h>
+#include <qlistview.h>
+
+class LVI : public QListViewItem
+{
+public:
+ LVI( QListView *parent, QString text = QString::null );
+ LVI( QListViewItem *parent, QString text = QString::null );
+ virtual int compare( QListViewItem *other, int column,
+ bool ascending ) const;
+ virtual bool danger() const { return FALSE; }
+
+protected:
+ void drawObsoleteText( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align );
+
+private:
+ static int count;
+};
+
+class MessageLVI;
+class ContextLVI : public LVI
+{
+public:
+ ContextLVI( QListView *lv, const QString& context );
+
+ virtual bool danger() const { return dangerCount > 0; }
+
+ void appendToComment( const QString& x );
+ void incrementUnfinishedCount();
+ void decrementUnfinishedCount();
+ void incrementDangerCount();
+ void decrementDangerCount();
+ void incrementObsoleteCount();
+ bool isContextObsolete();
+ void updateStatus();
+
+ QString context() const { return text( 1 ); }
+ QString comment() const { return com; }
+ QString fullContext() const;
+ bool finished() const { return unfinishedCount == 0; }
+
+ MessageLVI * firstMessageItem() { return messageItems.first(); }
+ MessageLVI * nextMessageItem() { return messageItems.next(); }
+ MessageLVI * takeMessageItem( int i ) { return messageItems.take( i ); }
+ void appendMessageItem( QListView * lv, MessageLVI * i );
+ void instantiateMessageItem( QListView * lv, MessageLVI * i );
+ int messageItemsInList() { return messageItems.count(); }
+
+ void paintCell( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align );
+private:
+ QPtrList<MessageLVI> messageItems;
+ QString com;
+ int unfinishedCount;
+ int dangerCount;
+ int obsoleteCount;
+ int itemCount;
+};
+
+class MessageLVI : public LVI
+{
+public:
+ MessageLVI( QListView *parent, const MetaTranslatorMessage & message,
+ const QString& text, const QString& comment, ContextLVI * c );
+
+ virtual bool danger() const { return d; }
+
+ void setTranslation( const QString& translation );
+ void setFinished( bool finished );
+ void setDanger( bool danger );
+
+ void setContextLVI( ContextLVI * c ) { ctxt = c; }
+ ContextLVI * contextLVI() const { return ctxt; }
+ void updateTranslationText();
+
+ QString context() const;
+ QString sourceText() const { return tx; }
+ QString comment() const { return com; }
+ QString translation() const { return m.translation(); }
+ bool finished() const { return fini; }
+ MetaTranslatorMessage message() const;
+
+ void paintCell( QPainter * p, const QColorGroup & cg, int column,
+ int width, int align );
+private:
+ MetaTranslatorMessage m;
+ QString tx;
+ QString com;
+ bool fini;
+ bool d;
+ ContextLVI * ctxt;
+};
+
+#endif
diff --git a/tools/linguist/linguist/main.cpp b/tools/linguist/linguist/main.cpp
new file mode 100644
index 0000000..e9490af
--- /dev/null
+++ b/tools/linguist/linguist/main.cpp
@@ -0,0 +1,89 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "trwindow.h"
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qtextcodec.h>
+#include <qtranslator.h>
+#include <qsettings.h>
+#include <qsplashscreen.h>
+
+int main( int argc, char **argv )
+{
+ QApplication app( argc, argv );
+ QApplication::setOverrideCursor( Qt::waitCursor );
+
+
+ QTranslator translator( 0 );
+ translator.load( QString( "linguist_" ) + QTextCodec::locale(), "." );
+ app.installTranslator( &translator );
+
+ bool showSplash = TRUE;
+
+ QString keybase("/Qt Linguist/3.1/");
+ QSettings config;
+ config.insertSearchPath( QSettings::Windows, "/Trolltech" );
+
+ QRect r( QApplication::desktop()->screenGeometry() );
+ r.setX( config.readNumEntry( keybase + "Geometry/MainwindowX", r.x() ) );
+ r.setY( config.readNumEntry( keybase + "Geometry/MainwindowY", r.y() ) );
+ r.setWidth( config.readNumEntry( keybase + "Geometry/MainwindowWidth", r.width() ) );
+ r.setHeight( config.readNumEntry( keybase + "Geometry/MainwindowHeight", r.height() ) );
+
+ QSplashScreen *splash = 0;
+ if ( showSplash ) {
+ splash = new QSplashScreen( QPixmap::fromMimeSource("splash.png"),
+ Qt::WDestructiveClose );
+ splash->show();
+ }
+
+ TrWindow *tw = new TrWindow;
+ app.setMainWidget( tw );
+
+ if ( app.argc() > 1 )
+ tw->openFile( QString(app.argv()[app.argc() - 1]) );
+
+ if ( config.readBoolEntry( keybase + "Geometry/MainwindowMaximized", FALSE ) )
+ tw->showMaximized();
+ else
+ tw->show();
+ if ( splash )
+ splash->finish( tw );
+ QApplication::restoreOverrideCursor();
+
+ return app.exec();
+}
diff --git a/tools/linguist/linguist/msgedit.cpp b/tools/linguist/linguist/msgedit.cpp
new file mode 100644
index 0000000..09e60a1
--- /dev/null
+++ b/tools/linguist/linguist/msgedit.cpp
@@ -0,0 +1,834 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* TRANSLATOR MsgEdit
+
+ This is the right panel of the main window.
+*/
+
+#include "msgedit.h"
+
+#include "trwindow.h"
+#include "phraselv.h"
+#include "simtexth.h"
+
+#include <qapplication.h>
+#include <qcheckbox.h>
+#include <qclipboard.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtextedit.h>
+#include <qpalette.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qtextview.h>
+#include <qwhatsthis.h>
+#include <qvbox.h>
+#include <qmainwindow.h>
+#include <qheader.h>
+#include <qregexp.h>
+#include <qdockarea.h>
+#include <qdockwindow.h>
+#include <qscrollview.h>
+#include <qfont.h>
+#include <qaccel.h>
+#include <private/qrichtext_p.h>
+
+static const int MaxCandidates = 5;
+
+class MED : public QTextEdit
+{
+public:
+ MED( QWidget *parent, const char *name = 0 )
+ : QTextEdit( parent, name ) {}
+
+ int cursorX() const { return textCursor()->x(); }
+ int cursorY() const { return textCursor()->paragraph()->rect().y() +
+ textCursor()->y(); }
+};
+
+
+QString richMeta( const QString& text )
+{
+ return QString( "<small><font color=blue>(" ) + text +
+ QString( ")</font></small>" );
+}
+
+QString richText( const QString& text )
+{
+ const char backTab[] = "\a\b\f\n\r\t";
+ const char * const friendlyBackTab[] = {
+ QT_TRANSLATE_NOOP( "MessageEditor", "bell" ),
+ QT_TRANSLATE_NOOP( "MessageEditor", "backspace" ),
+ QT_TRANSLATE_NOOP( "MessageEditor", "new page" ),
+ QT_TRANSLATE_NOOP( "MessageEditor", "new line" ),
+ QT_TRANSLATE_NOOP( "MessageEditor", "carriage return" ),
+ QT_TRANSLATE_NOOP( "MessageEditor", "tab" )
+ };
+ QString rich;
+
+ for ( int i = 0; i < (int) text.length(); i++ ) {
+ int ch = text[i].unicode();
+
+ if ( ch < 0x20 ) {
+ const char *p = strchr( backTab, ch );
+ if ( p == 0 )
+ rich += richMeta( QString::number(ch, 16) );
+ else
+ rich += richMeta( MessageEditor::tr(friendlyBackTab[p - backTab]) );
+ } else if ( ch == '<' ) {
+ rich += QString( "&lt;" );
+ } else if ( ch == '>' ) {
+ rich += QString( "&gt;" );
+ } else if ( ch == '&' ) {
+ rich += QString( "&amp;" );
+ } else if ( ch == ' ' ) {
+ if ( i == 0 || i == (text.length()-1) || text[i - 1] == ' ' || text[i + 1] == ' ' ) {
+ rich += richMeta( MessageEditor::tr("sp") );
+ } else {
+ rich += ' ';
+ }
+ } else {
+ rich += QChar( ch );
+ }
+ if ( ch == '\n' )
+ rich += QString( "<br>" );
+ }
+ return rich;
+}
+
+/*
+ ShadowWidget class impl.
+
+ Used to create a shadow like effect for a widget
+*/
+ShadowWidget::ShadowWidget( QWidget * parent, const char * name )
+ : QWidget( parent, name ), sWidth( 10 ), wMargin( 3 ), childWgt( 0 )
+{
+}
+
+ShadowWidget::ShadowWidget( QWidget * child, QWidget * parent,
+ const char * name )
+ : QWidget( parent, name ), sWidth( 10 ), wMargin( 3 ), childWgt( 0 )
+{
+ setWidget( child );
+}
+
+void ShadowWidget::setWidget( QWidget * child )
+{
+ childWgt = child;
+ if ( childWgt && childWgt->parent() != this ) {
+ childWgt->reparent( this, QPoint( 0, 0 ), TRUE );
+ }
+}
+
+void ShadowWidget::resizeEvent( QResizeEvent * )
+{
+ if( childWgt ) {
+ childWgt->move( wMargin, wMargin );
+ childWgt->resize( width() - sWidth - wMargin, height() - sWidth -
+ wMargin );
+ }
+}
+
+void ShadowWidget::paintEvent( QPaintEvent * e )
+{
+ QPainter p;
+ int w = width() - sWidth;
+ int h = height() - sWidth;
+
+
+ if ( !((w > 0) && (h > 0)) )
+ return;
+
+ if ( p.begin( this ) ) {
+ p.setPen( colorGroup().shadow() );
+
+ p.drawPoint( w + 5, 6 );
+ p.drawLine( w + 3, 6, w + 5, 8 );
+ p.drawLine( w + 1, 6, w + 5, 10 );
+ int i;
+ for( i=7; i < h; i += 2 )
+ p.drawLine( w, i, w + 5, i + 5 );
+ for( i = w - i + h; i > 6; i -= 2 )
+ p.drawLine( i, h, i + 5, h + 5 );
+ for( ; i > 0 ; i -= 2 )
+ p.drawLine( 6, h + 6 - i, i + 5, h + 5 );
+
+// p.eraseRect( w, 0, sWidth, 45 ); // Cheap hack for the page curl..
+ p.end();
+ }
+ QWidget::paintEvent( e );
+}
+
+/*
+ EditorPage class impl.
+
+ A frame that contains the source text, translated text and any
+ source code comments and hints.
+*/
+EditorPage::EditorPage( QWidget * parent, const char * name )
+ : QFrame( parent, name )
+{
+ setLineWidth( 1 );
+ setFrameStyle( QFrame::Box | QFrame::Plain );
+
+ // Use white explicitly as the background color for the editor page.
+ QPalette p = palette();
+ p.setColor( QPalette::Active, QColorGroup::Base, QColor( white ) );
+ p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( white ) );
+ p.setColor( QPalette::Disabled, QColorGroup::Base, QColor( white ) );
+ p.setColor( QPalette::Active, QColorGroup::Background,
+ p.active().color( QColorGroup::Base ) );
+ p.setColor( QPalette::Inactive, QColorGroup::Background,
+ p.inactive().color( QColorGroup::Base ) );
+ p.setColor( QPalette::Disabled, QColorGroup::Background,
+ p.disabled().color( QColorGroup::Base ) );
+ setPalette( p );
+
+ srcTextLbl = new QLabel( tr("Source text"), this, "source text label" );
+ transLbl = new QLabel( tr("Translation"), this, "translation label" );
+
+ QFont fnt = font();
+ fnt.setBold( TRUE );
+ srcTextLbl->setFont( fnt );
+ transLbl->setFont( fnt );
+
+ srcText = new QTextView( this, "source text view" );
+ srcText->setFrameStyle( QFrame::NoFrame );
+ srcText->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
+ QSizePolicy::Minimum ) );
+ srcText->setResizePolicy( QScrollView::AutoOne );
+ srcText->setHScrollBarMode( QScrollView::AlwaysOff );
+ srcText->setVScrollBarMode( QScrollView::AlwaysOff );
+ p = srcText->palette();
+ p.setColor( QPalette::Disabled, QColorGroup::Base, p.active().base() );
+ srcText->setPalette( p );
+ connect( srcText, SIGNAL(textChanged()), SLOT(handleSourceChanges()) );
+
+ cmtText = new QTextView( this, "comment/context view" );
+ cmtText->setFrameStyle( QFrame::NoFrame );
+ cmtText->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
+ QSizePolicy::Minimum ) );
+ cmtText->setResizePolicy( QScrollView::AutoOne );
+ cmtText->setHScrollBarMode( QScrollView::AlwaysOff );
+ cmtText->setVScrollBarMode( QScrollView::AlwaysOff );
+ p = cmtText->palette();
+ p.setColor( QPalette::Active, QColorGroup::Base, QColor( 236,245,255 ) );
+ p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( 236,245,255 ) );
+ cmtText->setPalette( p );
+ connect( cmtText, SIGNAL(textChanged()), SLOT(handleCommentChanges()) );
+
+ translationMed = new MED( this, "translation editor" );
+ translationMed->setFrameStyle( QFrame::NoFrame );
+ translationMed->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
+ QSizePolicy::MinimumExpanding ) );
+ translationMed->setHScrollBarMode( QScrollView::AlwaysOff );
+ translationMed->setVScrollBarMode( QScrollView::AlwaysOff );
+ translationMed->setResizePolicy( QScrollView::AutoOne );
+ translationMed->setWrapPolicy( QTextView::AtWhiteSpace );
+ translationMed->setWordWrap( QTextView::WidgetWidth );
+ translationMed->setTextFormat( QTextView::PlainText );
+ p = translationMed->palette();
+ p.setColor( QPalette::Disabled, QColorGroup::Base, p.active().base() );
+ translationMed->setPalette( p );
+ connect( translationMed, SIGNAL(textChanged()),
+ SLOT(handleTranslationChanges()) );
+
+ pageCurl = new PageCurl( this, "page curl" );
+
+ // Focus
+ setFocusPolicy( StrongFocus );
+ transLbl->setFocusProxy( translationMed );
+ srcTextLbl->setFocusProxy( translationMed );
+ cmtText->setFocusProxy( translationMed );
+ srcText->setFocusProxy( translationMed );
+ setFocusProxy( translationMed );
+
+ updateCommentField();
+}
+
+/*
+ Don't show the comment field if there are no comments.
+*/
+void EditorPage::updateCommentField()
+{
+ if( cmtText->text().isEmpty() )
+ cmtText->hide();
+ else
+ cmtText->show();
+
+ layoutWidgets();
+}
+
+/*
+ Handle the widget layout manually
+*/
+void EditorPage::layoutWidgets()
+ {
+ int margin = 6;
+ int space = 2;
+ int w = width();
+
+ pageCurl->move( width() - pageCurl->width(), 0 );
+
+ QFontMetrics fm( srcTextLbl->font() );
+ srcTextLbl->move( margin, margin );
+ srcTextLbl->resize( fm.width( srcTextLbl->text() ), srcTextLbl->height() );
+
+ srcText->move( margin, srcTextLbl->y() + srcTextLbl->height() + space );
+ srcText->resize( w - margin*2, srcText->height() );
+
+ cmtText->move( margin, srcText->y() + srcText->height() + space );
+ cmtText->resize( w - margin*2, cmtText->height() );
+
+ if( cmtText->isHidden() )
+ transLbl->move( margin, srcText->y() + srcText->height() + space );
+ else
+ transLbl->move( margin, cmtText->y() + cmtText->height() + space );
+ transLbl->resize( w - margin*2, transLbl->height() );
+
+ translationMed->move( margin, transLbl->y() + transLbl->height() + space );
+ translationMed->resize( w - margin*2, translationMed->height() );
+
+ // Calculate the total height for the editor page - emit a signal
+ // if the actual page size is larger/smaller
+ int totHeight = margin + srcTextLbl->height() +
+ srcText->height() + space +
+ transLbl->height() + space +
+ translationMed->height() + space +
+ frameWidth()*lineWidth()*2 + space * 3;
+
+ if( !cmtText->isHidden() )
+ totHeight += cmtText->height() + space;
+
+ if( height() != totHeight )
+ emit pageHeightUpdated( totHeight );
+}
+
+void EditorPage::resizeEvent( QResizeEvent * )
+{
+ handleTranslationChanges();
+ handleSourceChanges();
+ handleCommentChanges();
+ layoutWidgets();
+}
+
+void EditorPage::handleTranslationChanges()
+{
+ calculateFieldHeight( (QTextView *) translationMed );
+}
+
+void EditorPage::handleSourceChanges()
+{
+ calculateFieldHeight( srcText );
+}
+
+void EditorPage::handleCommentChanges()
+{
+ calculateFieldHeight( cmtText );
+}
+
+/*
+ Check if the translation text field is big enough to show all text
+ that has been entered. If it isn't, resize it.
+*/
+void EditorPage::calculateFieldHeight( QTextView * field )
+{
+ field->sync(); // make sure the text formatting is done!
+ int contentsHeight = field->contentsHeight();
+
+ if( contentsHeight != field->height() ) {
+ int oldHeight = field->height();
+ if( contentsHeight < 30 )
+ contentsHeight = 30;
+ field->resize( field->width(), contentsHeight );
+ emit pageHeightUpdated( height() + (field->height() - oldHeight) );
+ }
+}
+
+void EditorPage::fontChange( const QFont & )
+{
+ QFont fnt = font();
+
+ fnt.setBold( TRUE );
+ QFontMetrics fm( fnt );
+ srcTextLbl->setFont( fnt );
+ srcTextLbl->resize( fm.width( srcTextLbl->text() ), srcTextLbl->height() );
+ transLbl->setFont( fnt );
+ transLbl->resize( fm.width( transLbl->text() ), transLbl->height() );
+ update();
+}
+
+/*
+ MessageEditor class impl.
+
+ Handle layout of dock windows and the editor page.
+*/
+MessageEditor::MessageEditor( MetaTranslator * t, QWidget * parent,
+ const char * name )
+ : QWidget( parent, name ),
+ tor( t )
+{
+ doGuesses = TRUE;
+ v = new QVBoxLayout( this );
+ topDock = new QDockArea( Qt::Horizontal, QDockArea::Normal, this,
+ "top dock area" );
+ topDock->setMinimumHeight( 10 );
+ topDock->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
+ QSizePolicy::Minimum) );
+
+ topDockWnd = new QDockWindow( QDockWindow::InDock, topDock,
+ "top dock window" );
+ QMainWindow *mw = (QMainWindow*)topLevelWidget();
+ if ( mw ) {
+ mw->setDockEnabled( topDockWnd, Qt::DockTop, TRUE );
+ mw->setDockEnabled( topDockWnd, Qt::DockLeft, TRUE );
+ mw->setDockEnabled( topDockWnd, Qt::DockRight, TRUE );
+ mw->setDockEnabled( topDockWnd, Qt::DockBottom, TRUE );
+ }
+
+ topDockWnd->setCaption( tr("Source text") );
+ topDockWnd->setCloseMode( QDockWindow::Always );
+ topDockWnd->setResizeEnabled( TRUE );
+ topDockWnd->setFixedExtentHeight( 110 );
+
+ srcTextList = new QListView( topDockWnd, "source text list view" );
+ srcTextList->setShowSortIndicator( TRUE );
+ srcTextList->setAllColumnsShowFocus( TRUE );
+ srcTextList->setSorting( 0 );
+ QFontMetrics fm( font() );
+ srcTextList->addColumn( tr("Done"), fm.width( tr("Done") ) + 10 );
+ srcTextList->addColumn( tr("Source text") );
+ srcTextList->addColumn( tr("Translation"), 300 );
+ srcTextList->setColumnAlignment( 0, Qt::AlignCenter );
+ srcTextList->setColumnWidthMode( 1, QListView::Manual );
+ srcTextList->header()->setStretchEnabled( TRUE, 1 );
+ srcTextList->setMinimumSize( QSize( 50, 50 ) );
+ srcTextList->setHScrollBarMode( QScrollView::AlwaysOff );
+ srcTextList->installEventFilter( this );
+ topDockWnd->setWidget( srcTextList );
+
+ sv = new QScrollView( this, "scroll view" );
+ sv->setHScrollBarMode( QScrollView::AlwaysOff );
+ sv->viewport()->setBackgroundMode( PaletteBackground );
+
+ editorPage = new EditorPage( sv, "editor page" );
+ connect( editorPage, SIGNAL(pageHeightUpdated(int)),
+ SLOT(updatePageHeight(int)) );
+
+ editorPage->translationMed->installEventFilter( this );
+
+ sw = new ShadowWidget( editorPage, sv, "editor page shadow" );
+ sw->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
+ QSizePolicy::Expanding) );
+ sw->setMinimumSize( QSize( 100, 150 ) );
+ sv->addChild( sw );
+
+ bottomDock = new QDockArea( Qt::Horizontal, QDockArea::Reverse,
+ this, "bottom dock area" );
+ bottomDock->setMinimumHeight( 10 );
+ bottomDock->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
+ QSizePolicy::Minimum) );
+ bottomDockWnd = new QDockWindow( QDockWindow::InDock, bottomDock,
+ "bottom dock window" );
+ if ( mw ) {
+ mw->setDockEnabled( bottomDockWnd, Qt::DockTop, TRUE );
+ mw->setDockEnabled( bottomDockWnd, Qt::DockLeft, TRUE );
+ mw->setDockEnabled( bottomDockWnd, Qt::DockRight, TRUE );
+ mw->setDockEnabled( bottomDockWnd, Qt::DockBottom, TRUE );
+ }
+ bottomDockWnd->setCaption( tr("Phrases") );
+ bottomDockWnd->setCloseMode( QDockWindow::Always );
+ bottomDockWnd->setResizeEnabled( TRUE );
+
+ QWidget * w = new QWidget( bottomDockWnd );
+ w->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
+ QSizePolicy::Minimum ) );
+ QHBoxLayout *hl = new QHBoxLayout( w, 6 );
+ QVBoxLayout *vl = new QVBoxLayout( 6 );
+
+ phraseLbl = new QLabel( tr("Phrases and guesses:"), w );
+ phraseLv = new PhraseLV( w, "phrase list view" );
+ phraseLv->setSorting( PhraseLVI::DefinitionText );
+ phraseLv->installEventFilter( this );
+ hl->addLayout( vl );
+ vl->addWidget( phraseLbl );
+ vl->addWidget( phraseLv );
+
+ accel = new QAccel( this, "accel" );
+ connect( accel, SIGNAL(activated(int)), this, SLOT(guessActivated(int)) );
+ for ( int i = 0; i < 9; i++ )
+ accel->insertItem( CTRL + (Key_1 + i), i + 1 );
+
+ bottomDockWnd->setWidget( w );
+
+ v->addWidget( topDock );
+ v->addWidget( sv );
+ v->addWidget( bottomDock );
+
+ // Signals
+ connect( editorPage->pageCurl, SIGNAL(nextPage()),
+ SIGNAL(nextUnfinished()) );
+ connect( editorPage->pageCurl, SIGNAL(prevPage()),
+ SIGNAL(prevUnfinished()) );
+
+ connect( editorPage->translationMed, SIGNAL(textChanged()),
+ this, SLOT(emitTranslationChanged()) );
+ connect( editorPage->translationMed, SIGNAL(textChanged()),
+ this, SLOT(updateButtons()) );
+ connect( editorPage->translationMed, SIGNAL(undoAvailable(bool)),
+ this, SIGNAL(undoAvailable(bool)) );
+ connect( editorPage->translationMed, SIGNAL(redoAvailable(bool)),
+ this, SIGNAL(redoAvailable(bool)) );
+ connect( editorPage->translationMed, SIGNAL(copyAvailable(bool)),
+ this, SIGNAL(cutAvailable(bool)) );
+ connect( editorPage->translationMed, SIGNAL(copyAvailable(bool)),
+ this, SIGNAL(copyAvailable(bool)) );
+ connect( qApp->clipboard(), SIGNAL(dataChanged()),
+ this, SLOT(updateCanPaste()) );
+ connect( phraseLv, SIGNAL(doubleClicked(QListViewItem *)),
+ this, SLOT(insertPhraseInTranslation(QListViewItem *)) );
+ connect( phraseLv, SIGNAL(returnPressed(QListViewItem *)),
+ this, SLOT(insertPhraseInTranslationAndLeave(QListViewItem *)) );
+
+ // What's this
+ QWhatsThis::add( this, tr("This whole panel allows you to view and edit "
+ "the translation of some source text.") );
+ QWhatsThis::add( editorPage->srcText,
+ tr("This area shows the source text.") );
+ QWhatsThis::add( editorPage->cmtText, tr("This area shows a comment that"
+ " may guide you, and the context in which the text"
+ " occurs.") );
+ QWhatsThis::add( editorPage->translationMed,
+ tr("This is where you can enter or modify"
+ " the translation of some source text.") );
+}
+
+void MessageEditor::toggleFinished()
+{
+ if ( itemFinished )
+ itemFinished = FALSE;
+ else
+ itemFinished = TRUE;
+ emit finished( itemFinished );
+}
+
+bool MessageEditor::eventFilter( QObject *o, QEvent *e )
+{
+ // Handle keypresses in the message editor - scroll the view if the current
+ // line is hidden.
+ if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
+ QKeyEvent * ke = (QKeyEvent*)e;
+ const int k = ke->key();
+
+ if ( ::qt_cast<QTextEdit*>(o) ) {
+ if ( e->type() == QEvent::KeyPress ) {
+ // Hardcode the Tab key to do focus changes when pressed
+ // inside the editor
+ if ( k == Key_BackTab ) {
+ emit focusSourceList();
+ return TRUE;
+ }
+ } else if ( e->type() == QEvent::KeyRelease ) {
+ MED * ed = (MED *) o;
+ switch( k ) {
+ case Key_Up:
+ if (ed->cursorY() < 10)
+ sv->verticalScrollBar()->subtractLine();
+ break;
+
+ case Key_Down:
+ if (ed->cursorY() >= ed->height() - 20)
+ sv->verticalScrollBar()->addLine();
+ break;
+
+ case Key_PageUp:
+ if (ed->cursorY() < 10)
+ sv->verticalScrollBar()->subtractPage();
+ break;
+
+ case Key_PageDown:
+ if (ed->cursorY() >= ed->height() - 50)
+ sv->verticalScrollBar()->addPage();
+ break;
+ default:
+ sv->ensureVisible( sw->margin() + ed->x() + ed->cursorX(),
+ sw->margin() + ed->y() + ed->cursorY() );
+ break;
+ }
+ }
+ } else if ( ::qt_cast<QListView*>(o) ) {
+ // handle the ESC key in the list views
+ if ( e->type() == QEvent::KeyRelease && k == Key_Escape )
+ editorPage->translationMed->setFocus();
+ }
+ }
+ return QWidget::eventFilter( o, e );
+}
+
+void MessageEditor::updatePageHeight( int height )
+{
+ sw->resize( sw->width(), height + sw->margin() + sw->shadowWidth() );
+}
+
+void MessageEditor::resizeEvent( QResizeEvent * )
+{
+ sw->resize( sv->viewport()->width(), sw->height() );
+}
+
+QListView * MessageEditor::sourceTextList() const
+{
+ return srcTextList;
+}
+
+QListView * MessageEditor::phraseList() const
+{
+ return phraseLv;
+}
+
+void MessageEditor::showNothing()
+{
+ editorPage->srcText->setText( "" );
+ showContext( QString(""), FALSE );
+}
+
+void MessageEditor::showContext( const QString& context, bool finished )
+{
+ setEditionEnabled( FALSE );
+ sourceText = QString::null;
+ guesses.clear();
+
+ if( context.isEmpty() )
+ editorPage->cmtText->setText("");
+ else
+ editorPage->cmtText->setText( richText(context.simplifyWhiteSpace()) );
+ setTranslation( QString(""), FALSE );
+ setFinished( finished );
+ phraseLv->clear();
+ editorPage->handleSourceChanges();
+ editorPage->handleCommentChanges();
+ editorPage->handleTranslationChanges();
+ editorPage->updateCommentField();
+}
+
+void MessageEditor::showMessage( const QString& text,
+ const QString& comment,
+ const QString& fullContext,
+ const QString& translation,
+ MetaTranslatorMessage::Type type,
+ const QValueList<Phrase>& phrases )
+{
+ bool obsolete = ( type == MetaTranslatorMessage::Obsolete );
+ setEditionEnabled( !obsolete );
+ sourceText = text;
+ guesses.clear();
+
+ editorPage->srcText->setText( QString("<p>") + richText( text ) +
+ QString("</p>") );
+
+ if ( !fullContext.isEmpty() && !comment.isEmpty() )
+ editorPage->cmtText->setText( richText(fullContext.simplifyWhiteSpace()) +
+ "\n" + richText(comment.simplifyWhiteSpace()) );
+ else if ( !fullContext.isEmpty() && comment.isEmpty() )
+ editorPage->cmtText->setText(richText(fullContext.simplifyWhiteSpace() ) );
+ else if ( fullContext.isEmpty() && !comment.isEmpty() )
+ editorPage->cmtText->setText( richText(comment.simplifyWhiteSpace() ) );
+ else
+ editorPage->cmtText->setText( "" );
+
+ setTranslation( translation, FALSE );
+ setFinished( type != MetaTranslatorMessage::Unfinished );
+ QValueList<Phrase>::ConstIterator p;
+ phraseLv->clear();
+ for ( p = phrases.begin(); p != phrases.end(); ++p )
+ (void) new PhraseLVI( phraseLv, *p );
+
+ if ( doGuesses && !sourceText.isEmpty() ) {
+ CandidateList cl = similarTextHeuristicCandidates( tor,
+ sourceText.latin1(),
+ MaxCandidates );
+ int n = 0;
+ QValueList<Candidate>::Iterator it = cl.begin();
+ while ( it != cl.end() ) {
+ QString def;
+ if ( n < 9 )
+ def = tr( "Guess (%1)" ).arg( QString(QKeySequence(CTRL | (Key_0 + (n + 1)))) );
+ else
+ def = tr( "Guess" );
+ (void) new PhraseLVI( phraseLv,
+ Phrase((*it).source, (*it).target, def),
+ n + 1 );
+ n++;
+ ++it;
+ }
+ }
+ editorPage->handleSourceChanges();
+ editorPage->handleCommentChanges();
+ editorPage->handleTranslationChanges();
+ editorPage->updateCommentField();
+}
+
+void MessageEditor::setTranslation( const QString& translation, bool emitt )
+{
+ // Block signals so that 'textChanged()' is not emitted when
+ // for example a new source text item is selected and *not*
+ // the actual translation.
+ editorPage->translationMed->blockSignals( !emitt );
+ editorPage->translationMed->setText( translation );
+ editorPage->translationMed->blockSignals( FALSE );
+ if ( !emitt )
+ updateButtons();
+ emit cutAvailable( FALSE );
+ emit copyAvailable( FALSE );
+}
+
+void MessageEditor::setEditionEnabled( bool enabled )
+{
+ editorPage->transLbl->setEnabled( enabled );
+ editorPage->translationMed->setReadOnly( !enabled );
+
+ phraseLbl->setEnabled( enabled );
+ phraseLv->setEnabled( enabled );
+ updateCanPaste();
+}
+
+void MessageEditor::undo()
+{
+ editorPage->translationMed->undo();
+}
+
+void MessageEditor::redo()
+{
+ editorPage->translationMed->redo();
+}
+
+void MessageEditor::cut()
+{
+ editorPage->translationMed->cut();
+}
+
+void MessageEditor::copy()
+{
+ editorPage->translationMed->copy();
+}
+
+void MessageEditor::paste()
+{
+ editorPage->translationMed->paste();
+}
+
+void MessageEditor::del()
+{
+ editorPage->translationMed->del();
+}
+
+void MessageEditor::selectAll()
+{
+ editorPage->translationMed->selectAll();
+}
+
+void MessageEditor::emitTranslationChanged()
+{
+ emit translationChanged( editorPage->translationMed->text() );
+}
+
+void MessageEditor::guessActivated( int accelKey )
+{
+ QListViewItem *item = phraseLv->firstChild();
+ while ( item != 0 && ((PhraseLVI *) item)->accelKey() != accelKey )
+ item = item->nextSibling();
+ if ( item != 0 )
+ insertPhraseInTranslation( item );
+}
+
+void MessageEditor::insertPhraseInTranslation( QListViewItem *item )
+{
+ editorPage->translationMed->insert(((PhraseLVI *) item)->phrase().target());
+ emit translationChanged( editorPage->translationMed->text() );
+}
+
+void MessageEditor::insertPhraseInTranslationAndLeave( QListViewItem *item )
+{
+ editorPage->translationMed->insert(((PhraseLVI *) item)->phrase().target());
+ emit translationChanged( editorPage->translationMed->text() );
+ editorPage->translationMed->setFocus();
+}
+
+void MessageEditor::updateButtons()
+{
+ bool overwrite = ( !editorPage->translationMed->isReadOnly() &&
+ (editorPage->translationMed->text().stripWhiteSpace().isEmpty() ||
+ mayOverwriteTranslation) );
+ mayOverwriteTranslation = FALSE;
+ emit updateActions( overwrite );
+}
+
+void MessageEditor::beginFromSource()
+{
+ mayOverwriteTranslation = TRUE;
+ setTranslation( sourceText, TRUE );
+ if ( !editorPage->hasFocus() )
+ editorPage->setFocus();
+}
+
+void MessageEditor::finishAndNext()
+{
+ setFinished( TRUE );
+ emit nextUnfinished();
+ if ( !editorPage->hasFocus() )
+ editorPage->setFocus();
+}
+
+void MessageEditor::updateCanPaste()
+{
+ bool oldCanPaste = canPaste;
+ canPaste = ( !editorPage->translationMed->isReadOnly() &&
+ !qApp->clipboard()->text().isNull() );
+ if ( canPaste != oldCanPaste )
+ emit pasteAvailable( canPaste );
+}
+
+void MessageEditor::setFinished( bool finished )
+{
+ if ( !finished != !itemFinished )
+ toggleFinished();
+}
+
+void MessageEditor::toggleGuessing()
+{
+ doGuesses = !doGuesses;
+ if ( !doGuesses ) {
+ phraseLv->clear();
+ }
+}
diff --git a/tools/linguist/linguist/msgedit.h b/tools/linguist/linguist/msgedit.h
new file mode 100644
index 0000000..bf73483
--- /dev/null
+++ b/tools/linguist/linguist/msgedit.h
@@ -0,0 +1,244 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef MSGEDIT_H
+#define MSGEDIT_H
+
+#include "trwindow.h"
+#include "phrase.h"
+
+#include <metatranslator.h>
+
+#include <qsplitter.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qscrollview.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qtooltip.h>
+
+class QAccel;
+class QDockArea;
+class QDockWindow;
+class QLabel;
+class QListView;
+class QListViewItem;
+class QTextView;
+class QVBoxLayout;
+
+class EditorPage;
+class MED;
+class PhraseLV;
+
+class PageCurl : public QWidget
+{
+ Q_OBJECT
+public:
+ PageCurl( QWidget * parent = 0, const char * name = 0,
+ WFlags f = 0 )
+ : QWidget( parent, name, f )
+ {
+ QPixmap px = TrWindow::pageCurl();
+ if ( px.mask() ) {
+ setMask( *px.mask() );
+ }
+ setBackgroundPixmap( px );
+ setFixedSize( px.size() );
+
+ QRect r( 34, 0, width()-34, 19 );
+ QToolTip::add( this, r, tr("Next unfinished phrase") );
+ r.setSize( QSize(width()-34, height()-20) );
+ r.setX( 0 );
+ r.setY( 20 );
+ QToolTip::add( this, r, tr("Previous unfinished phrase") );
+ }
+
+protected:
+ void mouseReleaseEvent( QMouseEvent * e )
+ {
+ int x = e->pos().x() - 14;
+ int y = e->pos().y() - 8;
+
+ if ( y <= x )
+ emit nextPage();
+ else
+ emit prevPage();
+ }
+
+signals:
+ void prevPage();
+ void nextPage();
+};
+
+class ShadowWidget : public QWidget
+{
+public:
+ ShadowWidget( QWidget * parent = 0, const char * name = 0 );
+ ShadowWidget( QWidget * child, QWidget * parent = 0, const char * name = 0 );
+
+ void setShadowWidth( int width ) { sWidth = width; }
+ int shadowWidth() const { return sWidth; }
+ void setMargin( int margin ){ wMargin = margin; }
+ int margin() const { return wMargin; }
+ void setWidget( QWidget * child);
+
+protected:
+ void resizeEvent( QResizeEvent * e );
+ void paintEvent( QPaintEvent * e );
+
+private:
+ int sWidth;
+ int wMargin;
+ QWidget * childWgt;
+};
+
+class EditorPage : public QFrame
+{
+ Q_OBJECT
+public:
+ EditorPage( QWidget * parent = 0, const char * name = 0 );
+
+protected:
+ void resizeEvent( QResizeEvent * );
+ void layoutWidgets();
+ void updateCommentField();
+ void calculateFieldHeight( QTextView * field );
+ void fontChange( const QFont & );
+
+private:
+ PageCurl * pageCurl;
+ QLabel * srcTextLbl;
+ QLabel * transLbl;
+ QTextView * srcText;
+ QTextView * cmtText;
+ MED * translationMed;
+
+ friend class MessageEditor;
+
+private slots:
+ void handleTranslationChanges();
+ void handleSourceChanges();
+ void handleCommentChanges();
+
+signals:
+ void pageHeightUpdated( int height );
+};
+
+class MessageEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ MessageEditor( MetaTranslator * t, QWidget * parent = 0,
+ const char * name = 0 );
+ QListView * sourceTextList() const;
+ QListView * phraseList() const;
+
+ void showNothing();
+ void showContext( const QString& context, bool finished );
+ void showMessage( const QString& text, const QString& comment,
+ const QString& fullContext, const QString& translation,
+ MetaTranslatorMessage::Type type,
+ const QValueList<Phrase>& phrases );
+ void setFinished( bool finished );
+ bool eventFilter( QObject *, QEvent * );
+
+signals:
+ void translationChanged( const QString& translation );
+ void finished( bool finished );
+ void prevUnfinished();
+ void nextUnfinished();
+ void updateActions( bool enable );
+
+ void undoAvailable( bool avail );
+ void redoAvailable( bool avail );
+ void cutAvailable( bool avail );
+ void copyAvailable( bool avail );
+ void pasteAvailable( bool avail );
+
+ void focusSourceList();
+ void focusPhraseList();
+
+public slots:
+ void undo();
+ void redo();
+ void cut();
+ void copy();
+ void paste();
+ void del();
+ void selectAll();
+ void beginFromSource();
+ void toggleGuessing();
+ void finishAndNext();
+
+private slots:
+ void emitTranslationChanged();
+ void guessActivated( int accelKey );
+ void insertPhraseInTranslation( QListViewItem *item );
+ void insertPhraseInTranslationAndLeave( QListViewItem *item );
+ void updateButtons();
+ void updateCanPaste();
+ void toggleFinished();
+
+ void updatePageHeight( int height );
+
+protected:
+ void resizeEvent( QResizeEvent * );
+
+private:
+ void setTranslation( const QString& translation, bool emitt );
+ void setEditionEnabled( bool enabled );
+
+ QListView * srcTextList;
+ QDockArea * topDock, * bottomDock;
+ QDockWindow * topDockWnd, *bottomDockWnd;
+ EditorPage * editorPage;
+ QVBoxLayout * v;
+
+ QLabel * phraseLbl;
+ PhraseLV * phraseLv;
+ QAccel * accel;
+ bool itemFinished;
+
+ ShadowWidget * sw;
+ QScrollView * sv;
+
+ MetaTranslator *tor;
+ QString sourceText;
+ QStringList guesses;
+ bool mayOverwriteTranslation;
+ bool canPaste;
+ bool doGuesses;
+};
+
+#endif
diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp
new file mode 100644
index 0000000..da702a5
--- /dev/null
+++ b/tools/linguist/linguist/phrase.cpp
@@ -0,0 +1,189 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "phrase.h"
+
+#include <qapplication.h>
+#include <qcstring.h>
+#include <qfile.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qxml.h>
+
+static QString protect( const QString& str )
+{
+ QString p = str;
+ p.replace( "&", "&amp;" );
+ p.replace( "\"", "&quot;" );
+ p.replace( ">", "&gt;" );
+ p.replace( "<", "&lt;" );
+ p.replace( "'", "&apos;" );
+ return p;
+}
+
+Phrase::Phrase( const QString& source, const QString& target,
+ const QString& definition )
+ : s( source ), t( target ), d( definition )
+{
+}
+
+bool operator==( const Phrase& p, const Phrase& q )
+{
+ return p.source() == q.source() && p.target() == q.target() &&
+ p.definition() == q.definition();
+}
+
+class QphHandler : public QXmlDefaultHandler
+{
+public:
+ QphHandler( PhraseBook *phraseBook )
+ : pb( phraseBook ), ferrorCount( 0 ) { }
+
+ virtual bool startElement( const QString& namespaceURI,
+ const QString& localName, const QString& qName,
+ const QXmlAttributes& atts );
+ virtual bool endElement( const QString& namespaceURI,
+ const QString& localName, const QString& qName );
+ virtual bool characters( const QString& ch );
+ virtual bool fatalError( const QXmlParseException& exception );
+
+private:
+ PhraseBook *pb;
+ QString source;
+ QString target;
+ QString definition;
+
+ QString accum;
+ int ferrorCount;
+};
+
+bool QphHandler::startElement( const QString& /* namespaceURI */,
+ const QString& /* localName */,
+ const QString& qName,
+ const QXmlAttributes& /* atts */ )
+{
+ if ( qName == QString("phrase") ) {
+ source.truncate( 0 );
+ target.truncate( 0 );
+ definition.truncate( 0 );
+ }
+ accum.truncate( 0 );
+ return TRUE;
+}
+
+bool QphHandler::endElement( const QString& /* namespaceURI */,
+ const QString& /* localName */,
+ const QString& qName )
+{
+ if ( qName == QString("source") )
+ source = accum;
+ else if ( qName == QString("target") )
+ target = accum;
+ else if ( qName == QString("definition") )
+ definition = accum;
+ else if ( qName == QString("phrase") )
+ pb->append( Phrase(source, target, definition) );
+ return TRUE;
+}
+
+bool QphHandler::characters( const QString& ch )
+{
+ accum += ch;
+ return TRUE;
+}
+
+bool QphHandler::fatalError( const QXmlParseException& exception )
+{
+ if ( ferrorCount++ == 0 ) {
+ QString msg;
+ msg.sprintf( "Parse error at line %d, column %d (%s).",
+ exception.lineNumber(), exception.columnNumber(),
+ exception.message().latin1() );
+ QMessageBox::information( qApp->mainWidget(),
+ QObject::tr("Qt Linguist"), msg );
+ }
+ return FALSE;
+}
+
+bool PhraseBook::load( const QString& filename )
+{
+ QFile f( filename );
+ if ( !f.open(IO_ReadOnly) )
+ return FALSE;
+
+ QTextStream t( &f );
+ QXmlInputSource in( t );
+ QXmlSimpleReader reader;
+ // don't click on these!
+ reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE );
+ reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE );
+ reader.setFeature( "http://trolltech.com/xml/features/report-whitespace"
+ "-only-CharData", FALSE );
+ QXmlDefaultHandler *hand = new QphHandler( this );
+ reader.setContentHandler( hand );
+ reader.setErrorHandler( hand );
+
+ bool ok = reader.parse( in );
+ reader.setContentHandler( 0 );
+ reader.setErrorHandler( 0 );
+ delete hand;
+ f.close();
+ if ( !ok )
+ clear();
+ return ok;
+}
+
+bool PhraseBook::save( const QString& filename ) const
+{
+ QFile f( filename );
+ if ( !f.open(IO_WriteOnly) )
+ return FALSE;
+
+ QTextStream t( &f );
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << "<!DOCTYPE QPH><QPH>\n";
+ ConstIterator p;
+ for ( p = begin(); p != end(); ++p ) {
+ t << "<phrase>\n";
+ t << " <source>" << protect( (*p).source() ) << "</source>\n";
+ t << " <target>" << protect( (*p).target() ) << "</target>\n";
+ if ( !(*p).definition().isEmpty() )
+ t << " <definition>" << protect( (*p).definition() )
+ << "</definition>\n";
+ t << "</phrase>\n";
+ }
+ t << "</QPH>\n";
+ f.close();
+ return TRUE;
+}
diff --git a/tools/linguist/linguist/phrase.h b/tools/linguist/linguist/phrase.h
new file mode 100644
index 0000000..8b32a0c
--- /dev/null
+++ b/tools/linguist/linguist/phrase.h
@@ -0,0 +1,74 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef PHRASE_H
+#define PHRASE_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class Phrase
+{
+public:
+ Phrase() { }
+ Phrase( const QString& source, const QString& target,
+ const QString& definition );
+
+ QString source() const { return s; }
+ void setSource( const QString& ns ) { s = ns; }
+ QString target() const { return t; }
+ void setTarget( const QString& nt ) { t = nt; }
+ QString definition() const { return d; }
+ void setDefinition ( const QString& nd ) { d = nd; }
+
+private:
+ QString s;
+ QString t;
+ QString d;
+};
+
+bool operator==( const Phrase& p, const Phrase& q );
+inline bool operator!=( const Phrase& p, const Phrase& q ) {
+ return !( p == q );
+}
+
+class PhraseBook : public QValueList<Phrase>
+{
+public:
+ PhraseBook() { }
+
+ bool load( const QString& filename );
+ bool save( const QString& filename ) const;
+};
+
+#endif
diff --git a/tools/linguist/linguist/phrasebookbox.cpp b/tools/linguist/linguist/phrasebookbox.cpp
new file mode 100644
index 0000000..b8c6fab
--- /dev/null
+++ b/tools/linguist/linguist/phrasebookbox.cpp
@@ -0,0 +1,244 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* TRANSLATOR PhraseBookBox
+
+ Go to Phrase > Edit Phrase Book... The dialog that pops up is a
+ PhraseBookBox.
+*/
+
+#include "phrasebookbox.h"
+#include "phraselv.h"
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+
+PhraseBookBox::PhraseBookBox( const QString& filename,
+ const PhraseBook& phraseBook, QWidget *parent,
+ const char *name, bool modal )
+ : QDialog( parent, name, modal ), fn( filename ), pb( phraseBook )
+{
+ QGridLayout *gl = new QGridLayout( this, 4, 3, 11, 11,
+ "phrase book outer layout" );
+ QVBoxLayout *bl = new QVBoxLayout( 6, "phrase book button layout" );
+
+ sourceLed = new QLineEdit( this, "source line edit" );
+ QLabel *source = new QLabel( sourceLed, tr("S&ource phrase:"), this,
+ "source label" );
+ targetLed = new QLineEdit( this, "target line edit" );
+ QLabel *target = new QLabel( targetLed, tr("&Translation:"), this,
+ "target label" );
+ definitionLed = new QLineEdit( this, "definition line edit" );
+ QLabel *definition = new QLabel( definitionLed, tr("&Definition:"), this,
+ "target label" );
+ lv = new PhraseLV( this, "phrase book list view" );
+
+ newBut = new QPushButton( tr("&New Phrase"), this );
+ newBut->setDefault( TRUE );
+
+ removeBut = new QPushButton( tr("&Remove Phrase"), this );
+ removeBut->setEnabled( FALSE );
+ QPushButton *saveBut = new QPushButton( tr("&Save"), this );
+ QPushButton *closeBut = new QPushButton( tr("Close"), this );
+
+ gl->addWidget( source, 0, 0 );
+ gl->addWidget( sourceLed, 0, 1 );
+ gl->addWidget( target, 1, 0 );
+ gl->addWidget( targetLed, 1, 1 );
+ gl->addWidget( definition, 2, 0 );
+ gl->addWidget( definitionLed, 2, 1 );
+ gl->addMultiCellWidget( lv, 3, 3, 0, 1 );
+ gl->addMultiCell( bl, 0, 3, 2, 2 );
+
+ bl->addWidget( newBut );
+ bl->addWidget( removeBut );
+ bl->addWidget( saveBut );
+ bl->addWidget( closeBut );
+ bl->addStretch( 1 );
+
+ connect( sourceLed, SIGNAL(textChanged(const QString&)),
+ this, SLOT(sourceChanged(const QString&)) );
+ connect( targetLed, SIGNAL(textChanged(const QString&)),
+ this, SLOT(targetChanged(const QString&)) );
+ connect( definitionLed, SIGNAL(textChanged(const QString&)),
+ this, SLOT(definitionChanged(const QString&)) );
+ connect( lv, SIGNAL(selectionChanged(QListViewItem *)),
+ this, SLOT(selectionChanged(QListViewItem *)) );
+ connect( newBut, SIGNAL(clicked()), this, SLOT(newPhrase()) );
+ connect( removeBut, SIGNAL(clicked()), this, SLOT(removePhrase()) );
+ connect( saveBut, SIGNAL(clicked()), this, SLOT(save()) );
+ connect( closeBut, SIGNAL(clicked()), this, SLOT(accept()) );
+
+ PhraseBook::ConstIterator it;
+ for ( it = phraseBook.begin(); it != phraseBook.end(); ++it )
+ (void) new PhraseLVI( lv, (*it) );
+ enableDisable();
+
+ QWhatsThis::add( this, tr("This window allows you to add, modify, or delete"
+ " phrases in a phrase book.") );
+ QWhatsThis::add( sourceLed, tr("This is the phrase in the source"
+ " language.") );
+ QWhatsThis::add( targetLed, tr("This is the phrase in the target language"
+ " corresponding to the source phrase.") );
+ QWhatsThis::add( definitionLed, tr("This is a definition for the source"
+ " phrase.") );
+ QWhatsThis::add( newBut, tr("Click here to add the phrase to the phrase"
+ " book.") );
+ QWhatsThis::add( removeBut, tr("Click here to remove the phrase from the"
+ " phrase book.") );
+ QWhatsThis::add( saveBut, tr("Click here to save the changes made.") );
+ QWhatsThis::add( closeBut, tr("Click here to close this window.") );
+}
+
+void PhraseBookBox::keyPressEvent( QKeyEvent *ev )
+{
+ if ( ev->key() == Key_Down || ev->key() == Key_Up ||
+ ev->key() == Key_Next || ev->key() == Key_Prior )
+ QApplication::sendEvent( lv,
+ new QKeyEvent(ev->type(), ev->key(), ev->ascii(), ev->state(),
+ ev->text(), ev->isAutoRepeat(), ev->count()) );
+ else
+ QDialog::keyPressEvent( ev );
+}
+
+void PhraseBookBox::newPhrase()
+{
+ Phrase ph;
+ ph.setSource( NewPhrase );
+ QListViewItem *item = new PhraseLVI( lv, ph );
+ selectItem( item );
+}
+
+void PhraseBookBox::removePhrase()
+{
+ QListViewItem *item = lv->currentItem();
+ QListViewItem *next = item->itemBelow() != 0 ? item->itemBelow()
+ : item->itemAbove();
+ delete item;
+ if ( next != 0 )
+ selectItem( next );
+ enableDisable();
+}
+
+void PhraseBookBox::save()
+{
+ pb.clear();
+ QListViewItem *item = lv->firstChild();
+ while ( item != 0 ) {
+ if ( !item->text(PhraseLVI::SourceTextShown).isEmpty() &&
+ item->text(PhraseLVI::SourceTextShown) != NewPhrase )
+ pb.append( Phrase(((PhraseLVI *) item)->phrase()) );
+ item = item->nextSibling();
+ }
+ if ( !pb.save( fn ) )
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("Cannot save phrase book '%1'.").arg(fn) );
+}
+
+void PhraseBookBox::sourceChanged( const QString& source )
+{
+ if ( lv->currentItem() != 0 ) {
+ lv->currentItem()->setText( PhraseLVI::SourceTextShown,
+ source.stripWhiteSpace() );
+ lv->currentItem()->setText( PhraseLVI::SourceTextOriginal, source );
+ lv->sort();
+ lv->ensureItemVisible( lv->currentItem() );
+ }
+}
+
+void PhraseBookBox::targetChanged( const QString& target )
+{
+ if ( lv->currentItem() != 0 ) {
+ lv->currentItem()->setText( PhraseLVI::TargetTextShown,
+ target.stripWhiteSpace() );
+ lv->currentItem()->setText( PhraseLVI::TargetTextOriginal, target );
+ lv->sort();
+ lv->ensureItemVisible( lv->currentItem() );
+ }
+}
+
+void PhraseBookBox::definitionChanged( const QString& definition )
+{
+ if ( lv->currentItem() != 0 ) {
+ lv->currentItem()->setText( PhraseLVI::DefinitionText, definition );
+ lv->sort();
+ lv->ensureItemVisible( lv->currentItem() );
+ }
+}
+
+void PhraseBookBox::selectionChanged( QListViewItem * /* item */ )
+{
+ enableDisable();
+}
+
+void PhraseBookBox::selectItem( QListViewItem *item )
+{
+ lv->setSelected( item, TRUE );
+ lv->ensureItemVisible( item );
+}
+
+void PhraseBookBox::enableDisable()
+{
+ QListViewItem *item = lv->currentItem();
+
+ sourceLed->blockSignals( TRUE );
+ targetLed->blockSignals( TRUE );
+ definitionLed->blockSignals( TRUE );
+
+ if ( item == 0 ) {
+ sourceLed->setText( QString::null );
+ targetLed->setText( QString::null );
+ definitionLed->setText( QString::null );
+ } else {
+ sourceLed->setText( item->text(0) );
+ targetLed->setText( item->text(1) );
+ definitionLed->setText( item->text(2) );
+ }
+ sourceLed->setEnabled( item != 0 );
+ targetLed->setEnabled( item != 0 );
+ definitionLed->setEnabled( item != 0 );
+ removeBut->setEnabled( item != 0 );
+
+ sourceLed->blockSignals( FALSE );
+ targetLed->blockSignals( FALSE );
+ definitionLed->blockSignals( FALSE );
+
+ QLineEdit *led = ( sourceLed->text() == NewPhrase ? sourceLed : targetLed );
+ led->setFocus();
+ led->selectAll();
+}
diff --git a/tools/linguist/linguist/phrasebookbox.h b/tools/linguist/linguist/phrasebookbox.h
new file mode 100644
index 0000000..0f922b1
--- /dev/null
+++ b/tools/linguist/linguist/phrasebookbox.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef PHRASEBOOKBOX_H
+#define PHRASEBOOKBOX_H
+
+#include "phrase.h"
+
+#include <qdialog.h>
+#include <qvaluelist.h>
+
+class QLineEdit;
+class QPushButton;
+class QListViewItem;
+
+class PhraseLV;
+
+class PhraseBookBox : public QDialog
+{
+ Q_OBJECT
+public:
+ PhraseBookBox( const QString& filename, const PhraseBook& phraseBook,
+ QWidget *parent = 0, const char *name = 0,
+ bool modal = FALSE );
+
+ const PhraseBook& phraseBook() const { return pb; }
+
+protected:
+ virtual void keyPressEvent( QKeyEvent *ev );
+
+private slots:
+ void newPhrase();
+ void removePhrase();
+ void save();
+ void sourceChanged( const QString& source );
+ void targetChanged( const QString& target );
+ void definitionChanged( const QString& definition );
+ void selectionChanged( QListViewItem *item );
+
+private:
+ void selectItem( QListViewItem *item );
+ void enableDisable();
+
+ QLineEdit *sourceLed;
+ QLineEdit *targetLed;
+ QLineEdit *definitionLed;
+ QPushButton *newBut;
+ QPushButton *removeBut;
+ PhraseLV *lv;
+ QString fn;
+ PhraseBook pb;
+};
+
+#endif
diff --git a/tools/linguist/linguist/phraselv.cpp b/tools/linguist/linguist/phraselv.cpp
new file mode 100644
index 0000000..fa454f8
--- /dev/null
+++ b/tools/linguist/linguist/phraselv.cpp
@@ -0,0 +1,171 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* TRANSLATOR PhraseLV
+
+ The phrase list in the right panel of the main window (with Source phrase,
+ Target phrase, and Definition in its header) is a PhraseLV object.
+*/
+
+#include "phraselv.h"
+
+#include <qregexp.h>
+#include <qwhatsthis.h>
+#include <qheader.h>
+
+class WhatPhrase : public QWhatsThis
+{
+public:
+ WhatPhrase( PhraseLV *w );
+
+ virtual QString text( const QPoint& p );
+
+private:
+ PhraseLV *parent;
+};
+
+WhatPhrase::WhatPhrase( PhraseLV *w )
+ : QWhatsThis( w )
+{
+ parent = w;
+}
+
+QString WhatPhrase::text( const QPoint& p )
+{
+ QListViewItem *item = parent->itemAt( p );
+ if ( item == 0 )
+ return PhraseLV::tr( "This is a list of phrase entries relevant to the"
+ " source text. Each phrase is supplemented with a suggested"
+ " translation and a definition." );
+ else
+ return QString( PhraseLV::tr("<p><u>%1:</u>&nbsp;&nbsp;%2</p>"
+ "<p><u>%3:</u>&nbsp;&nbsp;%4</p>"
+ "<p><u>%5:</u>&nbsp;&nbsp;%6</p>") )
+ .arg( parent->columnText(PhraseLVI::SourceTextShown) )
+ .arg( item->text(PhraseLVI::SourceTextShown) )
+ .arg( parent->columnText(PhraseLVI::TargetTextShown) )
+ .arg( item->text(PhraseLVI::TargetTextShown) )
+ .arg( parent->columnText(PhraseLVI::DefinitionText) )
+ .arg( item->text(PhraseLVI::DefinitionText) );
+}
+
+PhraseLVI::PhraseLVI( PhraseLV *parent, const Phrase& phrase, int accelKey )
+ : QListViewItem( parent ),
+ akey( accelKey )
+{
+ setPhrase( phrase );
+}
+
+QString PhraseLVI::key( int column, bool ascending ) const
+{
+ if ( column == SourceTextShown ) {
+ if ( sourceTextKey.isEmpty() ) {
+ if ( ascending ) {
+ return "";
+ } else {
+ return QString::null;
+ }
+ } else {
+ return sourceTextKey;
+ }
+ } else if ( column == TargetTextShown ) {
+ return targetTextKey;
+ } else {
+ return QChar( '0' + akey ) + text( column );
+ }
+}
+
+void PhraseLVI::setText( int column, const QString& text )
+{
+ if ( column == SourceTextShown ) {
+ sourceTextKey = makeKey( text );
+ } else if ( column == TargetTextShown ) {
+ targetTextKey = makeKey( text );
+ }
+ QListViewItem::setText( column, text );
+}
+
+void PhraseLVI::setPhrase( const Phrase& phrase )
+{
+ setText( SourceTextShown, phrase.source().simplifyWhiteSpace() );
+ setText( TargetTextShown, phrase.target().simplifyWhiteSpace() );
+ setText( DefinitionText, phrase.definition() );
+ setText( SourceTextOriginal, phrase.source() );
+ setText( TargetTextOriginal, phrase.target() );
+}
+
+Phrase PhraseLVI::phrase() const
+{
+ return Phrase( text(SourceTextOriginal), text(TargetTextOriginal),
+ text(DefinitionText) );
+}
+
+QString PhraseLVI::makeKey( const QString& text ) const
+{
+ if ( text == NewPhrase )
+ return QString::null;
+
+ QString key;
+ for ( int i = 0; i < (int) text.length(); i++ ) {
+ if ( text[i] != QChar('&') )
+ key += text[i].lower();
+ }
+ // see Section 5, Exercise 4 of The Art of Computer Programming
+ key += QChar::null;
+ key += text;
+ return key;
+}
+
+PhraseLV::PhraseLV( QWidget *parent, const char *name )
+ : QListView( parent, name )
+{
+ setAllColumnsShowFocus( TRUE );
+ setShowSortIndicator( TRUE );
+ for ( int i = 0; i < 3; i++ )
+ addColumn( QString::null, 120 );
+ setColumnText( PhraseLVI::SourceTextShown, tr("Source phrase") );
+ setColumnText( PhraseLVI::TargetTextShown, tr("Translation") );
+ setColumnText( PhraseLVI::DefinitionText, tr("Definition") );
+ header()->setStretchEnabled( TRUE, -1 );
+ what = new WhatPhrase( this );
+}
+
+PhraseLV::~PhraseLV()
+{
+// delete what;
+}
+
+QSize PhraseLV::sizeHint() const
+{
+ return QSize( QListView::sizeHint().width(), 50 );
+}
diff --git a/tools/linguist/linguist/phraselv.h b/tools/linguist/linguist/phraselv.h
new file mode 100644
index 0000000..cb06090
--- /dev/null
+++ b/tools/linguist/linguist/phraselv.h
@@ -0,0 +1,83 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef PHRASELV_H
+#define PHRASELV_H
+
+#include "phrase.h"
+
+#include <qlistview.h>
+
+class QWhatsThis;
+
+class PhraseLV;
+
+#define NewPhrase PhraseLV::tr( "(New Phrase)" )
+
+class PhraseLVI : public QListViewItem
+{
+public:
+ enum { SourceTextShown, TargetTextShown, DefinitionText, SourceTextOriginal,
+ TargetTextOriginal };
+
+ PhraseLVI( PhraseLV *parent, const Phrase& phrase, int accelKey = 0 );
+
+ virtual void setText( int column, const QString& text );
+ virtual QString key( int column, bool ascending ) const;
+
+ void setPhrase( const Phrase& phrase );
+ Phrase phrase() const;
+ int accelKey() const { return akey; }
+
+private:
+ QString makeKey( const QString& text ) const;
+
+ int akey;
+ QString sourceTextKey;
+ QString targetTextKey;
+};
+
+class PhraseLV : public QListView
+{
+ Q_OBJECT
+public:
+ PhraseLV( QWidget *parent, const char *name );
+ ~PhraseLV();
+
+ virtual QSize sizeHint() const;
+
+private:
+ QWhatsThis *what;
+};
+
+#endif
diff --git a/tools/linguist/linguist/printout.cpp b/tools/linguist/linguist/printout.cpp
new file mode 100644
index 0000000..53d944a
--- /dev/null
+++ b/tools/linguist/linguist/printout.cpp
@@ -0,0 +1,182 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "printout.h"
+
+#include <qprinter.h>
+#include <qfontmetrics.h>
+
+PrintOut::PrintOut( QPrinter *printer )
+ : pr( printer ), pdmetrics( printer ), nextRule( NoRule ), page( 0 )
+{
+ p.begin( pr );
+ QFont f( "Arial" );
+ f8 = f;
+ f8.setPointSize( 8 );
+ f10 = f;
+ f10.setPointSize( 10 );
+ p.setFont( f10 );
+ fmetrics = new QFontMetrics( p.fontMetrics() );
+ hmargin = 5 * pdmetrics.width() / pdmetrics.widthMM(); // 5 mm
+ vmargin = 5 * pdmetrics.height() / pdmetrics.heightMM(); // 5 mm
+ hsize = pdmetrics.width() - 2 * hmargin;
+ vsize = pdmetrics.height() - vmargin;
+ dateTime = QDateTime::currentDateTime();
+ breakPage();
+ vsize -= voffset;
+ cp = Paragraph( QPoint(hmargin, voffset) );
+}
+
+PrintOut::~PrintOut()
+{
+ flushLine();
+ delete fmetrics;
+ p.end();
+}
+
+void PrintOut::setRule( Rule rule )
+{
+ if ( (int) nextRule < (int) rule )
+ nextRule = rule;
+}
+
+void PrintOut::setGuide( const QString& guide )
+{
+ g = guide;
+}
+
+void PrintOut::vskip()
+{
+ if ( !firstParagraph )
+ voffset += 14;
+}
+
+void PrintOut::flushLine( bool /* mayBreak */ )
+{
+ if ( voffset + cp.rect.height() > vsize )
+ breakPage();
+ else if ( !firstParagraph )
+ drawRule( nextRule );
+
+ for ( int i = 0; i < (int) cp.boxes.count(); i++ ) {
+ Box b = cp.boxes[i];
+ b.rect.moveBy( 0, voffset );
+ QRect r = b.rect;
+ p.setFont( b.font );
+ p.drawText( r, b.align, b.text );
+ }
+ voffset += cp.rect.height();
+
+ nextRule = NoRule;
+ cp = Paragraph( QPoint(hmargin, voffset) );
+ firstParagraph = FALSE;
+}
+
+void PrintOut::addBox( int percent, const QString& text, Style style,
+ int halign )
+{
+ int align = halign | Qt::AlignTop;
+ QFont f = f10;
+ if ( style == Strong )
+ f.setBold( TRUE );
+ else if ( style == Emphasis )
+ f.setItalic( TRUE );
+ int wd = hsize * percent / 100;
+ QRect r( cp.rect.x() + cp.rect.width(), 0, wd, vsize );
+ int ht = p.boundingRect( r, align, text ).height();
+
+ Box b( r, text, f, align );
+ cp.boxes.append( b );
+ cp.rect.setSize( QSize(cp.rect.width() + wd, QMAX(cp.rect.height(), ht)) );
+}
+
+void PrintOut::breakPage()
+{
+ static const int LeftAlign = Qt::AlignLeft | Qt::AlignTop;
+ static const int RightAlign = Qt::AlignRight | Qt::AlignTop;
+ QRect r1, r2;
+ int h1 = 0;
+ int h2 = 0;
+
+ if ( page++ > 0 )
+ pr->newPage();
+ voffset = 0;
+
+ p.setFont( f10 );
+ r1 = QRect( hmargin, voffset, 3 * hsize / 4, vsize );
+ r2 = QRect( r1.x() + r1.width(), voffset, hsize - r1.width(), vsize );
+ h1 = p.boundingRect( r1, LeftAlign, pr->docName() ).height();
+ p.drawText( r1, LeftAlign, pr->docName() );
+ h2 = p.boundingRect( r2, RightAlign, QString::number(page) ).height();
+ p.drawText( r2, RightAlign, QString::number(page) );
+ voffset += QMAX( h1, h2 );
+
+ r1 = QRect( hmargin, voffset, hsize / 2, LeftAlign );
+ p.setFont( f8 );
+ h1 = p.boundingRect( r1, LeftAlign, dateTime.toString() ).height();
+ p.drawText( r1, LeftAlign, dateTime.toString() );
+ p.setFont( f10 );
+ voffset += QMAX( h1, h2 );
+
+ voffset += 4;
+ p.drawLine( QPoint(hmargin, voffset), QPoint(hmargin + hsize, voffset) );
+ voffset += 14;
+ firstParagraph = TRUE;
+}
+
+void PrintOut::drawRule( Rule rule )
+{
+ QPen pen;
+
+ switch ( rule ) {
+ case NoRule:
+ voffset += 5;
+ break;
+ case ThinRule:
+ pen.setColor( QColor(192, 192, 192) );
+ pen.setStyle( QPen::DotLine );
+ pen.setWidth( 0 );
+ p.setPen( pen );
+ voffset += 5;
+ p.drawLine( QPoint(hmargin, voffset),
+ QPoint(hmargin + hsize, voffset) );
+ p.setPen( QPen() );
+ voffset += 2;
+ break;
+ case ThickRule:
+ voffset += 7;
+ p.drawLine( QPoint(hmargin, voffset),
+ QPoint(hmargin + hsize, voffset) );
+ voffset += 4;
+ }
+}
diff --git a/tools/linguist/linguist/printout.h b/tools/linguist/linguist/printout.h
new file mode 100644
index 0000000..d67191c
--- /dev/null
+++ b/tools/linguist/linguist/printout.h
@@ -0,0 +1,126 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef PRINTOUT_H
+#define PRINTOUT_H
+
+#include <qfont.h>
+#include <qpaintdevicemetrics.h>
+#include <qpainter.h>
+#include <qrect.h>
+#include <qvaluelist.h>
+#include <qdatetime.h>
+
+class QPrinter;
+class QFontMetrics;
+
+class PrintOut
+{
+public:
+ enum Rule { NoRule, ThinRule, ThickRule };
+ enum Style { Normal, Strong, Emphasis };
+
+ PrintOut( QPrinter *printer );
+ ~PrintOut();
+
+ void setRule( Rule rule );
+ void setGuide( const QString& guide );
+ void vskip();
+ void flushLine( bool mayBreak = FALSE );
+ void addBox( int percent, const QString& text = QString::null,
+ Style style = Normal,
+ int halign = Qt::AlignLeft | Qt::WordBreak );
+
+ int pageNum() const { return page; }
+
+ struct Box
+ {
+ QRect rect;
+ QString text;
+ QFont font;
+ int align;
+
+ Box() : align( 0 ) { }
+ Box( const QRect& r, const QString& t, const QFont& f, int a )
+ : rect( r ), text( t ), font( f ), align( a ) { }
+ Box( const Box& b )
+ : rect( b.rect ), text( b.text ), font( b.font ),
+ align( b.align ) { }
+
+ Box& operator=( const Box& b ) {
+ rect = b.rect;
+ text = b.text;
+ font = b.font;
+ align = b.align;
+ return *this;
+ }
+
+ bool operator==( const Box& b ) const {
+ return rect == b.rect && text == b.text && font == b.font &&
+ align == b.align;
+ }
+ };
+
+private:
+ void breakPage();
+ void drawRule( Rule rule );
+
+ struct Paragraph {
+ QRect rect;
+ QValueList<Box> boxes;
+
+ Paragraph() { }
+ Paragraph( QPoint p ) : rect( p, QSize(0, 0) ) { }
+ };
+
+ QPrinter *pr;
+ QPainter p;
+ QFont f8;
+ QFont f10;
+ QFontMetrics *fmetrics;
+ QPaintDeviceMetrics pdmetrics;
+ Rule nextRule;
+ Paragraph cp;
+ int page;
+ bool firstParagraph;
+ QString g;
+ QDateTime dateTime;
+
+ int hmargin;
+ int vmargin;
+ int voffset;
+ int hsize;
+ int vsize;
+};
+
+#endif
diff --git a/tools/linguist/linguist/simtexth.cpp b/tools/linguist/linguist/simtexth.cpp
new file mode 100644
index 0000000..8bed388
--- /dev/null
+++ b/tools/linguist/linguist/simtexth.cpp
@@ -0,0 +1,239 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "simtexth.h"
+
+#include <metatranslator.h>
+
+#include <qcstring.h>
+#include <qdict.h>
+#include <qmap.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+
+#include <string.h>
+
+typedef QValueList<MetaTranslatorMessage> TML;
+
+/*
+ How similar are two texts? The approach used here relies on co-occurrence
+ matrices and is very efficient.
+
+ Let's see with an example: how similar are "here" and "hither"? The
+ co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1, M[r,e] = 1, and 0
+ elsewhere; the matrix N for "hither" is N[h,i] = 1, N[i,t] = 1, ...,
+ N[h,e] = 1, N[e,r] = 1, and 0 elsewhere. The union U of both matrices is the
+ matrix U[i,j] = max { M[i,j], N[i,j] }, and the intersection V is
+ V[i,j] = min { M[i,j], N[i,j] }. The score for a pair of texts is
+
+ score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j),
+
+ a formula suggested by Arnt Gulbrandsen. Here we have
+
+ score = 2 / 6,
+
+ or one third.
+
+ The implementation differs from this in a few details. Most importantly,
+ repetitions are ignored; for input "xxx", M[x,x] equals 1, not 2.
+*/
+
+/*
+ Every character is assigned to one of 20 buckets so that the co-occurrence
+ matrix requires only 20 * 20 = 400 bits, not 256 * 256 = 65536 bits or even
+ more if we want the whole Unicode. Which character falls in which bucket is
+ arbitrary.
+
+ The second half of the table is a replica of the first half, because of
+ laziness.
+*/
+static const int indexOf[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// ! " # $ % & ' ( ) * + , - . /
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+// @ A B C D E F G H I J K L M N O
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+// ` a b c d e f g h i j k l m n o
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// p q r s t u v w x y z { | } ~
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0
+};
+
+/*
+ The entry bitCount[i] (for i between 0 and 255) is the number of bits used to
+ represent i in binary.
+*/
+static const int bitCount[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+struct CoMatrix
+{
+ /*
+ The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or 13
+ words. Some operations are performed on words for more efficiency.
+ */
+ union {
+ Q_UINT8 b[52];
+ Q_UINT32 w[13];
+ };
+
+ CoMatrix() { memset( b, 0, 52 ); }
+ CoMatrix( const char *text ) {
+ char c = '\0', d;
+ memset( b, 0, 52 );
+ /*
+ The Knuth books are not in the office only for show; they help make
+ loops 30% faster and 20% as readable.
+ */
+ while ( (d = *text) != '\0' ) {
+ setCoocc( c, d );
+ if ( (c = *++text) != '\0' ) {
+ setCoocc( d, c );
+ text++;
+ }
+ }
+ }
+
+ void setCoocc( char c, char d ) {
+ int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d];
+ b[k >> 3] |= k & 0x7;
+ }
+
+ int worth() const {
+ int w = 0;
+ for ( int i = 0; i < 50; i++ )
+ w += bitCount[b[i]];
+ return w;
+ }
+};
+
+static inline CoMatrix reunion( const CoMatrix& m, const CoMatrix& n )
+{
+ CoMatrix p;
+ for ( int i = 0; i < 13; i++ )
+ p.w[i] = m.w[i] | n.w[i];
+ return p;
+}
+
+static inline CoMatrix intersection( const CoMatrix& m, const CoMatrix& n )
+{
+ CoMatrix p;
+ for ( int i = 0; i < 13; i++ )
+ p.w[i] = m.w[i] & n.w[i];
+ return p;
+}
+
+CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor,
+ const char *text,
+ int maxCandidates )
+{
+ QValueList<int> scores;
+ CandidateList candidates;
+ CoMatrix cmTarget( text );
+ int targetLen = qstrlen( text );
+
+ TML all = tor->translatedMessages();
+ TML::Iterator it;
+
+ for ( it = all.begin(); it != all.end(); ++it ) {
+ if ( (*it).type() == MetaTranslatorMessage::Unfinished ||
+ (*it).translation().isEmpty() )
+ continue;
+
+ QString s = tor->toUnicode( (*it).sourceText(), (*it).utf8() );
+ CoMatrix cm( s.latin1() );
+ int delta = QABS( (int) s.length() - targetLen );
+
+ /*
+ Here is the score formula. A comment above contains a
+ discussion on a similar (but simpler) formula.
+ */
+ int score = ( (intersection(cm, cmTarget).worth() + 1) << 10 ) /
+ ( reunion(cm, cmTarget).worth() + (delta << 1) + 1 );
+
+ if ( (int) candidates.count() == maxCandidates &&
+ score > scores[maxCandidates - 1] )
+ candidates.remove( candidates.last() );
+ if ( (int) candidates.count() < maxCandidates && score >= 190 ) {
+ Candidate cand( s, (*it).translation() );
+
+ int i;
+ for ( i = 0; i < (int) candidates.count(); i++ ) {
+ if ( score >= scores[i] ) {
+ if ( score == scores[i] ) {
+ if ( candidates[i] == cand )
+ goto continue_outer_loop;
+ } else {
+ break;
+ }
+ }
+ }
+ scores.insert( scores.at(i), score );
+ candidates.insert( candidates.at(i), cand );
+ }
+ continue_outer_loop:
+ ;
+ }
+ return candidates;
+}
diff --git a/tools/linguist/linguist/simtexth.h b/tools/linguist/linguist/simtexth.h
new file mode 100644
index 0000000..91d8cbd
--- /dev/null
+++ b/tools/linguist/linguist/simtexth.h
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef SIMTEXTH_H
+#define SIMTEXTH_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class MetaTranslator;
+
+struct Candidate {
+ QString source;
+ QString target;
+
+ Candidate() { }
+ Candidate( const QString& source0, const QString& target0 )
+ : source( source0 ), target( target0 ) { }
+};
+
+inline bool operator==( const Candidate& c, const Candidate& d ) {
+ return c.target == d.target && c.source == d.source;
+}
+inline bool operator!=( const Candidate& c, const Candidate& d ) {
+ return !operator==( c, d );
+}
+
+typedef QValueList<Candidate> CandidateList;
+
+CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor,
+ const char *text,
+ int maxCandidates );
+
+#endif
diff --git a/tools/linguist/linguist/statistics.ui b/tools/linguist/linguist/statistics.ui
new file mode 100644
index 0000000..c897b78
--- /dev/null
+++ b/tools/linguist/linguist/statistics.ui
@@ -0,0 +1,259 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>Statistics</class>
+<comment>*********************************************************************
+** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*********************************************************************</comment>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>Statistics</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>336</width>
+ <height>164</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Statistics</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>closeBtn</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Translation</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Source</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>untrWords</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>trWords</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Words:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>trChars</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>untrChars</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Characters:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Characters (with spaces):</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>trCharsSpc</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>untrCharsSpc</cstring>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>closeBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>Statistics</receiver>
+ <slot>close()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">statistics.ui.h</include>
+</includes>
+<signals>
+ <signal>closed()</signal>
+</signals>
+<slots>
+ <slot>updateStats( int w1, int c1, int cs1, int w2, int c2, int cs2 )</slot>
+ <slot>closeEvent( QCloseEvent * e )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/tools/linguist/linguist/statistics.ui.h b/tools/linguist/linguist/statistics.ui.h
new file mode 100644
index 0000000..fe9b448
--- /dev/null
+++ b/tools/linguist/linguist/statistics.ui.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+void Statistics::init()
+{
+ setFixedHeight( sizeHint().height() );
+}
+
+void Statistics::updateStats( int w1, int c1, int cs1, int w2, int c2, int cs2 )
+{
+ untrWords->setText( QString::number( w1 ) );
+ untrChars->setText( QString::number( c1 ) );
+ untrCharsSpc->setText( QString::number( cs1 ) );
+ trWords->setText( QString::number( w2 ) );
+ trChars->setText( QString::number( c2 ) );
+ trCharsSpc->setText( QString::number( cs2 ) );
+}
+
+void Statistics::closeEvent( QCloseEvent * e )
+{
+ emit closed();
+ QDialog::closeEvent( e );
+}
diff --git a/tools/linguist/linguist/trwindow.cpp b/tools/linguist/linguist/trwindow.cpp
new file mode 100644
index 0000000..e8725e5
--- /dev/null
+++ b/tools/linguist/linguist/trwindow.cpp
@@ -0,0 +1,2071 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* TRANSLATOR TrWindow
+
+ This is the application's main window.
+*/
+
+#include "trwindow.h"
+#include "listviews.h"
+#include "finddialog.h"
+#include "msgedit.h"
+#include "phrasebookbox.h"
+#include "printout.h"
+#include "about.h"
+#include "phraselv.h"
+#include "statistics.h"
+
+#include <qaccel.h>
+#include <qaction.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qdict.h>
+#include <qdockarea.h>
+#include <qdockwindow.h>
+#include <qfile.h>
+#include <qfiledialog.h>
+#include <qfileinfo.h>
+#include <qheader.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmenubar.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qregexp.h>
+#include <qsettings.h>
+#include <qstatusbar.h>
+#include <qtoolbar.h>
+#include <qwhatsthis.h>
+#include <qprocess.h>
+#include <qassistantclient.h>
+
+#include <stdlib.h>
+
+#define pagecurl_mask_width 53
+#define pagecurl_mask_height 51
+static const uchar pagecurl_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x0f, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xfe, 0xff,
+ 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+ 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0xff,
+ 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+ 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f,
+ 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff,
+ 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0,
+ 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+ 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff,
+ 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+ 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f,
+ 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff,
+ 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0,
+ 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+ 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xfc,
+ 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
+
+typedef QValueList<MetaTranslatorMessage> TML;
+
+static const int ErrorMS = 600000; // for error messages
+static const int MessageMS = 2500;
+
+QPixmap * TrWindow::pxOn = 0;
+QPixmap * TrWindow::pxOff = 0;
+QPixmap * TrWindow::pxObsolete = 0;
+QPixmap * TrWindow::pxDanger = 0;
+
+enum Ending { End_None, End_FullStop, End_Interrobang, End_Colon,
+ End_Ellipsis };
+
+static Ending ending( QString str )
+{
+ str = str.simplifyWhiteSpace();
+ int ch = 0;
+ if ( !str.isEmpty() )
+ ch = str.right( 1 )[0].unicode();
+
+ switch ( ch ) {
+ case 0x002e: // full stop
+ if ( str.endsWith(QString("...")) )
+ return End_Ellipsis;
+ else
+ return End_FullStop;
+ case 0x0589: // armenian full stop
+ case 0x06d4: // arabic full stop
+ case 0x3002: // ideographic full stop
+ return End_FullStop;
+ case 0x0021: // exclamation mark
+ case 0x003f: // question mark
+ case 0x00a1: // inverted exclamation mark
+ case 0x00bf: // inverted question mark
+ case 0x01c3: // latin letter retroflex click
+ case 0x037e: // greek question mark
+ case 0x061f: // arabic question mark
+ case 0x203c: // double exclamation mark
+ case 0x203d: // interrobang
+ case 0x2048: // question exclamation mark
+ case 0x2049: // exclamation question mark
+ case 0x2762: // heavy exclamation mark ornament
+ return End_Interrobang;
+ case 0x003a: // colon
+ return End_Colon;
+ case 0x2026: // horizontal ellipsis
+ return End_Ellipsis;
+ default:
+ return End_None;
+ }
+}
+
+class Action : public QAction
+{
+public:
+ Action( QPopupMenu *pop, const QString& menuText, QObject *receiver,
+ const char *member, const QString &imageName = QString::null,
+ int accel = 0, bool toggle = FALSE );
+ Action( QPopupMenu *pop, const QString& menuText, int accel = 0,
+ bool toggle = FALSE );
+
+ virtual void setWhatsThis( const QString& whatsThis );
+
+ bool addToToolbar( QToolBar *tb, const QString& text );
+};
+
+Action::Action( QPopupMenu *pop, const QString& menuText, QObject *receiver,
+ const char *member, const QString &imageName, int accel,
+ bool toggle )
+ : QAction( pop->parent(), (const char *) 0, toggle )
+{
+ setMenuText( menuText );
+ setAccel( accel );
+
+ if ( !imageName.isEmpty() ) {
+ QPixmap enabledPix = QPixmap::fromMimeSource( imageName );
+ QIconSet s( enabledPix );
+ if ( imageName != "whatsthis.xpm" ) {
+ QPixmap disabledPix = QPixmap::fromMimeSource( "d_" + imageName );
+ s.setPixmap( disabledPix, QIconSet::Small, QIconSet::Disabled );
+ }
+ setIconSet( s );
+ }
+ QAction::addTo( pop );
+ connect( this, SIGNAL(activated()), receiver, member );
+}
+
+Action::Action( QPopupMenu *pop, const QString& menuText, int accel,
+ bool toggle )
+ : QAction( pop->parent(), (const char *) 0, toggle )
+{
+ QAction::addTo( pop );
+ setMenuText( menuText );
+ setAccel( accel );
+}
+
+void Action::setWhatsThis( const QString& whatsThis )
+{
+ QAction::setWhatsThis( whatsThis );
+ setStatusTip( whatsThis );
+}
+
+bool Action::addToToolbar( QToolBar *tb, const QString& text )
+{
+ setText( text );
+ return QAction::addTo( tb );
+}
+
+const QPixmap TrWindow::pageCurl()
+{
+ QPixmap pixmap;
+ pixmap = QPixmap::fromMimeSource( "pagecurl.png" );
+ if ( !pixmap.isNull() ) {
+ QBitmap pageCurlMask( pagecurl_mask_width, pagecurl_mask_height,
+ pagecurl_mask_bits, TRUE );
+ pixmap.setMask( pageCurlMask );
+ }
+
+ return pixmap;
+}
+
+TrWindow::TrWindow()
+ : QMainWindow( 0, "translation window", WType_TopLevel | WDestructiveClose )
+{
+
+#ifndef Q_WS_MACX
+ setIcon( QPixmap::fromMimeSource( "appicon.png" ) );
+#endif
+
+ // Create the application global listview symbols
+ pxOn = new QPixmap( QPixmap::fromMimeSource( "s_check_on.png" ) );
+ pxOff = new QPixmap( QPixmap::fromMimeSource( "s_check_off.png" ) );
+ pxObsolete = new QPixmap( QPixmap::fromMimeSource( "d_s_check_obs.png" ) );
+ pxDanger = new QPixmap( QPixmap::fromMimeSource( "s_check_danger.png" ) );
+
+ // Set up the Scope dock window
+ QDockWindow * dwScope = new QDockWindow( QDockWindow::InDock, this,
+ "context");
+ dwScope->setResizeEnabled( TRUE );
+ dwScope->setCloseMode( QDockWindow::Always );
+ addDockWindow( dwScope, tr("Context"), Qt::DockLeft );
+ dwScope->setCaption( tr("Context") );
+ dwScope->setFixedExtentWidth( 200 );
+ lv = new QListView( dwScope, "context list view" );
+ lv->setShowSortIndicator( TRUE );
+ lv->setAllColumnsShowFocus( TRUE );
+ lv->header()->setStretchEnabled( TRUE, 1 );
+ QFontMetrics fm( font() );
+ lv->addColumn( tr("Done"), fm.width( tr("Done") ) + 10 );
+ lv->addColumn( tr("Context") );
+ lv->addColumn( tr("Items"), 55 );
+ lv->setColumnAlignment( 0, Qt::AlignCenter );
+ lv->setColumnAlignment( 2, Qt::AlignRight );
+ lv->setSorting( 0 );
+ lv->setHScrollBarMode( QScrollView::AlwaysOff );
+ dwScope->setWidget( lv );
+
+ messageIsShown = FALSE;
+ me = new MessageEditor( &tor, this, "message editor" );
+ setCentralWidget( me );
+ slv = me->sourceTextList();
+ plv = me->phraseList();
+
+ setupMenuBar();
+ setupToolBars();
+
+ progress = new QLabel( statusBar(), "progress" );
+ statusBar()->addWidget( progress, 0, TRUE );
+ modified = new QLabel( QString(" %1 ").arg(tr("MOD")), statusBar(),
+ "modified?" );
+ statusBar()->addWidget( modified, 0, TRUE );
+
+ dirtyItem = -1;
+ numFinished = 0;
+ numNonobsolete = 0;
+ numMessages = 0;
+ updateProgress();
+
+ dirty = FALSE;
+ updateCaption();
+
+ phraseBooks.setAutoDelete( TRUE );
+
+ f = new FindDialog( FALSE, this, "find", FALSE );
+ f->setCaption( tr("Qt Linguist") );
+ h = new FindDialog( TRUE, this, "replace", FALSE );
+ h->setCaption( tr("Qt Linguist") );
+ findMatchCase = FALSE;
+ findWhere = 0;
+ foundItem = 0;
+ foundScope = 0;
+ foundWhere = 0;
+ foundOffset = 0;
+
+ connect( lv, SIGNAL(selectionChanged(QListViewItem *)),
+ this, SLOT(showNewScope(QListViewItem *)) );
+
+ connect( slv, SIGNAL(currentChanged(QListViewItem *)),
+ this, SLOT(showNewCurrent(QListViewItem *)) );
+
+ connect( slv, SIGNAL(clicked(QListViewItem *, const QPoint&, int)),
+ this, SLOT(showNewCurrent(QListViewItem *)) );
+
+ connect( slv, SIGNAL(clicked(QListViewItem *, const QPoint&, int)),
+ this, SLOT(toggleFinished(QListViewItem *, const QPoint&, int)) );
+
+ connect( me, SIGNAL(translationChanged(const QString&)),
+ this, SLOT(updateTranslation(const QString&)) );
+ connect( me, SIGNAL(finished(bool)), this, SLOT(updateFinished(bool)) );
+ connect( me, SIGNAL(prevUnfinished()), this, SLOT(prevUnfinished()) );
+ connect( me, SIGNAL(nextUnfinished()), this, SLOT(nextUnfinished()) );
+ connect( me, SIGNAL(focusSourceList()), this, SLOT(focusSourceList()) );
+ connect( me, SIGNAL(focusPhraseList()), this, SLOT(focusPhraseList()) );
+ connect( f, SIGNAL(findNext(const QString&, int, bool)),
+ this, SLOT(findNext(const QString&, int, bool)) );
+
+ QWhatsThis::add( lv, tr("This panel lists the source contexts.") );
+
+ QWhatsThis::add( slv, tr("This panel lists the source texts. "
+ "Items that violate validation rules "
+ "are marked with a warning.") );
+ showNewCurrent( 0 );
+
+ QSize as( qApp->desktop()->size() );
+ as -= QSize( 30, 30 );
+ resize( QSize( 1000, 800 ).boundedTo( as ) );
+ readConfig();
+ stats = 0;
+ srcWords = 0;
+ srcChars = 0;
+ srcCharsSpc = 0;
+}
+
+TrWindow::~TrWindow()
+{
+ writeConfig();
+ delete stats;
+}
+
+void TrWindow::openFile( const QString& name )
+{
+ if ( !name.isEmpty() ) {
+ statusBar()->message( tr("Loading...") );
+ qApp->processEvents();
+ tor.clear();
+ if ( tor.load(name) ) {
+ slv->clear();
+ slv->repaint();
+ slv->viewport()->repaint();
+ slv->setUpdatesEnabled( FALSE );
+ slv->viewport()->setUpdatesEnabled( FALSE );
+ lv->clear();
+ lv->repaint();
+ lv->viewport()->repaint();
+ lv->setUpdatesEnabled( FALSE );
+ lv->viewport()->setUpdatesEnabled( FALSE );
+ setEnabled( FALSE );
+ numFinished = 0;
+ numNonobsolete = 0;
+ numMessages = 0;
+ foundScope = 0;
+
+ TML all = tor.messages();
+ TML::Iterator it;
+ QDict<ContextLVI> contexts( 1009 );
+
+ srcWords = 0;
+ srcChars = 0;
+ srcCharsSpc = 0;
+ for ( it = all.begin(); it != all.end(); ++it ) {
+ qApp->processEvents();
+ ContextLVI *c = contexts.find( QString((*it).context()) );
+ if ( c == 0 ) {
+ c = new ContextLVI( lv, tor.toUnicode((*it).context(),
+ (*it).utf8()) );
+ contexts.insert( QString((*it).context()), c );
+ }
+ if ( QCString((*it).sourceText()) == ContextComment ) {
+ c->appendToComment( tor.toUnicode((*it).comment(),
+ (*it).utf8()) );
+ } else {
+ MessageLVI * tmp = new MessageLVI( slv, *it,
+ tor.toUnicode((*it).sourceText(),
+ (*it).utf8()),
+ tor.toUnicode((*it).comment(),
+ (*it).utf8()), c );
+ tmp->setDanger( danger(tmp->sourceText(),
+ tmp->translation()) &&
+ tmp->message().type() ==
+ MetaTranslatorMessage::Finished );
+ c->instantiateMessageItem( slv, tmp );
+ if ( (*it).type() != MetaTranslatorMessage::Obsolete ) {
+ numNonobsolete++;
+ if ( (*it).type() == MetaTranslatorMessage::Finished )
+ numFinished++;
+ doCharCounting( tmp->sourceText(), srcWords, srcChars, srcCharsSpc );
+ } else {
+ c->incrementObsoleteCount();
+ }
+ numMessages++;
+ }
+ c->updateStatus();
+ }
+ slv->viewport()->setUpdatesEnabled( TRUE );
+ slv->setUpdatesEnabled( TRUE );
+ lv->viewport()->setUpdatesEnabled( TRUE );
+ lv->setUpdatesEnabled( TRUE );
+ setEnabled( TRUE );
+ slv->repaint();
+ slv->viewport()->repaint();
+ lv->triggerUpdate();
+ updateProgress();
+ filename = name;
+ dirty = FALSE;
+ updateCaption();
+ me->showNothing();
+ doneAndNextAct->setEnabled( FALSE );
+ doneAndNextAlt->setEnabled( FALSE );
+ messageIsShown = FALSE;
+ statusBar()->message(
+ tr("%1 source phrase(s) loaded.").arg(numMessages),
+ MessageMS );
+
+ foundItem = 0;
+ foundWhere = 0;
+ foundOffset = 0;
+ if ( lv->childCount() > 0 ) {
+ findAct->setEnabled( TRUE );
+ findAgainAct->setEnabled( FALSE );
+#ifdef notyet
+ replaceAct->setEnabled( TRUE );
+#endif
+ lv->setCurrentItem( lv->firstChild() );
+ }
+ addRecentlyOpenedFile( name, recentFiles );
+ updateStatistics();
+ } else {
+ statusBar()->clear();
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("Cannot open '%1'.").arg(name) );
+ }
+ }
+}
+
+void TrWindow::open()
+{
+ if ( maybeSave() ) {
+ QString newFilename = QFileDialog::getOpenFileName( filename,
+ tr("Qt translation source (*.ts)\n"
+ "All files (*)"),
+ this, "open" );
+ openFile( newFilename );
+ }
+}
+
+void TrWindow::save()
+{
+ if ( filename.isEmpty() )
+ return;
+
+ if ( tor.save(filename) ) {
+ dirty = FALSE;
+ updateCaption();
+ statusBar()->message( tr("File saved."), MessageMS );
+ } else {
+ QMessageBox::warning( this, tr("Qt Linguist"), tr("Cannot save '%1'.")
+ .arg(filename) );
+ }
+}
+
+void TrWindow::saveAs()
+{
+ QString newFilename = QFileDialog::getSaveFileName( filename,
+ tr( "Qt translation source (*.ts)\n"
+ "All files (*)"),
+ this, "save_as" );
+ if ( !newFilename.isEmpty() ) {
+ filename = newFilename;
+ save();
+ updateCaption();
+ }
+}
+
+void TrWindow::release()
+{
+ QString newFilename = filename;
+ newFilename.replace( QRegExp(".ts$"), "" );
+ newFilename += QString( ".qm" );
+
+ newFilename = QFileDialog::getSaveFileName( newFilename,
+ tr("Qt message files for released applications (*.qm)\n"
+ "All files (*)"),
+ this, "release",
+ tr("Release") );
+ if ( !newFilename.isEmpty() ) {
+ if ( tor.release(newFilename) )
+ statusBar()->message( tr("File created."), MessageMS );
+ else
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("Cannot save '%1'.").arg(newFilename) );
+ }
+}
+
+void TrWindow::print()
+{
+ int pageNum = 0;
+
+ if ( printer.setup(this) ) {
+ QApplication::setOverrideCursor( WaitCursor );
+ printer.setDocName( filename );
+ statusBar()->message( tr("Printing...") );
+ PrintOut pout( &printer );
+ ContextLVI *c = (ContextLVI *) lv->firstChild();
+ while ( c != 0 ) {
+ setCurrentContextItem( c );
+ pout.vskip();
+ pout.setRule( PrintOut::ThickRule );
+ pout.setGuide( c->context() );
+ pout.addBox( 100, tr("Context: %1").arg(c->context()),
+ PrintOut::Strong );
+ pout.flushLine();
+ pout.addBox( 4 );
+ pout.addBox( 92, c->comment(), PrintOut::Emphasis );
+ pout.flushLine();
+ pout.setRule( PrintOut::ThickRule );
+
+ MessageLVI *m = (MessageLVI *) slv->firstChild();
+ while ( m != 0 ) {
+ pout.setRule( PrintOut::ThinRule );
+
+ QString type;
+ switch ( m->message().type() ) {
+ case MetaTranslatorMessage::Finished:
+ type = tr( "finished" );
+ break;
+ case MetaTranslatorMessage::Unfinished:
+ type = m->danger() ? tr( "unresolved" ) : QString( "unfinished" );
+ break;
+ case MetaTranslatorMessage::Obsolete:
+ type = tr( "obsolete" );
+ break;
+ default:
+ type = QString( "" );
+ }
+ pout.addBox( 40, m->sourceText() );
+ pout.addBox( 4 );
+ pout.addBox( 40, m->translation() );
+ pout.addBox( 4 );
+ pout.addBox( 12, type, PrintOut::Normal, Qt::AlignRight );
+ if ( !m->comment().isEmpty() ) {
+ pout.flushLine();
+ pout.addBox( 4 );
+ pout.addBox( 92, m->comment(), PrintOut::Emphasis );
+ }
+ pout.flushLine( TRUE );
+
+ if ( pout.pageNum() != pageNum ) {
+ pageNum = pout.pageNum();
+ statusBar()->message( tr("Printing... (page %1)")
+ .arg(pageNum) );
+ }
+ m = (MessageLVI *) m->nextSibling();
+ }
+ c = (ContextLVI *) c->nextSibling();
+ }
+ pout.flushLine( TRUE );
+ QApplication::restoreOverrideCursor();
+ statusBar()->message( tr("Printing completed"), MessageMS );
+ } else {
+ statusBar()->message( tr("Printing aborted"), MessageMS );
+ }
+}
+
+void TrWindow::find()
+{
+ h->hide();
+ f->show();
+ f->setActiveWindow();
+ f->raise();
+}
+
+void TrWindow::findAgain()
+{
+ int pass = 0;
+ int oldItemNo = itemToIndex( slv, slv->currentItem() );
+ QString delayedMsg;
+ QListViewItem * j = foundScope;
+ QListViewItem * k = indexToItem( slv, foundItem );
+ QListViewItem * oldScope = lv->currentItem();
+
+ if ( lv->childCount() == 0 )
+ return;
+#if 1
+ /*
+ As long as we don't implement highlighting of the text in the QTextView,
+ we may have only one match per message.
+ */
+ foundOffset = (int) 0x7fffffff;
+#else
+ foundOffset++;
+#endif
+ slv->setUpdatesEnabled( FALSE );
+ do {
+ // Iterate through every item in all contexts
+ if ( j == 0 ) {
+ j = lv->firstChild();
+ setCurrentContextItem( j );
+ if ( foundScope != 0 )
+ delayedMsg = tr("Search wrapped.");
+ }
+ if ( k == 0 )
+ k = slv->firstChild();
+
+ while ( k ) {
+ MessageLVI * m = (MessageLVI *) k;
+ switch ( foundWhere ) {
+ case 0:
+ foundWhere = FindDialog::SourceText;
+ foundOffset = 0;
+ // fall-through
+ case FindDialog::SourceText:
+ if ( searchItem( m->sourceText(), j, k ) ) {
+ f->hide();
+ if ( !delayedMsg.isEmpty() )
+ statusBar()->message( delayedMsg, MessageMS );
+ return;
+ }
+ foundWhere = FindDialog::Translations;
+ foundOffset = 0;
+ // fall-through
+ case FindDialog::Translations:
+ if ( searchItem( m->translation(), j, k ) ) {
+ f->hide();
+ if ( !delayedMsg.isEmpty() )
+ statusBar()->message( delayedMsg, MessageMS );
+ return;
+ }
+ foundWhere = FindDialog::Comments;
+ foundOffset = 0;
+ // fall-through
+ case FindDialog::Comments:
+ if ( searchItem( ((ContextLVI *) j)->fullContext(), j, k) ) {
+ f->hide();
+ if ( !delayedMsg.isEmpty() )
+ statusBar()->message( delayedMsg, MessageMS );
+ return;
+ }
+ foundWhere = 0;
+ foundOffset = 0;
+ }
+ k = k->nextSibling();
+ }
+
+ j = j->nextSibling();
+ if ( j ) {
+ setCurrentContextItem( j );
+ k = slv->firstChild();
+ }
+ } while ( pass++ != lv->childCount() );
+
+ // This is just to keep the current scope and source text item
+ // selected after a search failed.
+ if ( oldScope ) {
+ setCurrentContextItem( oldScope );
+ QListViewItem * tmp = indexToItem( slv, oldItemNo );
+ if( tmp )
+ setCurrentMessageItem( tmp );
+ } else {
+ if( lv->firstChild() )
+ setCurrentContextItem( lv->firstChild() );
+ if( slv->firstChild() )
+ setCurrentMessageItem( slv->firstChild() );
+ }
+
+ slv->setUpdatesEnabled( TRUE );
+ slv->triggerUpdate();
+ qApp->beep();
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ QString( tr("Cannot find the string '%1'.") ).arg(findText) );
+ foundItem = 0;
+ foundWhere = 0;
+ foundOffset = 0;
+}
+
+void TrWindow::replace()
+{
+ f->hide();
+ h->show();
+ h->setActiveWindow();
+ h->raise();
+}
+
+int TrWindow::itemToIndex( QListView * view, QListViewItem * item )
+{
+ int no = 0;
+ QListViewItem * tmp;
+
+ if( view && item ){
+ if( (tmp = view->firstChild()) != 0 )
+ do {
+ no++;
+ tmp = tmp->nextSibling();
+ } while( tmp && (tmp != item) );
+ }
+ return no;
+}
+
+QListViewItem * TrWindow::indexToItem( QListView * view, int index )
+{
+ QListViewItem * item = 0;
+
+ if ( view && index > 0 ) {
+ item = view->firstChild();
+ while( item && index-- > 0 )
+ item = item->nextSibling();
+ }
+ return item;
+}
+
+bool TrWindow::searchItem( const QString & searchWhat, QListViewItem * j,
+ QListViewItem * k )
+{
+ if ( (findWhere & foundWhere) != 0 ) {
+ foundOffset = searchWhat.find( findText, foundOffset, findMatchCase );
+ if ( foundOffset >= 0 ) {
+ foundItem = itemToIndex( slv, k );
+ foundScope = j;
+ setCurrentMessageItem( k );
+ slv->setUpdatesEnabled( TRUE );
+ slv->triggerUpdate();
+ return TRUE;
+ }
+ }
+ foundOffset = 0;
+ return FALSE;
+}
+
+void TrWindow::newPhraseBook()
+{
+ QString name;
+ for (;;) {
+ name = QFileDialog::getSaveFileName( QString::null,
+ tr("Qt phrase books (*.qph)\n"
+ "All files (*)"),
+ this, "new_phrasebook",
+ tr("Create New Phrase Book") );
+ if ( !QFile::exists(name) )
+ break;
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("A file called '%1' already exists."
+ " Please choose another name.").arg(name) );
+ }
+ if ( !name.isEmpty() ) {
+ PhraseBook pb;
+ if ( savePhraseBook(name, pb) ) {
+ if ( openPhraseBook(name) )
+ statusBar()->message( tr("Phrase book created."), MessageMS );
+ }
+ }
+}
+
+void TrWindow::openPhraseBook()
+{
+ QString phrasebooks( qInstallPathData() );
+ QString name = QFileDialog::getOpenFileName( phrasebooks + "/phrasebooks",
+ tr("Qt phrase books (*.qph)\n"
+ "All files (*)"),
+ this, "open_phrasebook",
+ tr("Open Phrase Book") );
+ if ( !name.isEmpty() && !phraseBookNames.contains(name) ) {
+ if ( openPhraseBook(name) ) {
+ int n = (int)(phraseBooks.at( phraseBooks.count() - 1 )->count());
+ statusBar()->message( tr("%1 phrase(s) loaded.").arg(n),
+ MessageMS );
+ }
+ }
+}
+
+void TrWindow::closePhraseBook( int id )
+{
+ int index = closePhraseBookp->indexOf( id );
+ phraseBooks.remove( index );
+ phraseBookNames.remove( phraseBookNames.at(index) );
+ updatePhraseDict();
+
+ dirtyItem = index; // remove the item next time the menu is opened
+ editPhraseBookp->removeItem( editPhraseBookp->idAt(index) );
+ printPhraseBookp->removeItem( printPhraseBookp->idAt(index) );
+}
+
+void TrWindow::editPhraseBook( int id )
+{
+ int index = editPhraseBookp->indexOf( id );
+ PhraseBookBox box( phraseBookNames[index], *phraseBooks.at(index), this,
+ "phrase book box", TRUE );
+ box.setCaption( tr("%1 - %2").arg(tr("Qt Linguist"))
+ .arg(friendlyPhraseBookName(index)) );
+ box.resize( 500, 300 );
+ box.exec();
+ *phraseBooks.at( index ) = box.phraseBook();
+ updatePhraseDict();
+}
+
+void TrWindow::printPhraseBook( int id )
+{
+ int index = printPhraseBookp->indexOf( id );
+ int pageNum = 0;
+
+ if ( printer.setup(this) ) {
+ printer.setDocName( phraseBookNames[index] );
+ statusBar()->message( tr("Printing...") );
+ PrintOut pout( &printer );
+ PhraseBook *phraseBook = phraseBooks.at( index );
+ PhraseBook::Iterator p;
+ pout.setRule( PrintOut::ThinRule );
+ for ( p = phraseBook->begin(); p != phraseBook->end(); ++p ) {
+ pout.setGuide( (*p).source() );
+ pout.addBox( 29, (*p).source() );
+ pout.addBox( 4 );
+ pout.addBox( 29, (*p).target() );
+ pout.addBox( 4 );
+ pout.addBox( 34, (*p).definition(), PrintOut::Emphasis );
+
+ if ( pout.pageNum() != pageNum ) {
+ pageNum = pout.pageNum();
+ statusBar()->message( tr("Printing... (page %1)")
+ .arg(pageNum) );
+ }
+ pout.setRule( PrintOut::NoRule );
+ pout.flushLine( TRUE );
+ }
+ pout.flushLine( TRUE );
+ statusBar()->message( tr("Printing completed"), MessageMS );
+ } else {
+ statusBar()->message( tr("Printing aborted"), MessageMS );
+ }
+}
+
+void TrWindow::revertSorting()
+{
+ lv->setSorting( 0 );
+ slv->setSorting( 0 );
+}
+
+void TrWindow::manual()
+{
+ QAssistantClient *ac = new QAssistantClient( qInstallPathBins(), this );
+ ac->showPage( QString( qInstallPathDocs() ) + "/html/linguist-manual.html" );
+}
+
+void TrWindow::about()
+{
+ AboutDialog about( this, 0, TRUE );
+ about.versionLabel->setText( tr("Version %1").arg(QT_VERSION_STR) );
+ about.exec();
+}
+
+void TrWindow::aboutQt()
+{
+ QMessageBox::aboutQt( this, tr("Qt Linguist") );
+}
+
+void TrWindow::setupPhrase()
+{
+ bool enabled = !phraseBooks.isEmpty();
+ phrasep->setItemEnabled( closePhraseBookId, enabled );
+ phrasep->setItemEnabled( editPhraseBookId, enabled );
+ phrasep->setItemEnabled( printPhraseBookId, enabled );
+}
+
+void TrWindow::closeEvent( QCloseEvent *e )
+{
+ if ( maybeSave() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+bool TrWindow::maybeSave()
+{
+ if ( dirty ) {
+ switch ( QMessageBox::information(this, tr("Qt Linguist"),
+ tr("Do you want to save '%1'?")
+ .arg(filename),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape ) )
+ {
+ case QMessageBox::Cancel:
+ return FALSE;
+ case QMessageBox::Yes:
+ save();
+ return !dirty;
+ case QMessageBox::No:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+void TrWindow::updateCaption()
+{
+ QString cap;
+ bool enable = !filename.isEmpty();
+ saveAct->setEnabled( enable );
+ saveAsAct->setEnabled( enable );
+ releaseAct->setEnabled( enable );
+ printAct->setEnabled( enable );
+ acceleratorsAct->setEnabled( enable );
+ endingPunctuationAct->setEnabled( enable );
+ phraseMatchesAct->setEnabled( enable );
+ revertSortingAct->setEnabled( enable );
+
+ if ( filename.isEmpty() )
+ cap = tr( "Qt Linguist by Trolltech" );
+ else
+ cap = tr( "%1 - %2" ).arg( tr("Qt Linguist by Trolltech") )
+ .arg( filename );
+ setCaption( cap );
+ modified->setEnabled( dirty );
+}
+
+//
+// New scope selected - build a new list of source text items
+// for that scope.
+//
+void TrWindow::showNewScope( QListViewItem *item )
+{
+ static ContextLVI * oldContext = 0;
+
+ if( item != 0 ) {
+ ContextLVI * c = (ContextLVI *) item;
+ bool upe = slv->isUpdatesEnabled();
+ slv->setUpdatesEnabled( FALSE );
+ slv->viewport()->setUpdatesEnabled( FALSE );
+ if ( oldContext != 0 ) {
+ MessageLVI * tmp;
+ slv->blockSignals( TRUE );
+ while ( (tmp = (MessageLVI *) slv->firstChild()) != 0 )
+ oldContext->appendMessageItem( slv, tmp );
+ slv->blockSignals( FALSE );
+ }
+ MessageLVI * tmp;
+ while ( c->messageItemsInList() ) {
+ tmp = c->takeMessageItem( c->messageItemsInList() - 1);
+ slv->insertItem( tmp );
+ tmp->updateTranslationText();
+ }
+
+ // Make sure that we update the source text and translation text. Use the first message in the new scope.
+ setCurrentMessageItem(slv->firstChild());
+ // This must be explicitly called since the signal is not emitted if the context only contains one item
+ showNewCurrent(slv->firstChild());
+ slv->viewport()->setUpdatesEnabled( upe );
+ slv->setUpdatesEnabled( upe );
+ if( upe )
+ slv->triggerUpdate();
+ oldContext = (ContextLVI *) item;
+ statusBar()->clear();
+ }
+}
+
+void TrWindow::showNewCurrent( QListViewItem *item )
+{
+ messageIsShown = (item != 0);
+ MessageLVI *m = (MessageLVI *) item;
+ ContextLVI *c = (ContextLVI *) m ? m->contextLVI() : 0;
+
+ if ( messageIsShown ) {
+ me->showMessage( m->sourceText(), m->comment(), c->fullContext(),
+ m->translation(), m->message().type(),
+ getPhrases(m->sourceText()) );
+ if ( (m->message().type() != MetaTranslatorMessage::Finished) &&
+ m->danger() )
+ danger( m->sourceText(), m->translation(), TRUE );
+ else
+ statusBar()->clear();
+
+ doneAndNextAct->setEnabled( m->message().type() !=
+ MetaTranslatorMessage::Obsolete );
+ } else {
+ if ( item == 0 )
+ me->showNothing();
+ else
+ me->showContext( c->fullContext(), c->finished() );
+ doneAndNextAct->setEnabled( FALSE );
+ }
+ doneAndNextAlt->setEnabled( doneAndNextAct->isEnabled() );
+
+ selectAllAct->setEnabled( messageIsShown );
+}
+
+void TrWindow::updateTranslation( const QString& translation )
+{
+ QListViewItem *item = slv->currentItem();
+ if ( item != 0 ) {
+ MessageLVI *m = (MessageLVI *) item;
+ if ( translation != m->translation() ) {
+ bool dngr;
+ m->setTranslation( translation );
+ if ( m->finished() &&
+ (dngr = danger( m->sourceText(), m->translation(), TRUE )) ) {
+ numFinished -= 1;
+ m->setDanger( dngr );
+ m->setFinished( FALSE );
+ m->contextLVI()->updateStatus();
+ updateProgress();
+ }
+ tor.insert( m->message() );
+ if ( !dirty ) {
+ dirty = TRUE;
+ updateCaption();
+ }
+ m->updateTranslationText();
+ }
+ }
+}
+
+void TrWindow::updateFinished( bool finished )
+{
+ QListViewItem *item = slv->currentItem();
+ if ( item != 0 ) {
+ MessageLVI *m = (MessageLVI *) item;
+ if ( finished != m->finished() ) {
+ numFinished += finished ? +1 : -1;
+ updateProgress();
+ m->setFinished( finished );
+ bool oldDanger = m->danger();
+ m->setDanger( /*m->finished() &&*/
+ danger(m->sourceText(), m->translation(),
+ !oldDanger) );
+ if ( !oldDanger && m->danger() )
+ qApp->beep();
+ tor.insert( m->message() );
+ if ( !dirty ) {
+ dirty = TRUE;
+ updateCaption();
+ }
+ }
+ }
+}
+
+void TrWindow::doneAndNext()
+{
+ MessageLVI * m = (MessageLVI *) slv->currentItem();
+ bool dngr = FALSE;
+
+ if ( !m ) return;
+ dngr = danger( m->sourceText(), m->translation(), TRUE );
+ if ( !dngr ) {
+ me->finishAndNext();
+ m->contextLVI()->updateStatus();
+ } else {
+ if ( m->danger() != dngr )
+ m->setDanger( dngr );
+ tor.insert( m->message() );
+ if ( !dirty ) {
+ dirty = TRUE;
+ updateCaption();
+ }
+ qApp->beep();
+ }
+ updateStatistics();
+}
+
+void TrWindow::toggleFinished( QListViewItem *item, const QPoint& /* p */,
+ int column )
+{
+ if ( item != 0 && column == 0 ) {
+ MessageLVI *m = (MessageLVI *) item;
+ bool dngr = FALSE;
+
+ if ( m->message().type() == MetaTranslatorMessage::Unfinished ) {
+ dngr = danger( m->sourceText(), m->translation(), TRUE );
+ }
+ if ( !dngr && m->message().type() != MetaTranslatorMessage::Obsolete) {
+ setCurrentMessageItem( m );
+ me->setFinished( !m->finished() );
+ m->contextLVI()->updateStatus();
+ } else {
+ bool oldDanger = m->danger();
+ m->setDanger( danger(m->sourceText(), m->translation(),
+ !oldDanger) );
+ if ( !oldDanger && m->danger() )
+ qApp->beep();
+ tor.insert( m->message() );
+ if ( !dirty ) {
+ dirty = TRUE;
+ updateCaption();
+ }
+ }
+ updateStatistics();
+ }
+}
+
+void TrWindow::nextUnfinished()
+{
+ if ( nextUnfinishedAct->isEnabled() ) {
+ // Select a message to translate, grab the first available if
+ // there are no current selection.
+ QListViewItem * cItem = lv->currentItem(); // context item
+ QListViewItem * mItem = slv->currentItem(); // message item
+
+ // Make sure an item is selected from both the context and the
+ // message list.
+ if( (mItem == 0) && !(mItem = slv->firstChild()) ) {
+ if( (cItem == 0) && !(cItem = lv->firstChild()) ) {
+ statusBar()->message( tr("No phrase to translate."),
+ MessageMS );
+ qApp->beep();
+ return;
+ } else {
+ showNewScope( cItem );
+ while( cItem && !(mItem = slv->firstChild()) ) {
+ // no children in this node - try next one
+ cItem = cItem->nextSibling();
+ showNewScope( cItem );
+ }
+ setCurrentContextItem( cItem );
+ if( mItem ) {
+ setCurrentMessageItem( mItem );
+ } else {
+ statusBar()->message( tr("No phrase to translate."),
+ MessageMS );
+ qApp->beep();
+ return;
+ }
+ }
+ } else {
+ setCurrentMessageItem( mItem );
+ }
+
+ MessageLVI * m = (MessageLVI *) mItem;
+ MessageLVI * n;
+ ContextLVI * p = (ContextLVI *) cItem;
+ ContextLVI * q;
+
+ // Find the next Unfinished sibling within the same context.
+ m = (MessageLVI *) mItem->nextSibling();
+ n = m;
+ do {
+ if ( n == 0 )
+ break;
+ if ( n && !n->finished() && n != mItem ) {
+ setCurrentMessageItem( n );
+ return;
+ }
+ n = (MessageLVI *) n->nextSibling();
+ } while ( n != m );
+
+ // If all siblings are Finished or Obsolete, look in the first
+ // Unfinished context.
+ p = (ContextLVI *) p->nextSibling();
+ q = p;
+ do {
+ if ( q == 0 )
+ q = (ContextLVI *) lv->firstChild();
+ if ( q && !q->finished() ) {
+ showNewScope( q );
+ setCurrentContextItem( q );
+ n = (MessageLVI *) slv->firstChild();
+ while ( n && n->finished() )
+ n = (MessageLVI *) n->nextSibling();
+ if ( n && q ) {
+ setCurrentMessageItem( n );
+ showNewCurrent( n );
+ return;
+ }
+ }
+ q = (ContextLVI *) q->nextSibling();
+ } while ( q != p );
+ }
+
+ // If no Unfinished message is left, the user has finished the job. We
+ // congratulate on a job well done with this ringing bell.
+ statusBar()->message( tr("No untranslated phrases left."), MessageMS );
+ qApp->beep();
+}
+
+static QListViewItem * lastChild( QListView * view )
+{
+ if ( view ) {
+ QListViewItem * ret, * tmp;
+ ret = view->firstChild();
+ while ( ret ) {
+ tmp = ret->nextSibling();
+ if ( tmp == 0 )
+ return ret;
+ ret = tmp;
+ }
+ }
+ return 0;
+}
+
+void TrWindow::prevUnfinished()
+{
+ if ( prevUnfinishedAct->isEnabled() ) {
+ // Select a message to translate, grab the first available if
+ // there are no current selection.
+ QListViewItem * cItem = lv->currentItem(); // context item
+ QListViewItem * mItem = slv->currentItem(); // message item
+
+ // Make sure an item is selected from both the context and the
+ // message list.
+ if( (mItem == 0) && !(mItem = slv->firstChild()) ) {
+ if( (cItem == 0) && !(cItem = lv->firstChild()) ) {
+ statusBar()->message( tr("No phrase to translate."),
+ MessageMS );
+ qApp->beep();
+ return;
+ } else {
+ showNewScope( cItem );
+ while( cItem && !(mItem = slv->firstChild()) ) {
+ // no children in this node - try next one
+ cItem = cItem->nextSibling();
+ showNewScope( cItem );
+ }
+ setCurrentContextItem( cItem );
+ if( mItem ) {
+ setCurrentMessageItem( cItem );
+ } else {
+ statusBar()->message( tr("No phrase to translate."),
+ MessageMS );
+ qApp->beep();
+ return;
+ }
+ }
+ } else {
+ setCurrentMessageItem( mItem );
+ }
+
+ MessageLVI * m = (MessageLVI *) mItem;
+ MessageLVI * n;
+ ContextLVI * p = (ContextLVI *) cItem;
+ ContextLVI * q;
+
+ // Find the next Unfinished sibling within the same context.
+ n = m;
+ do {
+ n = (MessageLVI * ) n->itemAbove();
+ if ( n == 0 )
+ break;
+ if ( n && !n->finished() ) {
+ setCurrentMessageItem( n );
+ return;
+ }
+ } while ( !((ContextLVI *) cItem)->finished() && n != 0 );
+
+ // If all siblings are Finished or Obsolete, look in the prev
+ // Unfinished context.
+ q = p;
+ do {
+ q = (ContextLVI *) q->itemAbove();
+ if ( q == 0 )
+ q = (ContextLVI *) lastChild( lv );
+ if ( q && !q->finished() ) {
+ showNewScope( q );
+ setCurrentContextItem( q );
+ n = (MessageLVI *) lastChild( slv );
+ while ( n && n->finished() )
+ n = (MessageLVI *) n->itemAbove();
+ if ( n && q ) {
+ setCurrentMessageItem( n );
+ return;
+ }
+ }
+ } while ( q != 0 );
+ }
+ statusBar()->message( tr("No untranslated phrases left."), MessageMS );
+ qApp->beep();
+}
+
+void TrWindow::prev()
+{
+ QListViewItem * cItem = lv->currentItem(); // context item
+ QListViewItem * mItem = slv->currentItem(); // message item
+ QListViewItem * tmp;
+
+ if ( !cItem ) {
+ cItem = lv->firstChild();
+ if ( !cItem ) return;
+ setCurrentContextItem( cItem );
+ }
+
+ if ( !mItem ) {
+ mItem = lastChild( slv );
+ if ( !mItem ) return;
+ setCurrentMessageItem( mItem );
+ } else {
+ if ( (tmp = mItem->itemAbove()) != 0 ) {
+ setCurrentMessageItem( tmp );
+ return;
+ } else {
+ if ( (tmp = cItem->itemAbove()) == 0 ) {
+ tmp = lastChild( lv );
+ }
+ if ( !tmp ) return;
+ setCurrentContextItem( tmp );
+ setCurrentMessageItem( lastChild( slv ) );
+ }
+ }
+}
+
+void TrWindow::next()
+{
+ QListViewItem * cItem = lv->currentItem(); // context item
+ QListViewItem * mItem = slv->currentItem(); // message item
+ QListViewItem * tmp;
+
+ if ( !cItem ) {
+ cItem = lv->firstChild();
+ if ( !cItem ) return;
+ setCurrentContextItem( cItem );
+ }
+
+ if ( !mItem ) {
+ mItem = slv->firstChild();
+ if ( !mItem ) return;
+ setCurrentMessageItem( mItem );
+ } else {
+ if ( (tmp = mItem->nextSibling()) != 0 ) {
+ setCurrentMessageItem( tmp );
+ return;
+ } else {
+ if ( (tmp = cItem->nextSibling()) == 0 ) {
+ tmp = lv->firstChild();
+ }
+ if ( !tmp ) return;
+ setCurrentContextItem( tmp );
+ setCurrentMessageItem( slv->firstChild() );
+ }
+ }
+}
+
+
+void TrWindow::findNext( const QString& text, int where, bool matchCase )
+{
+ findText = text;
+ if ( findText.isEmpty() )
+ findText = QString( "magicwordthatyoushouldavoid" );
+ findWhere = where;
+ findMatchCase = matchCase;
+ findAgainAct->setEnabled( TRUE );
+ findAgain();
+}
+
+void TrWindow::revalidate()
+{
+ ContextLVI *c = (ContextLVI *) lv->firstChild();
+ QListViewItem * oldScope = lv->currentItem();
+ int oldItemNo = itemToIndex( slv, slv->currentItem() );
+ slv->setUpdatesEnabled( FALSE );
+
+ while ( c != 0 ) {
+ showNewScope( c );
+ MessageLVI *m = (MessageLVI *) slv->firstChild();
+ while ( m != 0 ) {
+ m->setDanger( danger(m->sourceText(), m->translation()) &&
+ m->message().type() == MetaTranslatorMessage::Finished );
+ m = (MessageLVI *) m->nextSibling();
+ }
+ c = (ContextLVI *) c->nextSibling();
+ }
+
+ if ( oldScope ){
+ showNewScope( oldScope );
+ QListViewItem * tmp = indexToItem( slv, oldItemNo );
+ if( tmp )
+ setCurrentMessageItem( tmp );
+ }
+ slv->setUpdatesEnabled( TRUE );
+ slv->triggerUpdate();
+}
+
+QString TrWindow::friendlyString( const QString& str )
+{
+ QString f = str.lower();
+ f.replace( QRegExp(QString("[.,:;!?()-]")), QString(" ") );
+ f.replace( "&", QString("") );
+ f = f.simplifyWhiteSpace();
+ f = f.lower();
+ return f;
+}
+
+void TrWindow::setupMenuBar()
+{
+ QMenuBar * m = menuBar();
+ QPopupMenu * filep = new QPopupMenu( this );
+ QPopupMenu * editp = new QPopupMenu( this );
+ QPopupMenu * translationp = new QPopupMenu( this );
+ QPopupMenu * validationp = new QPopupMenu( this );
+ validationp->setCheckable( TRUE );
+ phrasep = new QPopupMenu( this );
+ closePhraseBookp = new QPopupMenu( this );
+ editPhraseBookp = new QPopupMenu( this );
+ printPhraseBookp = new QPopupMenu( this );
+ QPopupMenu * viewp = new QPopupMenu( this );
+ viewp->setCheckable( TRUE );
+ QPopupMenu * helpp = new QPopupMenu( this );
+
+ m->insertItem( tr("&File"), filep );
+ m->insertItem( tr("&Edit"), editp );
+ m->insertItem( tr("&Translation"), translationp );
+ m->insertItem( tr("V&alidation"), validationp );
+ m->insertItem( tr("&Phrases"), phrasep );
+ m->insertItem( tr("&View"), viewp );
+ m->insertSeparator();
+ m->insertItem( tr("&Help"), helpp );
+
+ connect( closePhraseBookp, SIGNAL(activated(int)),
+ this, SLOT(closePhraseBook(int)) );
+ connect( closePhraseBookp, SIGNAL(aboutToShow()),
+ this, SLOT(updateClosePhraseBook()) );
+ connect( editPhraseBookp, SIGNAL(activated(int)),
+ this, SLOT(editPhraseBook(int)) );
+ connect( printPhraseBookp, SIGNAL(activated(int)),
+ this, SLOT(printPhraseBook(int)) );
+ // File menu
+ openAct = new Action( filep, tr("&Open..."), this, SLOT(open()),
+ "fileopen.png", QAccel::stringToKey(tr("Ctrl+O")) );
+
+ filep->insertSeparator();
+
+ saveAct = new Action( filep, tr("&Save"), this, SLOT(save()),
+ "filesave.png", QAccel::stringToKey(tr("Ctrl+S")) );
+ saveAsAct = new Action( filep, tr("Save &As..."), this, SLOT(saveAs()) );
+ releaseAct = new Action( filep, tr("&Release..."), this, SLOT(release()) );
+ filep->insertSeparator();
+ printAct = new Action( filep, tr("&Print..."), this, SLOT(print()),
+ "print.png", QAccel::stringToKey(tr("Ctrl+P")) );
+
+ filep->insertSeparator();
+
+ recentFilesMenu = new QPopupMenu( this );
+ filep->insertItem( tr("Re&cently opened files"), recentFilesMenu );
+ connect( recentFilesMenu, SIGNAL(aboutToShow()), this,
+ SLOT(setupRecentFilesMenu()) );
+ connect( recentFilesMenu, SIGNAL(activated( int )), this,
+ SLOT(recentFileActivated( int )) );
+
+ filep->insertSeparator();
+
+ exitAct = new Action( filep, tr("E&xit"), this, SLOT(close()),
+ QString::null, QAccel::stringToKey(tr("Ctrl+Q")) );
+ // Edit menu
+ undoAct = new Action( editp, tr("&Undo"), me, SLOT(undo()),
+ "undo.png", QAccel::stringToKey(tr("Ctrl+Z")) );
+ undoAct->setEnabled( FALSE );
+ connect( me, SIGNAL(undoAvailable(bool)), undoAct, SLOT(setEnabled(bool)) );
+ redoAct = new Action( editp, tr("&Redo"), me, SLOT(redo()),
+ "redo.png", QAccel::stringToKey(tr("Ctrl+Y")) );
+ redoAct->setEnabled( FALSE );
+ connect( me, SIGNAL(redoAvailable(bool)), redoAct, SLOT(setEnabled(bool)) );
+ editp->insertSeparator();
+ cutAct = new Action( editp, tr("Cu&t"), me, SLOT(cut()),
+ "editcut.png", QAccel::stringToKey(tr("Ctrl+X")) );
+ cutAct->setEnabled( FALSE );
+ connect( me, SIGNAL(cutAvailable(bool)), cutAct, SLOT(setEnabled(bool)) );
+ copyAct = new Action( editp, tr("&Copy"), me, SLOT(copy()),
+ "editcopy.png", QAccel::stringToKey(tr("Ctrl+C")) );
+ copyAct->setEnabled( FALSE );
+ connect( me, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool)) );
+ pasteAct = new Action( editp, tr("&Paste"), me, SLOT(paste()),
+ "editpaste.png", QAccel::stringToKey(tr("Ctrl+V")) );
+ pasteAct->setEnabled( FALSE );
+ connect( me, SIGNAL(pasteAvailable(bool)),
+ pasteAct, SLOT(setEnabled(bool)) );
+ selectAllAct = new Action( editp, tr("Select &All"), me, SLOT(selectAll()),
+ QString::null, QAccel::stringToKey(tr("Ctrl+A")) );
+ selectAllAct->setEnabled( FALSE );
+ editp->insertSeparator();
+ findAct = new Action( editp, tr("&Find..."), this, SLOT(find()),
+ "searchfind.png", QAccel::stringToKey(tr("Ctrl+F")) );
+ findAct->setEnabled( FALSE );
+ findAgainAct = new Action( editp, tr("Find &Next"),
+ this, SLOT(findAgain()), QString::null, Key_F3 );
+ findAgainAct->setEnabled( FALSE );
+#ifdef notyet
+ replaceAct = new Action( editp, tr("&Replace..."), this, SLOT(replace()),
+ QAccel::stringToKey(tr("Ctrl+H")) );
+ replaceAct->setEnabled( FALSE );
+#endif
+
+ // Translation menu
+ // when updating the accelerators, remember the status bar
+ prevUnfinishedAct = new Action( translationp, tr("&Prev Unfinished"),
+ this, SLOT(prevUnfinished()),
+ "prevunfinished.png", QAccel::stringToKey(tr("Ctrl+K")) );
+ nextUnfinishedAct = new Action( translationp, tr("&Next Unfinished"),
+ this, SLOT(nextUnfinished()),
+ "nextunfinished.png", QAccel::stringToKey(tr("Ctrl+L")) );
+
+ prevAct = new Action( translationp, tr("P&rev"),
+ this, SLOT(prev()), "prev.png",
+ QAccel::stringToKey(tr("Ctrl+Shift+K")) );
+ nextAct = new Action( translationp, tr("Ne&xt"),
+ this, SLOT(next()), "next.png",
+ QAccel::stringToKey(tr("Ctrl+Shift+L")) );
+ doneAndNextAct = new Action( translationp, tr("Done and &Next"),
+ this, SLOT(doneAndNext()), "doneandnext.png",
+ QAccel::stringToKey(tr("Ctrl+Enter")) );
+ doneAndNextAlt = new QAction( this );
+ doneAndNextAlt->setAccel( QAccel::stringToKey(tr("Ctrl+Return")) );
+ connect( doneAndNextAlt, SIGNAL(activated()), this, SLOT(doneAndNext()) );
+ beginFromSourceAct = new Action( translationp, tr("&Begin from Source"),
+ me, SLOT(beginFromSource()),
+ QString::null, QAccel::stringToKey(tr("Ctrl+B")) );
+ connect( me, SIGNAL(updateActions(bool)), beginFromSourceAct,
+ SLOT(setEnabled(bool)) );
+
+ // Phrasebook menu
+ newPhraseBookAct = new Action( phrasep, tr("&New Phrase Book..."),
+ this, SLOT(newPhraseBook()),
+ QString::null, QAccel::stringToKey(tr("Ctrl+N")) );
+ openPhraseBookAct = new Action( phrasep, tr("&Open Phrase Book..."),
+ this, SLOT(openPhraseBook()),
+ "book.png", QAccel::stringToKey(tr("Ctrl+H")) );
+ closePhraseBookId = phrasep->insertItem( tr("&Close Phrase Book"),
+ closePhraseBookp );
+ phrasep->insertSeparator();
+ editPhraseBookId = phrasep->insertItem( tr("&Edit Phrase Book..."),
+ editPhraseBookp );
+ printPhraseBookId = phrasep->insertItem( tr("&Print Phrase Book..."),
+ printPhraseBookp );
+ connect( phrasep, SIGNAL(aboutToShow()), this, SLOT(setupPhrase()) );
+
+ // Validation menu
+ acceleratorsAct = new Action( validationp, tr("&Accelerators"),
+ this, SLOT(revalidate()), "accelerator.png", 0, TRUE );
+ acceleratorsAct->setOn( TRUE );
+ endingPunctuationAct = new Action( validationp, tr("&Ending Punctuation"),
+ this, SLOT(revalidate()), "punctuation.png", 0, TRUE );
+ endingPunctuationAct->setOn( TRUE );
+ phraseMatchesAct = new Action( validationp, tr("&Phrase Matches"),
+ this, SLOT(revalidate()), "phrase.png", 0, TRUE );
+ phraseMatchesAct->setOn( TRUE );
+
+ // View menu
+ revertSortingAct = new Action( viewp, tr("&Revert Sorting"),
+ this, SLOT(revertSorting()) );
+ doGuessesAct = new Action( viewp, tr("&Display guesses"),
+ this, SLOT(toggleGuessing()) );
+ doGuessesAct->setToggleAction( TRUE );
+ doGuessesAct->setOn( TRUE );
+ toggleStats = new Action( viewp, tr("&Statistics"), this, SLOT(toggleStatistics()) );
+ toggleStats->setToggleAction( TRUE );
+ viewp->insertSeparator();
+ viewp->insertItem( tr("Vie&ws"), createDockWindowMenu( NoToolBars ) );
+ viewp->insertItem( tr("&Toolbars"), createDockWindowMenu( OnlyToolBars ) );
+
+ // Help
+ manualAct = new Action( helpp, tr("&Manual"), this, SLOT(manual()), 0,
+ Key_F1 );
+ helpp->insertSeparator();
+ aboutAct = new Action( helpp, tr("&About"), this, SLOT(about()) );
+ aboutQtAct = new Action( helpp, tr("About &Qt"), this, SLOT(aboutQt()) );
+ helpp->insertSeparator();
+ whatsThisAct = new Action( helpp, tr("&What's This?"),
+ this, SLOT(whatsThis()), "whatsthis.xpm", SHIFT + Key_F1 );
+
+ openAct->setWhatsThis( tr("Open a Qt translation source file (TS file) for"
+ " editing.") );
+ saveAct->setWhatsThis( tr("Save changes made to this Qt translation "
+ "source file.") );
+ saveAsAct->setWhatsThis( tr("Save changes made to this Qt translation"
+ "source file into a new file.") );
+ releaseAct->setWhatsThis( tr("Create a Qt message file suitable for"
+ " released applications"
+ " from the current message file.") );
+ printAct->setWhatsThis( tr("Print a list of all the phrases in the current"
+ " Qt translation source file.") );
+ exitAct->setWhatsThis( tr("Close this window and exit.") );
+
+ undoAct->setWhatsThis( tr("Undo the last editing operation performed on the"
+ " translation.") );
+ redoAct->setWhatsThis( tr("Redo an undone editing operation performed on"
+ " the translation.") );
+ cutAct->setWhatsThis( tr("Copy the selected translation text to the"
+ " clipboard and deletes it.") );
+ copyAct->setWhatsThis( tr("Copy the selected translation text to the"
+ " clipboard.") );
+ pasteAct->setWhatsThis( tr("Paste the clipboard text into the"
+ " translation.") );
+ selectAllAct->setWhatsThis( tr("Select the whole translation text.") );
+ findAct->setWhatsThis( tr("Search for some text in the translation "
+ "source file.") );
+ findAgainAct->setWhatsThis( tr("Continue the search where it was left.") );
+#ifdef notyet
+ replaceAct->setWhatsThis( tr("Search for some text in the translation"
+ " source file and replace it by another"
+ " text.") );
+#endif
+
+ newPhraseBookAct->setWhatsThis( tr("Create a new phrase book.") );
+ openPhraseBookAct->setWhatsThis( tr("Open a phrase book to assist"
+ " translation.") );
+ acceleratorsAct->setWhatsThis( tr("Toggle validity checks of"
+ " accelerators.") );
+ endingPunctuationAct->setWhatsThis( tr("Toggle validity checks"
+ " of ending punctuation.") );
+ phraseMatchesAct->setWhatsThis( tr("Toggle checking that phrase"
+ " suggestions are used.") );
+
+ revertSortingAct->setWhatsThis( tr("Sort the items back in the same order"
+ " as in the message file.") );
+
+ doGuessesAct->setWhatsThis( tr("Set whether or not to display translation guesses.") );
+ manualAct->setWhatsThis( tr("Display the manual for %1.")
+ .arg(tr("Qt Linguist")) );
+ aboutAct->setWhatsThis( tr("Display information about %1.")
+ .arg(tr("Qt Linguist")) );
+ aboutQtAct->setWhatsThis( tr("Display information about the Qt toolkit by"
+ " Trolltech.") );
+ whatsThisAct->setWhatsThis( tr("Enter What's This? mode.") );
+
+ beginFromSourceAct->setWhatsThis( tr("Copies the source text into"
+ " the translation field.") );
+ nextAct->setWhatsThis( tr("Moves to the next item.") );
+ prevAct->setWhatsThis( tr("Moves to the previous item.") );
+ nextUnfinishedAct->setWhatsThis( tr("Moves to the next unfinished item.") );
+ prevUnfinishedAct->setWhatsThis( tr("Moves to the previous unfinished item.") );
+ doneAndNextAct->setWhatsThis( tr("Marks this item as done and moves to the"
+ " next unfinished item.") );
+ doneAndNextAlt->setWhatsThis( doneAndNextAct->whatsThis() );
+}
+
+void TrWindow::setupToolBars()
+{
+ QToolBar *filet = new QToolBar( tr("File"), this );
+ QToolBar *editt = new QToolBar( tr("Edit"), this );
+ QToolBar *translationst = new QToolBar( tr("Translation"), this );
+ QToolBar *validationt = new QToolBar( tr("Validation"), this );
+ QToolBar *helpt = new QToolBar( tr("Help"), this );
+
+ openAct->addToToolbar( filet, tr("Open") );
+ saveAct->addToToolbar( filet, tr("Save") );
+ printAct->addToToolbar( filet, tr("Print") );
+ filet->addSeparator();
+ openPhraseBookAct->addToToolbar( filet, tr("Open Phrase Book") );
+
+ undoAct->addToToolbar( editt, tr("Undo") );
+ redoAct->addToToolbar( editt, tr("Redo") );
+ editt->addSeparator();
+ cutAct->addToToolbar( editt, tr("Cut") );
+ copyAct->addToToolbar( editt, tr("Copy") );
+ pasteAct->addToToolbar( editt, tr("Paste") );
+ editt->addSeparator();
+ findAct->addToToolbar( editt, tr("Find") );
+#ifdef notyet
+ replaceAct->addToToolbar( editt, tr("Replace") );
+#endif
+
+ // beginFromSourceAct->addToToolbar( translationst,
+ // tr("Begin from Source"), "searchfind" );
+ prevAct->addToToolbar( translationst, tr("Prev") );
+ nextAct->addToToolbar( translationst, tr("Next") );
+ prevUnfinishedAct->addToToolbar( translationst, tr("Prev Unfinished") );
+ nextUnfinishedAct->addToToolbar( translationst, tr("Next Unfinished") );
+ doneAndNextAct->addToToolbar( translationst, tr("Done and Next") );
+
+ acceleratorsAct->addToToolbar( validationt, tr("Accelerators") );
+ endingPunctuationAct->addToToolbar( validationt, tr("Punctuation") );
+ phraseMatchesAct->addToToolbar( validationt, tr("Phrases") );
+
+ whatsThisAct->addToToolbar( helpt, tr("What's This?") );
+}
+
+void TrWindow::setCurrentContextItem( QListViewItem *item )
+{
+ lv->ensureItemVisible( item );
+ lv->setSelected( item, TRUE );
+}
+
+void TrWindow::setCurrentMessageItem( QListViewItem *item )
+{
+ slv->ensureItemVisible( item );
+ slv->setSelected( item, TRUE );
+}
+
+QString TrWindow::friendlyPhraseBookName( int k )
+{
+ return QFileInfo( phraseBookNames[k] ).fileName();
+}
+
+bool TrWindow::openPhraseBook( const QString& name )
+{
+ PhraseBook *pb = new PhraseBook;
+ if ( !pb->load(name) ) {
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("Cannot read from phrase book '%1'.")
+ .arg(name) );
+ return FALSE;
+ }
+
+ int index = (int) phraseBooks.count();
+ phraseBooks.append( pb );
+ phraseBookNames.append( name );
+ int id = closePhraseBookp->insertItem( friendlyPhraseBookName(index) );
+ closePhraseBookp->setWhatsThis( id, tr("Close this phrase book.") );
+ id = editPhraseBookp->insertItem( friendlyPhraseBookName(index) );
+ editPhraseBookp->setWhatsThis( id, tr("Allow you to add, modify, or delete"
+ " phrases of this phrase book.") );
+ id = printPhraseBookp->insertItem( friendlyPhraseBookName(index) );
+ printPhraseBookp->setWhatsThis( id, tr("Print the entries of the phrase"
+ " book.") );
+ updatePhraseDict();
+ return TRUE;
+}
+
+bool TrWindow::savePhraseBook( QString& name, const PhraseBook& pb )
+{
+ if ( !name.contains( ".qph" ) && !name.contains(".") )
+ name += ".qph";
+
+ if ( !pb.save(name) ) {
+ QMessageBox::warning( this, tr("Qt Linguist"),
+ tr("Cannot create phrase book '%1'.")
+ .arg(name) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void TrWindow::updateProgress()
+{
+ if ( numNonobsolete == 0 )
+ progress->setText( QString(" " " ") );
+ else
+ progress->setText( QString(" %1/%2 ").arg(numFinished)
+ .arg(numNonobsolete) );
+ prevUnfinishedAct->setEnabled( numFinished != numNonobsolete );
+ nextUnfinishedAct->setEnabled( numFinished != numNonobsolete );
+ prevAct->setEnabled( lv->firstChild() != 0 );
+ nextAct->setEnabled( lv->firstChild() != 0 );
+}
+
+void TrWindow::updatePhraseDict()
+{
+ QPtrListIterator<PhraseBook> pb = phraseBooks;
+ PhraseBook::Iterator p;
+ PhraseBook *ent;
+ phraseDict.clear();
+ while ( pb.current() != 0 ) {
+ for ( p = (*pb)->begin(); p != (*pb)->end(); ++p ) {
+ QString f = friendlyString( (*p).source() );
+ if ( f.length() > 0 ) {
+ f = QStringList::split( QChar(' '), f ).first();
+ ent = phraseDict.find( f );
+ if ( ent == 0 ) {
+ ent = new PhraseBook;
+ phraseDict.insert( f, ent );
+ }
+ ent->append( *p );
+ }
+ }
+ ++pb;
+ }
+ revalidate();
+}
+
+PhraseBook TrWindow::getPhrases( const QString& source )
+{
+ PhraseBook phrases;
+ QString f = friendlyString( source );
+ QStringList lookupWords = QStringList::split( QChar(' '), f );
+ QStringList::Iterator w;
+ PhraseBook::Iterator p;
+
+ for ( w = lookupWords.begin(); w != lookupWords.end(); ++w ) {
+ PhraseBook *ent = phraseDict.find( *w );
+ if ( ent != 0 ) {
+ for ( p = ent->begin(); p != ent->end(); ++p ) {
+ if ( f.find(friendlyString((*p).source())) >= 0 )
+ phrases.append( *p );
+ }
+ }
+ }
+ return phrases;
+}
+
+bool TrWindow::danger( const QString& source, const QString& translation,
+ bool verbose )
+{
+ if ( acceleratorsAct->isOn() ) {
+ int sk = QAccel::shortcutKey( source );
+ int tk = QAccel::shortcutKey( translation );
+ if ( sk == 0 && tk != 0 ) {
+ if ( verbose )
+ statusBar()->message( tr("Accelerator possibly superfluous in"
+ " translation."), ErrorMS );
+ return TRUE;
+ } else if ( sk != 0 && tk == 0 ) {
+ if ( verbose )
+ statusBar()->message( tr("Accelerator possibly missing in"
+ " translation."), ErrorMS );
+ return TRUE;
+ }
+ }
+ if ( endingPunctuationAct->isOn() ) {
+ if ( ending(source) != ending(translation) ) {
+ if ( verbose )
+ statusBar()->message( tr("Translation does not end with the"
+ " same punctuation as the source"
+ " text."), ErrorMS );
+ return TRUE;
+ }
+ }
+ if ( phraseMatchesAct->isOn() ) {
+ QString fsource = friendlyString( source );
+ QString ftranslation = friendlyString( translation );
+ QStringList lookupWords = QStringList::split( QChar(' '), fsource );
+ QStringList::Iterator w;
+ PhraseBook::Iterator p;
+
+ for ( w = lookupWords.begin(); w != lookupWords.end(); ++w ) {
+ PhraseBook *ent = phraseDict.find( *w );
+ if ( ent != 0 ) {
+ for ( p = ent->begin(); p != ent->end(); ++p ) {
+ if ( fsource.find(friendlyString((*p).source())) < 0 ||
+ ftranslation.find(friendlyString((*p).target())) >= 0 )
+ break;
+ }
+ if ( p == ent->end() ) {
+ if ( verbose )
+ statusBar()->message( tr("A phrase book suggestion for"
+ " '%1' was ignored.")
+ .arg(*w), ErrorMS );
+ return TRUE;
+ }
+ }
+ }
+ }
+ if ( verbose )
+ statusBar()->clear();
+
+ return FALSE;
+}
+
+void TrWindow::readConfig()
+{
+ QString keybase( "/Qt Linguist/" +
+ QString::number( (QT_VERSION >> 16) & 0xff ) +
+ "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" );
+ QSettings config;
+
+ config.insertSearchPath( QSettings::Windows, "/Trolltech" );
+
+ QRect r( pos(), size() );
+ recentFiles = config.readListEntry( keybase + "RecentlyOpenedFiles" );
+ if ( !config.readBoolEntry( keybase + "Geometry/MainwindowMaximized", FALSE ) ) {
+ r.setX( config.readNumEntry( keybase + "Geometry/MainwindowX", r.x() ) );
+ r.setY( config.readNumEntry( keybase + "Geometry/MainwindowY", r.y() ) );
+ r.setWidth( config.readNumEntry( keybase + "Geometry/MainwindowWidth", r.width() ) );
+ r.setHeight( config.readNumEntry( keybase + "Geometry/MainwindowHeight", r.height() ) );
+
+ QRect desk = QApplication::desktop()->geometry();
+ QRect inter = desk.intersect( r );
+ resize( r.size() );
+ if ( inter.width() * inter.height() > ( r.width() * r.height() / 20 ) ) {
+ move( r.topLeft() );
+ }
+ }
+
+ QDockWindow * dw;
+ dw = (QDockWindow *) lv->parent();
+ int place;
+ place = config.readNumEntry( keybase + "Geometry/ContextwindowInDock" );
+ r.setX( config.readNumEntry( keybase + "Geometry/ContextwindowX" ) );
+ r.setY( config.readNumEntry( keybase + "Geometry/ContextwindowY" ) );
+ r.setWidth( config.readNumEntry( keybase +
+ "Geometry/ContextwindowWidth" ) );
+ r.setHeight( config.readNumEntry( keybase +
+ "Geometry/ContextwindowHeight" ) );
+ if ( place == QDockWindow::OutsideDock ) {
+ dw->undock();
+ dw->show();
+ }
+ dw->setGeometry( r );
+
+ dw = (QDockWindow *) slv->parent();
+ place = config.readNumEntry( keybase + "Geometry/SourcewindowInDock" );
+ r.setX( config.readNumEntry( keybase + "Geometry/SourcewindowX" ) );
+ r.setY( config.readNumEntry( keybase + "Geometry/SourcewindowY" ) );
+ r.setWidth( config.readNumEntry( keybase +
+ "Geometry/SourcewindowWidth" ) );
+ r.setHeight( config.readNumEntry( keybase +
+ "Geometry/SourcewindowHeight" ) );
+ if ( place == QDockWindow::OutsideDock ) {
+ dw->undock();
+ dw->show();
+ }
+ dw->setGeometry( r );
+
+ dw = (QDockWindow *) plv->parent()->parent();
+ place = config.readNumEntry( keybase + "Geometry/PhrasewindowInDock" );
+ r.setX( config.readNumEntry( keybase + "Geometry/PhrasewindowX" ) );
+ r.setY( config.readNumEntry( keybase + "Geometry/PhrasewindowY" ) );
+ r.setWidth( config.readNumEntry( keybase +
+ "Geometry/PhrasewindowWidth" ) );
+ r.setHeight( config.readNumEntry( keybase +
+ "Geometry/PhrasewindowHeight" ) );
+ if ( place == QDockWindow::OutsideDock ) {
+ dw->undock();
+ dw->show();
+ }
+ dw->setGeometry( r );
+ QApplication::sendPostedEvents();
+}
+
+void TrWindow::writeConfig()
+{
+ QString keybase( "/Qt Linguist/" +
+ QString::number( (QT_VERSION >> 16) & 0xff ) +
+ "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" );
+ QSettings config;
+
+ config.insertSearchPath( QSettings::Windows, "/Trolltech" );
+ config.writeEntry( keybase + "RecentlyOpenedFiles", recentFiles );
+ config.writeEntry( keybase + "Geometry/MainwindowMaximized", isMaximized() );
+ config.writeEntry( keybase + "Geometry/MainwindowX", x() );
+ config.writeEntry( keybase + "Geometry/MainwindowY", y() );
+ config.writeEntry( keybase + "Geometry/MainwindowWidth", width() );
+ config.writeEntry( keybase + "Geometry/MainwindowHeight", height() );
+
+ QDockWindow * dw =(QDockWindow *) lv->parent();
+ config.writeEntry( keybase + "Geometry/ContextwindowInDock", dw->place() );
+ config.writeEntry( keybase + "Geometry/ContextwindowX", dw->x() );
+ config.writeEntry( keybase + "Geometry/ContextwindowY", dw->y() );
+ config.writeEntry( keybase + "Geometry/ContextwindowWidth", dw->width() );
+ config.writeEntry( keybase + "Geometry/ContextwindowHeight", dw->height() );
+
+ dw =(QDockWindow *) slv->parent();
+ config.writeEntry( keybase + "Geometry/SourcewindowInDock",
+ dw->place() );
+ config.writeEntry( keybase + "Geometry/SourcewindowX", dw->geometry().x() );
+ config.writeEntry( keybase + "Geometry/SourcewindowY", dw->geometry().y() );
+ config.writeEntry( keybase + "Geometry/SourcewindowWidth", dw->width() );
+ config.writeEntry( keybase + "Geometry/SourcewindowHeight", dw->height() );
+
+ dw =(QDockWindow *) plv->parent()->parent();
+ config.writeEntry( keybase + "Geometry/PhrasewindowInDock",
+ dw->place() );
+ config.writeEntry( keybase + "Geometry/PhrasewindowX", dw->geometry().x() );
+ config.writeEntry( keybase + "Geometry/PhrasewindowY", dw->geometry().y() );
+ config.writeEntry( keybase + "Geometry/PhrasewindowWidth", dw->width() );
+ config.writeEntry( keybase + "Geometry/PhrasewindowHeight", dw->height() );
+}
+
+void TrWindow::setupRecentFilesMenu()
+{
+ recentFilesMenu->clear();
+ int id = 0;
+ QStringList::Iterator it = recentFiles.begin();
+ for ( ; it != recentFiles.end(); ++it )
+ {
+ recentFilesMenu->insertItem( *it, id );
+ id++;
+ }
+}
+
+void TrWindow::recentFileActivated( int id )
+{
+ if ( id != -1 ) {
+ if ( maybeSave() )
+ openFile( *recentFiles.at( id ) );
+ }
+}
+
+void TrWindow::addRecentlyOpenedFile( const QString &fn, QStringList &lst )
+{
+ if ( lst.find( fn ) != lst.end() )
+ return;
+ if ( lst.count() >= 10 )
+ lst.remove( lst.begin() );
+ lst << fn;
+}
+
+void TrWindow::toggleGuessing()
+{
+ me->toggleGuessing();
+}
+
+void TrWindow::focusSourceList()
+{
+ slv->setFocus();
+}
+
+void TrWindow::focusPhraseList()
+{
+ plv->setFocus();
+}
+
+void TrWindow::updateClosePhraseBook()
+{
+ if ( dirtyItem != -1 ) {
+ closePhraseBookp->removeItem( closePhraseBookp->idAt(dirtyItem) );
+ dirtyItem = -1;
+ }
+}
+
+void TrWindow::toggleStatistics()
+{
+ if ( toggleStats->isOn() ) {
+ if ( !stats ) {
+ stats = new Statistics( this, "linguist_stats" );
+ connect( this, SIGNAL(statsChanged(int,int,int,int,int,int)), stats,
+ SLOT(updateStats(int,int,int,int,int,int)) );
+ connect( stats, SIGNAL(closed()), toggleStats, SLOT(toggle()) );
+ }
+ updateStatistics();
+ stats->show();
+ } else if ( stats ) {
+ stats->close();
+ }
+}
+
+void TrWindow::updateStatistics()
+{
+ QListViewItem * ci = lv->firstChild();
+ int trW = 0;
+ int trC = 0;
+ int trCS = 0;
+ while ( ci ) {
+ countStats( ci, ((ContextLVI *)ci)->firstMessageItem(), trW, trC, trCS );
+ ci = ci->nextSibling();
+ }
+ // ..and the items in the source list
+ countStats( 0, slv->firstChild(), trW, trC, trCS );
+ emit statsChanged( srcWords, srcChars, srcCharsSpc, trW, trC, trCS );
+}
+
+
+void TrWindow::countStats( QListViewItem* ci, QListViewItem* mi, int& trW, int& trC, int& trCS )
+{
+ MessageLVI * m;
+ while ( mi ) {
+ m = (MessageLVI *) mi;
+ if ( m->finished() && !(m->message().type() == MetaTranslatorMessage::Obsolete) )
+ doCharCounting( m->translation(), trW, trC, trCS );
+ if ( ci )
+ mi = ((ContextLVI *)ci)->nextMessageItem();
+ else
+ mi = mi->nextSibling();
+ }
+}
+
+void TrWindow::doCharCounting( const QString& text, int& trW, int& trC, int& trCS )
+{
+ trCS += text.length();
+ bool inWord = FALSE;
+ for ( int i = 0; i < (int) text.length(); i++ ) {
+ if ( text[i].isLetterOrNumber() || text[i] == QChar('_') ) {
+ if ( !inWord ) {
+ trW++;
+ inWord = TRUE;
+ }
+ } else {
+ inWord = FALSE;
+ }
+ if ( !text[i].isSpace() )
+ trC++;
+ }
+}
diff --git a/tools/linguist/linguist/trwindow.h b/tools/linguist/linguist/trwindow.h
new file mode 100644
index 0000000..38cba25
--- /dev/null
+++ b/tools/linguist/linguist/trwindow.h
@@ -0,0 +1,237 @@
+/**********************************************************************
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of Qt Linguist.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TRWINDOW_H
+#define TRWINDOW_H
+
+#include "phrase.h"
+
+#include <metatranslator.h>
+
+#include <qmainwindow.h>
+#include <qptrlist.h>
+#include <qdict.h>
+#include <qprinter.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qlistview.h>
+
+class QAction;
+class QDialog;
+class QLabel;
+class QListView;
+class QListViewItem;
+class QPrinter;
+
+class Action;
+class FindDialog;
+class MessageEditor;
+
+class PhraseLV;
+class ContextLVI;
+class Statistics;
+
+class TrWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ static QPixmap * pxOn;
+ static QPixmap * pxOff;
+ static QPixmap * pxObsolete;
+ static QPixmap * pxDanger;
+ static const QPixmap pageCurl();
+
+ TrWindow();
+ ~TrWindow();
+
+ void openFile( const QString& name );
+
+protected:
+ void readConfig();
+ void writeConfig();
+ void closeEvent( QCloseEvent * );
+
+signals:
+ void statsChanged( int w, int c, int cs, int w2, int c2, int cs2 );
+
+private slots:
+ void doneAndNext();
+ void prev();
+ void next();
+ void recentFileActivated( int );
+ void setupRecentFilesMenu();
+ void open();
+ void save();
+ void saveAs();
+ void release();
+ void print();
+ void find();
+ void findAgain();
+ void replace();
+ void newPhraseBook();
+ void openPhraseBook();
+ void closePhraseBook( int id );
+ void editPhraseBook( int id );
+ void printPhraseBook( int id );
+ void manual();
+ void revertSorting();
+ void about();
+ void aboutQt();
+
+ void setupPhrase();
+ bool maybeSave();
+ void updateCaption();
+ void showNewScope( QListViewItem *item );
+ void showNewCurrent( QListViewItem *item );
+ void updateTranslation( const QString& translation );
+ void updateFinished( bool finished );
+ void toggleFinished( QListViewItem *item, const QPoint& p, int column );
+ void prevUnfinished();
+ void nextUnfinished();
+ void findNext( const QString& text, int where, bool matchCase );
+ void revalidate();
+ void toggleGuessing();
+ void focusSourceList();
+ void focusPhraseList();
+ void updateClosePhraseBook();
+ void toggleStatistics();
+ void updateStatistics();
+
+private:
+ typedef QPtrList<PhraseBook> PBL;
+ typedef QDict<PhraseBook> PBD;
+
+ static QString friendlyString( const QString& str );
+
+ void addRecentlyOpenedFile( const QString & fn, QStringList & lst );
+ void setupMenuBar();
+ void setupToolBars();
+ void setCurrentContextItem( QListViewItem *item );
+ void setCurrentMessageItem( QListViewItem *item );
+ QString friendlyPhraseBookName( int k );
+ bool openPhraseBook( const QString& name );
+ bool savePhraseBook( QString& name, const PhraseBook& pb );
+ void updateProgress();
+ void updatePhraseDict();
+ PhraseBook getPhrases( const QString& source );
+ bool danger( const QString& source, const QString& translation,
+ bool verbose = FALSE );
+
+ int itemToIndex( QListView * view, QListViewItem * item );
+ QListViewItem * indexToItem( QListView * view, int index );
+ bool searchItem( const QString & searchWhat, QListViewItem * j,
+ QListViewItem * k );
+ void countStats( QListViewItem * ci, QListViewItem * mi, int& trW, int& trC, int& trCS );
+ void doCharCounting( const QString& text, int& trW, int& trC, int& trCS );
+
+ QListView * plv;
+ QListView * lv;
+ QListView * slv;
+ MessageEditor * me;
+ QLabel * progress;
+ QLabel * modified;
+ MetaTranslator tor;
+ bool dirty;
+ bool messageIsShown;
+ int numFinished;
+ int numNonobsolete;
+ int numMessages;
+ int dirtyItem;
+ QStringList recentFiles;
+ QString filename;
+
+ PBD phraseDict;
+ PBL phraseBooks;
+ QStringList phraseBookNames;
+
+ QPrinter printer;
+
+ FindDialog *f;
+ FindDialog *h;
+ QString findText;
+ int findWhere;
+ bool findMatchCase;
+ int foundItem;
+ QListViewItem *foundScope;
+ int foundWhere;
+ int foundOffset;
+
+ QPopupMenu * phrasep;
+ QPopupMenu * closePhraseBookp;
+ QPopupMenu * editPhraseBookp;
+ QPopupMenu * printPhraseBookp;
+ QPopupMenu * recentFilesMenu;
+ int closePhraseBookId;
+ int editPhraseBookId;
+ int printPhraseBookId;
+ Action *openAct;
+ Action *saveAct;
+ Action *saveAsAct;
+ Action *releaseAct;
+ Action *printAct;
+ Action *exitAct;
+ Action *undoAct;
+ Action *redoAct;
+ Action *cutAct;
+ Action *copyAct;
+ Action *pasteAct;
+ Action *selectAllAct;
+ Action *findAct;
+ Action *findAgainAct;
+ Action *replaceAct;
+ Action *newPhraseBookAct;
+ Action *openPhraseBookAct;
+ Action *acceleratorsAct;
+ Action *endingPunctuationAct;
+ Action *phraseMatchesAct;
+ Action *revertSortingAct;
+ Action *aboutAct;
+ Action *aboutQtAct;
+ Action *manualAct;
+ Action *whatsThisAct;
+ Action *beginFromSourceAct;
+ Action *prevAct;
+ Action *nextAct;
+ Action *prevUnfinishedAct;
+ Action *nextUnfinishedAct;
+ Action *doneAndNextAct;
+ QAction *doneAndNextAlt;
+ Action *doGuessesAct;
+ Action *toggleStats;
+ Statistics * stats;
+ int srcWords;
+ int srcChars;
+ int srcCharsSpc;
+};
+
+#endif