summaryrefslogtreecommitdiffstats
path: root/kbabel/kbabel
diff options
context:
space:
mode:
Diffstat (limited to 'kbabel/kbabel')
-rw-r--r--kbabel/kbabel/Makefile.am92
-rw-r--r--kbabel/kbabel/charselectview.cpp115
-rw-r--r--kbabel/kbabel/charselectview.h71
-rw-r--r--kbabel/kbabel/colorpreferences.ui188
-rw-r--r--kbabel/kbabel/commentview.cpp221
-rw-r--r--kbabel/kbabel/commentview.h96
-rw-r--r--kbabel/kbabel/contextview.cpp158
-rw-r--r--kbabel/kbabel/contextview.h56
-rw-r--r--kbabel/kbabel/editordiffpreferences.ui192
-rw-r--r--kbabel/kbabel/editorpreferences.ui353
-rw-r--r--kbabel/kbabel/editorpreferences.ui.h23
-rw-r--r--kbabel/kbabel/errorlistview.cpp76
-rw-r--r--kbabel/kbabel/errorlistview.h55
-rw-r--r--kbabel/kbabel/fontpreferences.ui63
-rw-r--r--kbabel/kbabel/fontpreferences.ui.h14
-rw-r--r--kbabel/kbabel/gotodialog.cpp74
-rw-r--r--kbabel/kbabel/gotodialog.h63
-rw-r--r--kbabel/kbabel/headereditor.cpp214
-rw-r--r--kbabel/kbabel/headereditor.h85
-rw-r--r--kbabel/kbabel/headerwidget.ui64
-rw-r--r--kbabel/kbabel/hi16-app-kbabel.pngbin0 -> 952 bytes
-rw-r--r--kbabel/kbabel/hi32-app-kbabel.pngbin0 -> 2561 bytes
-rw-r--r--kbabel/kbabel/hi48-app-kbabel.pngbin0 -> 4753 bytes
-rw-r--r--kbabel/kbabel/hidingmsgedit.cpp426
-rw-r--r--kbabel/kbabel/hidingmsgedit.h161
-rw-r--r--kbabel/kbabel/icons/Makefile.am5
-rw-r--r--kbabel/kbabel/icons/hi16-action-autodiff.pngbin0 -> 242 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-catalogmanager.pngbin0 -> 791 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-diff.pngbin0 -> 203 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-insert_arg.pngbin0 -> 303 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-insert_tag.pngbin0 -> 329 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-msgid2msgstr.pngbin0 -> 298 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-nexterror.pngbin0 -> 416 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-nextfuzzy.pngbin0 -> 299 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.pngbin0 -> 422 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-nextuntranslated.pngbin0 -> 323 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-preverror.pngbin0 -> 443 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-prevfuzzy.pngbin0 -> 346 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.pngbin0 -> 469 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-prevuntranslated.pngbin0 -> 350 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-search2msgstr.pngbin0 -> 374 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-spellcheck_actual.pngbin0 -> 223 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-spellcheck_all.pngbin0 -> 204 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.pngbin0 -> 216 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-spellcheck_selected.pngbin0 -> 214 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-togglefuzzy.pngbin0 -> 316 bytes
-rw-r--r--kbabel/kbabel/icons/hi16-action-transsearch.pngbin0 -> 694 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-autodiff.pngbin0 -> 314 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-catalogmanager.pngbin0 -> 1540 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-diff.pngbin0 -> 227 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-insert_arg.pngbin0 -> 316 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-insert_tag.pngbin0 -> 332 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-msgid2msgstr.pngbin0 -> 277 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-nexterror.pngbin0 -> 530 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-nextfuzzy.pngbin0 -> 471 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.pngbin0 -> 561 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-nextuntranslated.pngbin0 -> 459 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-preverror.pngbin0 -> 465 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-prevfuzzy.pngbin0 -> 413 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.pngbin0 -> 490 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-prevuntranslated.pngbin0 -> 399 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-search2msgstr.pngbin0 -> 338 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-togglefuzzy.pngbin0 -> 386 bytes
-rw-r--r--kbabel/kbabel/icons/hi22-action-transsearch.pngbin0 -> 1357 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-autodiff.pngbin0 -> 571 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-catalogmanager.pngbin0 -> 2201 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-diff.pngbin0 -> 296 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-insert_arg.pngbin0 -> 537 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-insert_tag.pngbin0 -> 602 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-msgid2msgstr.pngbin0 -> 531 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-nexterror.pngbin0 -> 836 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-nextfuzzy.pngbin0 -> 597 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.pngbin0 -> 720 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-nextuntranslated.pngbin0 -> 583 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-preverror.pngbin0 -> 1334 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-prevfuzzy.pngbin0 -> 1012 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.pngbin0 -> 1140 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-prevuntranslated.pngbin0 -> 1000 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-search2msgstr.pngbin0 -> 756 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-togglefuzzy.pngbin0 -> 854 bytes
-rw-r--r--kbabel/kbabel/icons/hi32-action-transsearch.pngbin0 -> 1807 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-autodiff.pngbin0 -> 361 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-catalogmanager.pngbin0 -> 588 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-diff.pngbin0 -> 349 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-insert_arg.pngbin0 -> 341 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-insert_tag.pngbin0 -> 358 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-msgid2msgstr.pngbin0 -> 342 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-nexterror.pngbin0 -> 390 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-nextfuzzy.pngbin0 -> 363 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.pngbin0 -> 373 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-nextuntranslated.pngbin0 -> 360 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-preverror.pngbin0 -> 393 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-prevfuzzy.pngbin0 -> 366 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.pngbin0 -> 377 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-prevuntranslated.pngbin0 -> 363 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-search2msgstr.pngbin0 -> 370 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-spellcheck_actual.pngbin0 -> 223 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-spellcheck_all.pngbin0 -> 204 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.pngbin0 -> 216 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-spellcheck_selected.pngbin0 -> 214 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-togglefuzzy.pngbin0 -> 316 bytes
-rw-r--r--kbabel/kbabel/icons/lo16-action-transsearch.pngbin0 -> 435 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-autodiff.pngbin0 -> 478 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-catalogmanager.pngbin0 -> 828 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-diff.pngbin0 -> 390 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-insert_arg.pngbin0 -> 409 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-insert_tag.pngbin0 -> 431 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-msgid2msgstr.pngbin0 -> 403 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-nexterror.pngbin0 -> 539 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-nextfuzzy.pngbin0 -> 430 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.pngbin0 -> 472 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-nextuntranslated.pngbin0 -> 429 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-preverror.pngbin0 -> 547 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-prevfuzzy.pngbin0 -> 428 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.pngbin0 -> 474 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-prevuntranslated.pngbin0 -> 427 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-search2msgstr.pngbin0 -> 478 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-togglefuzzy.pngbin0 -> 854 bytes
-rw-r--r--kbabel/kbabel/icons/lo32-action-transsearch.pngbin0 -> 1267 bytes
-rw-r--r--kbabel/kbabel/kbabel-difftoproject.upd6
-rw-r--r--kbabel/kbabel/kbabel-project.upd11
-rw-r--r--kbabel/kbabel/kbabel.cpp1825
-rw-r--r--kbabel/kbabel/kbabel.desktop83
-rw-r--r--kbabel/kbabel/kbabel.h325
-rw-r--r--kbabel/kbabel/kbabel.kcfg304
-rw-r--r--kbabel/kbabel/kbabeliface.h81
-rw-r--r--kbabel/kbabel/kbabelpref.cpp198
-rw-r--r--kbabel/kbabel/kbabelpref.h69
-rw-r--r--kbabel/kbabel/kbabelsettings.kcfgc5
-rw-r--r--kbabel/kbabel/kbabelsplash.cpp73
-rw-r--r--kbabel/kbabel/kbabelsplash.h55
-rw-r--r--kbabel/kbabel/kbabelui.rc235
-rw-r--r--kbabel/kbabel/kbabelview.cpp4473
-rw-r--r--kbabel/kbabel/kbabelview.h712
-rw-r--r--kbabel/kbabel/kbabelview2.cpp1025
-rw-r--r--kbabel/kbabel/kbbookmarkhandler.cpp131
-rw-r--r--kbabel/kbabel/kbbookmarkhandler.h155
-rw-r--r--kbabel/kbabel/kbcatalog.cpp63
-rw-r--r--kbabel/kbabel/kbcatalog.h61
-rw-r--r--kbabel/kbabel/kbcataloglistview.cpp136
-rw-r--r--kbabel/kbabel/kbcataloglistview.h82
-rw-r--r--kbabel/kbabel/kbcataloglistviewitem.cpp213
-rw-r--r--kbabel/kbabel/kbcataloglistviewitem.h72
-rw-r--r--kbabel/kbabel/kbcatalogview.cpp137
-rw-r--r--kbabel/kbabel/kbcatalogview.h102
-rw-r--r--kbabel/kbabel/kbcharselect.cpp94
-rw-r--r--kbabel/kbabel/kbcharselect.h65
-rw-r--r--kbabel/kbabel/kbhighlighting.cpp316
-rw-r--r--kbabel/kbabel/kbhighlighting.h104
-rw-r--r--kbabel/kbabel/lo16-app-kbabel.pngbin0 -> 352 bytes
-rw-r--r--kbabel/kbabel/lo32-app-kbabel.pngbin0 -> 546 bytes
-rw-r--r--kbabel/kbabel/main.cpp612
-rw-r--r--kbabel/kbabel/mymultilineedit.cpp1668
-rw-r--r--kbabel/kbabel/mymultilineedit.h307
-rw-r--r--kbabel/kbabel/pics/Makefile.am6
-rw-r--r--kbabel/kbabel/pics/broken.pngbin0 -> 188 bytes
-rw-r--r--kbabel/kbabel/pics/missing.pngbin0 -> 215 bytes
-rw-r--r--kbabel/kbabel/pics/needwork.pngbin0 -> 189 bytes
-rw-r--r--kbabel/kbabel/pics/noflag.pngbin0 -> 159 bytes
-rw-r--r--kbabel/kbabel/pics/ok.pngbin0 -> 219 bytes
-rw-r--r--kbabel/kbabel/pics/pref_identity.pngbin0 -> 1369 bytes
-rw-r--r--kbabel/kbabel/pics/splash.pngbin0 -> 24019 bytes
-rw-r--r--kbabel/kbabel/searchpreferences.ui109
-rw-r--r--kbabel/kbabel/sourceview.cpp75
-rw-r--r--kbabel/kbabel/sourceview.h57
-rw-r--r--kbabel/kbabel/spelldlg.cpp142
-rw-r--r--kbabel/kbabel/spelldlg.h63
-rw-r--r--kbabel/kbabel/spelldlgwidget.ui126
-rw-r--r--kbabel/kbabel/taglistview.cpp78
-rw-r--r--kbabel/kbabel/taglistview.h61
170 files changed, 17380 insertions, 0 deletions
diff --git a/kbabel/kbabel/Makefile.am b/kbabel/kbabel/Makefile.am
new file mode 100644
index 00000000..29c8d576
--- /dev/null
+++ b/kbabel/kbabel/Makefile.am
@@ -0,0 +1,92 @@
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+SUBDIRS = pics icons
+
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+noinst_LTLIBRARIES = libkbabel.la
+bin_PROGRAMS = kbabel
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../common -I../common -I$(srcdir)/../commonui -I../commonui -I$(srcdir)/../kbabeldict -I../kbabeldict $(all_includes)
+
+
+# which sources should be compiled for kbabel
+libkbabel_la_SOURCES = kbbookmarkhandler.cpp \
+ kbcatalog.cpp headerwidget.ui headereditor.cpp \
+ spelldlgwidget.ui spelldlg.cpp gotodialog.cpp\
+ kbhighlighting.cpp mymultilineedit.cpp \
+ hidingmsgedit.cpp \
+ kbabelpref.cpp \
+ kbcatalogview.cpp \
+ commentview.cpp \
+ contextview.cpp \
+ charselectview.cpp \
+ taglistview.cpp \
+ sourceview.cpp \
+ kbabelview.cpp kbabelview2.cpp \
+ kbabel.cpp kbabeliface.skel kbabelsplash.cpp \
+ kbabelsettings.kcfgc \
+ fontpreferences.ui \
+ editordiffpreferences.ui \
+ editorpreferences.ui \
+ searchpreferences.ui \
+ colorpreferences.ui \
+ kbcataloglistview.cpp kbcataloglistviewitem.cpp \
+ errorlistview.cpp
+
+kde_kcfg_DATA=kbabel.kcfg
+
+libkbabel_la_LIBADD = ../commonui/libkbabelcommonui.la ../kbabeldict/libkbabeldict.la $(LIB_KIO) $(LIB_KSPELL)
+libkbabel_la_LDFLAGS = $(all_libraries)
+
+
+kbabel_SOURCES = main.cpp
+
+# the libraries to link against.
+kbabel_LDADD = libkbabel.la
+kbabel_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# these are the headers for your project
+noinst_HEADERS = kbabel.h kbabelview.h \
+ kbcatalogview.h \
+ commentview.h \
+ contextview.h \
+ charselectview.h \
+ taglistview.h \
+ sourceview.h \
+ kbabeliface.h kbabelpref.h\
+ headereditor.h mymultilineedit.h\
+ gotodialog.h hidingmsgedit.h\
+ kbcatalog.h spelldlg.h\
+ kbabelsplash.h kbbookmarkhandler.h \
+ kbhighlighting.h \
+ kbcataloglistview.h \
+ kbcataloglistviewitem.h \
+ errorlistview.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+rcdir = $(kde_datadir)/kbabel
+rc_DATA = kbabelui.rc
+
+update_DATA = kbabel-project.upd kbabel-difftoproject.upd
+updatedir = $(kde_datadir)/kconf_update
+
+api:
+ mkdir -p API && kdoc -d API -u $$PWD/API -p -lkdeui -lkdecore -lqt -ldcop $(noinst_HEADERS)
+
+distclean-local:
+ rm -r -f API
+
+KDE_ICON = kbabel
+
+ # this is where the kdelnk file will go
+xdg_apps_DATA = kbabel.desktop
+
+kbabel.lo: ../common/kbprojectsettings.h ../common/version.h
+kbabelview.lo: ../common/kbprojectsettings.h ../common/version.h
+kbabelview2.lo: ../common/kbprojectsettings.h
+main.o: ../common/version.h
+
diff --git a/kbabel/kbabel/charselectview.cpp b/kbabel/kbabel/charselectview.cpp
new file mode 100644
index 00000000..12cd765f
--- /dev/null
+++ b/kbabel/kbabel/charselectview.cpp
@@ -0,0 +1,115 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "charselectview.h"
+
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qscrollview.h>
+
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kcharselect.h>
+
+#include "kbcatalog.h"
+
+using namespace KBabel;
+
+CharacterSelectorView::CharacterSelectorView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent,project)
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setResizeMode( QLayout::Minimum );
+
+ layout->setSpacing( KDialog::spacingHint() );
+
+ QHBox* bar = new QHBox(this);
+ bar->setSpacing( KDialog::spacingHint() );
+ layout->addWidget (bar);
+
+ QLabel *lTable = new QLabel( i18n( "Table:" ), bar );
+ _tableNum = new QSpinBox( 0, 255, 1, bar );
+ lTable->setBuddy( _tableNum );
+ bar->setStretchFactor( _tableNum, 1 );
+
+ QScrollView* scroll = new QScrollView( this );
+ _table = new KCharSelectTable(scroll,"charselector","helvetica",' ',0);
+ _table->setNumCols(16);
+ _table->setNumRows(16);
+
+ scroll->addChild(_table);
+ layout->addWidget (scroll);
+
+ connect( _table, SIGNAL( doubleClicked() ), this, SLOT( emitChar() ) );
+ connect( _tableNum, SIGNAL( valueChanged(int) ), this, SLOT( setTab(int) ));
+
+ connect( _catalog, SIGNAL( signalFileOpened(bool) ), this, SLOT (setDisabled (bool)));
+ connect( _catalog, SIGNAL( signalFileOpened(bool) ), _table, SLOT (setDisabled (bool)));
+
+ QWhatsThis::add(this,
+ i18n("<qt><p><b>Character Selector</b></p>"
+ "<p>This tool allows to insert special characters using "
+ "double click.</p></qt>"));
+}
+
+void CharacterSelectorView::emitChar()
+{
+ emit characterDoubleClicked( _table->chr() );
+}
+
+void CharacterSelectorView::setTab(int value)
+{
+ _table->setTableNum( value );
+}
+
+void CharacterSelectorView::saveSettings(KConfig* config)
+{
+ KConfigGroupSaver saver(config, "KBCharSelector" );
+
+ config->writeEntry( "TableNum", _tableNum->value() );
+ config->writeEntry( "SelectedChar", QString(_table->chr()) );
+}
+
+void CharacterSelectorView::restoreSettings(KConfig* config)
+{
+ KConfigGroupSaver saver(config, "KBCharSelector" );
+
+ _tableNum->setValue( config->readNumEntry("TableNum", 0 ));
+ _table->setChar( config->readEntry("SelectedChar"," ").at(0));
+}
+
+#include "charselectview.moc"
diff --git a/kbabel/kbabel/charselectview.h b/kbabel/kbabel/charselectview.h
new file mode 100644
index 00000000..76ee19b8
--- /dev/null
+++ b/kbabel/kbabel/charselectview.h
@@ -0,0 +1,71 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef CHARSELECTVIEW_H
+#define CHARSELECTVIEW_H
+
+#include "kbcatalogview.h"
+
+class KCharSelectTable;
+class QSpinBox;
+
+class CharacterSelectorView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ CharacterSelectorView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+ void saveSettings(KConfig* config);
+ void restoreSettings(KConfig* config);
+
+public slots:
+ // this view does not depend on the current item
+ virtual void updateView() {}
+
+signals:
+ void characterDoubleClicked( QChar ch );
+
+public slots:
+ void emitChar();
+
+private slots:
+ void setTab( int value);
+
+private:
+ KCharSelectTable* _table;
+ QSpinBox* _tableNum;
+};
+
+#endif // CHARSELECTVIEW_H
diff --git a/kbabel/kbabel/colorpreferences.ui b/kbabel/kbabel/colorpreferences.ui
new file mode 100644
index 00000000..97e89df6
--- /dev/null
+++ b/kbabel/kbabel/colorpreferences.ui
@@ -0,0 +1,188 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ColorPreferences</class>
+<author>Stanislav Visnovsky</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ColorPreferences</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>627</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KColorButton" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_QuotedColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_BackgroundColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Background color:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_BackgroundColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Color for &amp;quoted characters:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_QuotedColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Color for &amp;syntax errors:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_ErrorColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="2" column="1">
+ <property name="name">
+ <cstring>kcfg_ErrorColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>label</cstring>
+ </property>
+ <property name="text">
+ <string>Color for s&amp;pellcheck errors:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_ErrorColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="3" column="1">
+ <property name="name">
+ <cstring>kcfg_SpellcheckErrorColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;Here you can setup a color to display identified &lt;b&gt;mispelled&lt;/b&gt; words and
+phrases.&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Color for &amp;keyboard accelerators:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_AccelColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="6" column="1">
+ <property name="name">
+ <cstring>kcfg_TagColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="5" column="1">
+ <property name="name">
+ <cstring>kcfg_AccelColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Color for c-for&amp;mat characters:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_CformatColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="4" column="1">
+ <property name="name">
+ <cstring>kcfg_CformatColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Color for &amp;tags:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_TagColor</cstring>
+ </property>
+ </widget>
+ <spacer row="7" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabel/commentview.cpp b/kbabel/kbabel/commentview.cpp
new file mode 100644
index 00000000..bf2301de
--- /dev/null
+++ b/kbabel/kbabel/commentview.cpp
@@ -0,0 +1,221 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "commentview.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qdragobject.h>
+#include <qtextview.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kurldrag.h>
+
+#include "resources.h"
+
+#include "editcmd.h"
+#include "hidingmsgedit.h"
+#include "kbcatalog.h"
+
+#define ID_DROP_OPEN 1
+#define ID_DROP_OPEN_TEMPLATE 2
+
+#define MAX_HISTORY 50
+
+using namespace KBabel;
+
+CommentView::CommentView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent, project)
+{
+ setAcceptDrops(true);
+
+ QVBoxLayout* layout=new QVBoxLayout(this);
+
+ commentEdit = new MsgMultiLineEdit(0, 0, this);
+ commentEdit->setMinimumHeight(50);
+ commentEdit->setSpacePoints(false);
+ commentEdit->setHighlightSyntax(false);
+ KCursor::setAutoHideCursor(commentEdit,true);
+
+ QLabel* label=new QLabel(commentEdit,i18n("&Comment:"),this);
+
+ QHBoxLayout* hb=new QHBoxLayout(layout);
+ hb->addSpacing(KDialog::marginHint());
+ hb->addWidget(label);
+
+ layout->addWidget(commentEdit);
+ layout->setStretchFactor(commentEdit,1);
+
+ QWhatsThis::add(this,
+ i18n("<qt><p><b>Comment Editor</b></p>\n\
+This edit window shows you the comments of the currently displayed message.<p>\n\
+<p>The comments normally contain information about where the message is found in the source\n\
+code and status information about this message (fuzzy, c-format).\n\
+Hints from other translators are also sometimes contained in comments.</p>\n\
+<p>You can hide the comment editor by deactivating\n\
+<b>Options->Show Comments</b>.</p></qt>"));
+
+ commentEdit->setReadOnly(true);
+ connect(commentEdit,SIGNAL(signalUndoCmd(KBabel::EditCommand*)),this,SLOT(forwardCommentEditCmd(KBabel::EditCommand*)));
+
+ connect(commentEdit,SIGNAL(cursorPositionChanged(int,int))
+ , this, SIGNAL(signalCursorPosChanged(int,int)));
+
+ connect(_catalog, SIGNAL(signalFileOpened(bool)), this, SLOT(setDisabled(bool)));
+}
+
+void CommentView::update(EditCommand* cmd, bool undo)
+{
+ if((int)_currentIndex==cmd->index())
+ {
+ if(cmd->part()==Comment)
+ {
+ commentEdit->processCommand(cmd,undo);
+ }
+ }
+}
+
+void CommentView::textCut()
+{
+ if(commentEdit->hasFocus())
+ {
+ commentEdit->cut();
+ }
+}
+
+void CommentView::textCopy()
+{
+ if(commentEdit->hasSelectedText())
+ {
+ commentEdit->copy();
+ }
+}
+
+void CommentView::textPaste()
+{
+ if(commentEdit->hasFocus())
+ {
+ commentEdit->paste();
+ }
+}
+
+void CommentView::textSelectAll()
+{
+ if(commentEdit->hasFocus())
+ {
+ commentEdit->selectAll();
+ }
+}
+
+void CommentView::textDeselectAll()
+{
+ commentEdit->selectAll(false);
+}
+
+void CommentView::updateView()
+{
+ commentEdit->setText ( _catalog->comment (_currentIndex) );
+}
+
+void CommentView::forwardCommentEditCmd(EditCommand* cmd)
+{
+ cmd->setPart(Comment);
+ cmd->setIndex(_currentIndex);
+
+ _catalog->applyEditCommand(cmd,this);
+}
+
+void CommentView::setReadOnly(bool on)
+{
+ commentEdit->setReadOnly( on );
+}
+
+void CommentView::setOverwriteMode(bool on)
+{
+ commentEdit->setOverwriteMode( on );
+}
+
+void CommentView::readFileSettings()
+{
+ setReadOnly( _catalog->isReadOnly() );
+}
+
+const QString CommentView::selectText(int from, int to)
+{
+ int line, col, endline, endcol;
+
+ commentEdit->selectAll(false);
+ commentEdit->setFocus();
+ commentEdit->offset2Pos(from,line,col);
+ commentEdit->offset2Pos(to,endline,endcol);
+
+ commentEdit->setSelection(line,col,endline,endcol);
+ commentEdit->setCursorPosition(endline,endcol);
+
+ return commentEdit->selectedText();
+}
+
+bool CommentView::isActiveView ()
+{
+ return hasFocus () || commentEdit->hasFocus ();
+}
+
+int CommentView::currentIndex ()
+{
+ return commentEdit->currentIndex ();
+}
+
+const QString CommentView::selectedText ()
+{
+ return commentEdit->selectedText ();
+}
+
+void CommentView::installEventFilter( const QObject * filterObj )
+{
+ commentEdit->installEventFilter( filterObj );
+}
+
+bool CommentView::hasFocus()
+{
+ return commentEdit->hasFocus();
+}
+
+#include "commentview.moc"
diff --git a/kbabel/kbabel/commentview.h b/kbabel/kbabel/commentview.h
new file mode 100644
index 00000000..1531683b
--- /dev/null
+++ b/kbabel/kbabel/commentview.h
@@ -0,0 +1,96 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef COMMENTVIEW_H
+#define COMMENTVIEW_H
+
+class QTextView;
+
+#include <qwidget.h>
+
+#include "kbcatalogview.h"
+#include "kbcatalog.h"
+#include "kbproject.h"
+#include "projectsettings.h"
+
+class MsgMultiLineEdit;
+
+class CommentView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ CommentView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+ /**
+ * this is called from the catalog when updating his views.
+ * reimplemented from @ref CatalogView
+ * @param cmd the edit command that has been applied
+ */
+ virtual void update(KBabel::EditCommand* cmd, bool undo=false);
+
+ virtual void updateView();
+ virtual void textCut ();
+ virtual void textCopy ();
+ virtual void textPaste ();
+ virtual void textSelectAll ();
+ virtual void textDeselectAll ();
+
+ const QString selectText( int from, int to );
+ const QString selectedText ();
+ bool isActiveView ();
+ int currentIndex ();
+
+ // this method is not virtual!
+ void installEventFilter( const QObject * filterObj );
+
+ bool hasFocus ();
+
+public slots:
+ virtual void setReadOnly(bool on);
+ virtual void setOverwriteMode(bool on);
+
+ virtual void readFileSettings();
+
+signals:
+ void signalCommentsShown();
+
+private slots:
+ void forwardCommentEditCmd(KBabel::EditCommand*);
+
+private:
+ MsgMultiLineEdit* commentEdit;
+};
+
+#endif // COMMENTVIEW_H
diff --git a/kbabel/kbabel/contextview.cpp b/kbabel/kbabel/contextview.cpp
new file mode 100644
index 00000000..e56e15dc
--- /dev/null
+++ b/kbabel/kbabel/contextview.cpp
@@ -0,0 +1,158 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "contextview.h"
+
+#include <qlayout.h>
+#include <qtextview.h>
+#include <qwhatsthis.h>
+
+#include <kcursor.h>
+#include <klocale.h>
+
+#include "resources.h"
+#include "kbcatalog.h"
+
+using namespace KBabel;
+
+ContextView::ContextView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent,project)
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setResizeMode( QLayout::Minimum );
+
+ _textview = new QTextView (this, "context textview");
+ KCursor::setAutoHideCursor(_textview->viewport(),true);
+ _textview->setReadOnly(true);
+
+ layout->addWidget (_textview);
+
+ QWhatsThis::add(this,
+ i18n("<qt><p><b>PO Context</b></p>"
+ "<p>This window shows the context of the current message "
+ "in the PO file. Normally it shows four messages in front "
+ "of the current message and four after it.</p>"
+ "<p>You can hide the tools window by deactivating "
+ "<b>Options->Show Tools</b>.</p></qt></qt>"));
+
+ connect(_catalog, SIGNAL(signalFileOpened(bool)), this, SLOT(setDisabled(bool)));
+}
+
+void ContextView::updateView()
+{
+ uint total = _catalog->numberOfEntries();
+ if(total==0)
+ return;
+
+ QString text;
+ uint startIndex;
+ uint context = 4;
+ if(_currentIndex < context)
+ {
+ startIndex = 0;
+ }
+ else if(_currentIndex > total-2*context-2)
+ {
+ startIndex = total-2*context-1;
+ }
+ else
+ {
+ startIndex = _currentIndex-context;
+ }
+
+ for(uint i=startIndex; i < QMIN(startIndex+(2*context+1), total); i++)
+ {
+ if(i == _currentIndex)
+ {
+ text += "<p><hr/><b>"+i18n("current entry") +"</b><hr/></p>";
+ continue;
+ }
+
+ QString entry;
+ QString temp;
+ temp = _catalog->comment(i);
+ if(!temp.isEmpty())
+ {
+ temp = QStyleSheet::convertFromPlainText(temp);
+ temp.replace(QRegExp("^<p>"),"");
+ temp.replace(QRegExp("</p>$"),"");
+ entry += "<i>"+temp+"</i><br/>";
+ }
+
+ // FIXME: should care about plural forms
+ temp = QStyleSheet::convertFromPlainText(_catalog->msgid(i).first());
+ temp.replace(QRegExp("^<p>"),"");
+ temp.replace(QRegExp("</p>$"),"");
+ entry += temp + "<br/>---<br/>";
+
+ QStringList tempList = _catalog->msgstr(i);
+
+ if(tempList.isEmpty())
+ {
+ entry +="<i><b><font color=\"red\">"
+ +i18n("untranslated")
+ +"</font></b></i><br/>";
+ }
+ else
+ {
+ if( tempList.count() == 1 )
+ {
+ temp = tempList.first();
+ }
+ else
+ {
+ uint counter = 1;
+ temp = "";
+ for( QStringList::Iterator i=tempList.begin() ; i != tempList.end() ; ++i)
+ {
+ temp += i18n("Plural %1: %2\n").arg(counter++).arg(*i);
+ }
+ }
+ temp = QStyleSheet::convertFromPlainText(temp);
+ temp.replace(QRegExp("^<p>"),"");
+ temp.replace(QRegExp("</p>$"),"");
+
+ entry += temp+"<br/>";
+ }
+
+ text += "<p>"+entry+"</p>";
+ }
+ _textview->setText("<qt>"+text+"</qt>");
+
+ int height = _textview->contentsHeight();
+ _textview->setContentsPos(0,height/2);
+}
+
+#include "contextview.moc"
diff --git a/kbabel/kbabel/contextview.h b/kbabel/kbabel/contextview.h
new file mode 100644
index 00000000..18bd0f4e
--- /dev/null
+++ b/kbabel/kbabel/contextview.h
@@ -0,0 +1,56 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef CONTEXTVIEW_H
+#define CONTEXTVIEW_H
+
+#include "kbcatalogview.h"
+
+class QTextView;
+
+class ContextView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ ContextView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+public slots:
+ virtual void updateView();
+
+private:
+ QTextView* _textview;
+};
+
+#endif // CONTEXTVIEW_H
diff --git a/kbabel/kbabel/editordiffpreferences.ui b/kbabel/kbabel/editordiffpreferences.ui
new file mode 100644
index 00000000..db21bc8e
--- /dev/null
+++ b/kbabel/kbabel/editordiffpreferences.ui
@@ -0,0 +1,192 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>EditorDiffPreferences</class>
+<author>Stanislav Visnovsky</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>EditorDiffPreferences</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>538</width>
+ <height>462</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Appearance</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Added Characters</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Ho&amp;w to display:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_DiffAddUnderline</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Co&amp;lor:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_DiffAddColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Removed Characters</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>How &amp;to display:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_DiffDelStrikeOut</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Colo&amp;r:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_DiffDelColor</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>Highlighted</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Underlined</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_DiffAddUnderline</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="2" column="1">
+ <property name="name">
+ <cstring>kcfg_DiffAddColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>192</red>
+ <green>192</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="4" column="1">
+ <item>
+ <property name="text">
+ <string>Highlighted</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Stroked Out</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_DiffDelStrikeOut</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="5" column="1">
+ <property name="name">
+ <cstring>kcfg_DiffDelColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<functions>
+ <function>init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabel/editorpreferences.ui b/kbabel/kbabel/editorpreferences.ui
new file mode 100644
index 00000000..ee8632f9
--- /dev/null
+++ b/kbabel/kbabel/editorpreferences.ui
@@ -0,0 +1,353 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>EditorPreferences</class>
+<author>Stanislav Visnovsky</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>EditorPreferences</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>627</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget2</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;General</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame6</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_AutoUnsetFuzzy</cstring>
+ </property>
+ <property name="text">
+ <string>A&amp;utomatically unset fuzzy status</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Automatically unset fuzzy status&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;If this is activated and you are editing a fuzzy entry, the fuzzy status is automatically
+unset (this means the string &lt;i&gt;, fuzzy&lt;/i&gt;
+is removed from the entry's comment).&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_CleverEditing</cstring>
+ </property>
+ <property name="text">
+ <string>Use cle&amp;ver editing</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Use clever editing&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;Check this to make typing text more comfortable and let
+KBabel take care of some special characters that have to
+be quoted. For example typing '\"' will result in
+'\\\"', pressing Return will automatically add whitespace
+at the end of the line, pressing Shift+Return will add
+'\\n' at the end of the line.&lt;/p&gt;
+&lt;p&gt;Note that this is just a hint: it is still possible to
+generate syntactically incorrect text.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Automatic Checks</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Error recognition&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;Here you can set how to show that an error occurred.
+&lt;b&gt;Beep on error&lt;/b&gt; beeps and &lt;b&gt;Change text color on error
+&lt;/b&gt; changes the color of the translated text. If none is
+activated, you will still see a message in the statusbar.
+&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="ToolSelectionWidget">
+ <property name="name">
+ <cstring>_kcfg_AutoCheckTools</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_BeepOnError</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Beep on error</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_AutoCheckColorError</cstring>
+ </property>
+ <property name="text">
+ <string>Change te&amp;xt color on error</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>A&amp;ppearance</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_HighlightSyntax</cstring>
+ </property>
+ <property name="text">
+ <string>H&amp;ighlight syntax</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_HighlightBackground</cstring>
+ </property>
+ <property name="text">
+ <string>Highlight backgrou&amp;nd</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_WhitespacePoints</cstring>
+ </property>
+ <property name="text">
+ <string>Mark &amp;whitespaces with points</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_EnableQuotes</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Show surrounding quotes</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Status LEDs</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Status LEDs&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;Choose here where the status LEDs are displayed and what color they have.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>kcfg_LedInStatusbar</cstring>
+ </property>
+ <property name="text">
+ <string>Display in stat&amp;usbar</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>radioButton2</cstring>
+ </property>
+ <property name="text">
+ <string>Display in edi&amp;tor</string>
+ </property>
+ <property name="checked">
+ <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>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Colo&amp;r:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_LedColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton">
+ <property name="name">
+ <cstring>kcfg_LedColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>29</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>ToolSelectionWidget</class>
+ <header location="global">toolselectionwidget.h</header>
+ <sizehint>
+ <width>200</width>
+ <height>200</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>kcfg_LedInStatusbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>EditorPreferences</receiver>
+ <slot>ledWarning(bool)</slot>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>EditorPreferences</receiver>
+ <slot>ledWarning(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_LedInStatusbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>EditorPreferences</receiver>
+ <slot>toggleOther(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">editorpreferences.ui.h</include>
+</includes>
+<slots>
+ <slot specifier="non virtual">ledWarning( bool show )</slot>
+ <slot specifier="non virtual">toggleOther( bool other )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>toolselectionwidget.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabel/editorpreferences.ui.h b/kbabel/kbabel/editorpreferences.ui.h
new file mode 100644
index 00000000..b7f9827c
--- /dev/null
+++ b/kbabel/kbabel/editorpreferences.ui.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+#include <kmessagebox.h>
+#include "toolselectionwidget.h"
+
+void EditorPreferences::ledWarning( bool show )
+{
+if(show)
+ KMessageBox::information( this,i18n("This option takes no effect until KBabel is restarted.") );
+}
+
+
+void EditorPreferences::toggleOther( bool other )
+{
+ radioButton2->setChecked(! other);
+}
diff --git a/kbabel/kbabel/errorlistview.cpp b/kbabel/kbabel/errorlistview.cpp
new file mode 100644
index 00000000..2dcd3b12
--- /dev/null
+++ b/kbabel/kbabel/errorlistview.cpp
@@ -0,0 +1,76 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "errorlistview.h"
+
+#include <qlayout.h>
+#include <qtextview.h>
+#include <qwhatsthis.h>
+
+#include <kcursor.h>
+#include <klocale.h>
+
+#include "resources.h"
+#include "kbcatalog.h"
+
+using namespace KBabel;
+
+ErrorListView::ErrorListView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent,project)
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setResizeMode( QLayout::Minimum );
+
+ _textview = new QTextView (this);
+ KCursor::setAutoHideCursor(_textview->viewport(),true);
+ _textview->setReadOnly(true);
+
+ layout->addWidget(_textview);
+
+ QWhatsThis::add(this, i18n( "<qt><p><b>Error List</b></p>"
+ "<p>This window shows the list of errors found by validator tools "
+ "so you can know why the current message has been marked with an "
+ "error.</p></qt>" ) );
+}
+
+void ErrorListView::updateView()
+{
+ if( _catalog->numberOfEntries() == 0 )
+ return;
+
+ _textview->setText( _catalog->itemStatus( _currentIndex ).join( "\n---\n" ) );
+}
+
+#include "errorlistview.moc"
diff --git a/kbabel/kbabel/errorlistview.h b/kbabel/kbabel/errorlistview.h
new file mode 100644
index 00000000..d50e7ec7
--- /dev/null
+++ b/kbabel/kbabel/errorlistview.h
@@ -0,0 +1,55 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Albert Cervera Areny <albertca@hotpop.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef ERRORLISTVIEW_H
+#define ERRORLISTVIEW_H
+
+#include "kbcatalogview.h"
+
+class QTextView;
+
+class ErrorListView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ ErrorListView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+public slots:
+ virtual void updateView();
+
+private:
+ QTextView* _textview;
+};
+
+#endif // ERRORLISTVIEW_H
diff --git a/kbabel/kbabel/fontpreferences.ui b/kbabel/kbabel/fontpreferences.ui
new file mode 100644
index 00000000..aefb8c7e
--- /dev/null
+++ b/kbabel/kbabel/fontpreferences.ui
@@ -0,0 +1,63 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>FontPreferences</class>
+<author>Stanislav Visnovsky</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>FontPreferences</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>595</width>
+ <height>515</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Font for Messages</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>checkBox1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Show only fixed font</string>
+ </property>
+ </widget>
+ <widget class="KFontChooser">
+ <property name="name">
+ <cstring>kcfg_MsgFont</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>checkBox1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FontPreferences</receiver>
+ <slot>showOnlyFixedFonts(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">fontpreferences.ui.h</include>
+</includes>
+<slots>
+ <slot access="private">showOnlyFixedFonts( bool on )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbabel/kbabel/fontpreferences.ui.h b/kbabel/kbabel/fontpreferences.ui.h
new file mode 100644
index 00000000..065318f1
--- /dev/null
+++ b/kbabel/kbabel/fontpreferences.ui.h
@@ -0,0 +1,14 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void FontPreferences::showOnlyFixedFonts( bool on)
+{
+ kcfg_MsgFont->setFont(kcfg_MsgFont->font(), on);
+}
diff --git a/kbabel/kbabel/gotodialog.cpp b/kbabel/kbabel/gotodialog.cpp
new file mode 100644
index 00000000..f822f0dc
--- /dev/null
+++ b/kbabel/kbabel/gotodialog.cpp
@@ -0,0 +1,74 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include <qstring.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include "gotodialog.h"
+
+GotoDialog::GotoDialog(int max,QWidget* parent)
+ : KDialogBase(parent,0,true,i18n("Go to Entry"),Ok|Cancel)
+{
+ QGroupBox* box=new QGroupBox(1,Qt::Horizontal,i18n("Go to Entry"),this);
+ _spinBox= new KIntSpinBox(1,max,1,1,10,box);
+
+ setMainWidget(box);
+
+ _spinBox->setFocus();
+}
+
+GotoDialog::~GotoDialog()
+{
+}
+
+
+void GotoDialog::show()
+{
+ _spinBox->setEditFocus(true);
+
+ KDialogBase::show();
+}
+
+
+int GotoDialog::number()
+{
+ return _spinBox->value();
+}
+
+void GotoDialog::setMax(int max)
+{
+ _spinBox->setRange(1,max);
+ if(_spinBox->value()>max)
+ _spinBox->setValue(max);
+}
diff --git a/kbabel/kbabel/gotodialog.h b/kbabel/kbabel/gotodialog.h
new file mode 100644
index 00000000..4c8378d8
--- /dev/null
+++ b/kbabel/kbabel/gotodialog.h
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef GOTODIALOG_H
+#define GOTODIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kdialogbase.h>
+#include <qgroupbox.h>
+
+class KIntSpinBox;
+
+class GotoDialog : public KDialogBase
+{
+public:
+ GotoDialog(int max, QWidget* parent);
+ virtual ~GotoDialog();
+
+ /** reimplemented to select contents when shown*/
+ virtual void show();
+
+ int number();
+ void setMax(int max);
+
+private:
+ KIntSpinBox* _spinBox;
+
+};
+
+
+#endif // GOTODIALOG_H
diff --git a/kbabel/kbabel/headereditor.cpp b/kbabel/kbabel/headereditor.cpp
new file mode 100644
index 00000000..55ad4eb5
--- /dev/null
+++ b/kbabel/kbabel/headereditor.cpp
@@ -0,0 +1,214 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2003 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#include <kcursor.h>
+#include <kglobalsettings.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktextedit.h>
+#include <kurl.h>
+
+#include "catalog.h"
+#include "catalogitem.h"
+#include "headereditor.h"
+#include "headerwidget.h"
+
+using namespace KBabel;
+
+HeaderEditor::HeaderEditor(Catalog* cat,const char* name)
+ : KDialogBase((QWidget*)0,name,false,QString::null, Ok|Cancel|Default|User1)
+{
+ restoreSettings();
+
+ _catalog=cat;
+ connect(_catalog,SIGNAL(signalFileOpened(bool)),this,SLOT(readHeader(bool)));
+ connect(_catalog,SIGNAL(signalHeaderChanged()),this,SLOT(updateHeader()));
+
+ setButtonText(User1,i18n("&Apply Settings"));
+ setButtonWhatsThis (User1, i18n("<qt><p>This button "
+ "updates the header using the current settings. "
+ "The resulting header is the one that would be written into the PO file "
+ "on saving.</p></qt>") );
+ setButtonText(Default,i18n("&Reset"));
+ setButtonWhatsThis (Default, i18n("<qt><p>This button "
+ "will revert all changes made so far.</p></qt>") );
+
+ _editor=new HeaderWidget(this,"internal headereditor");
+ _editor->setMinimumSize(_editorSize);
+
+ KCursor::setAutoHideCursor(_editor,true);
+
+ readHeader(cat->isReadOnly());
+ updateHeader();
+
+ setMainWidget(_editor);
+}
+
+HeaderEditor::~HeaderEditor()
+{
+ saveSettings();
+}
+
+void HeaderEditor::saveSettings()
+{
+ KConfig* config = KGlobal::config();
+
+ KConfigGroupSaver saver(config, "HeaderEditor" );
+
+ config->writeEntry( "Size", _editor->size() );
+}
+
+void HeaderEditor::restoreSettings()
+{
+ KConfig* config = KGlobal::config();
+
+ KConfigGroupSaver saver(config, "HeaderEditor" );
+
+ QSize defaultSize(350,250);
+ _editorSize = config->readSizeEntry("Size", &defaultSize );
+}
+
+bool HeaderEditor::isModified()
+{
+ return _editor->commentEdit->isModified() || _editor->headerEdit->isModified();
+}
+
+void HeaderEditor::readHeader(bool readOnly)
+{
+ setCaption(i18n("Header Editor for %1").arg(_catalog->currentURL().prettyURL()));
+
+ _editor->headerEdit->setReadOnly(readOnly);
+ _editor->commentEdit->setReadOnly(readOnly);
+ enableButton(User1,!readOnly);
+}
+
+void HeaderEditor::updateHeader()
+{
+ _editor->headerEdit->setText(_catalog->header().msgstr().first());
+ _editor->headerEdit->setModified(false);
+ _editor->commentEdit->setText(_catalog->header().comment());
+ _editor->commentEdit->setModified(false);
+}
+
+
+// update button
+void HeaderEditor::slotUser1()
+{
+ CatalogItem header;
+
+ bool error = !isValid();
+
+ if(error)
+ {
+ QString msg=i18n("<qt><p>This is not a valid header.</p>\n"
+ "<p>Please edit the header before updating!</p></qt>");
+
+ KMessageBox::sorry(this,msg);
+
+ return;
+ }
+
+ header.setComment( _editor->commentEdit->text() );
+ header.setMsgstr( _editor->headerEdit->text() );
+
+ header=_catalog->updatedHeader(header,true);
+
+ _editor->headerEdit->setText(header.msgstr().first());
+ _editor->commentEdit->setText(header.comment());
+}
+
+
+void HeaderEditor::slotDefault()
+{
+ updateHeader();
+}
+
+void HeaderEditor::slotCancel()
+{
+ updateHeader();
+
+ QDialog::reject();
+}
+
+void HeaderEditor::slotOk()
+{
+ if(isModified())
+ {
+ if(!isValid())
+ {
+ QString msg=i18n("<qt><p>This is not a valid header.</p>\n"
+ "<p>Please edit the header before updating.</p></qt>");
+
+ switch(KMessageBox::warningYesNo(this,msg,i18n("Warning"),KStdGuiItem::discard(),i18n("Edit")))
+ {
+ case KMessageBox::Yes:
+ {
+ slotCancel();
+ return;
+ }
+ default:
+ return;
+ }
+ }
+
+ CatalogItem header;
+
+ header.setComment( _editor->commentEdit->text() );
+ header.setMsgstr( _editor->headerEdit->text() );
+
+ _catalog->setHeader(header);
+ }
+
+ QDialog::accept();
+}
+
+bool HeaderEditor::isValid()
+{
+ // check the comments
+ QStringList comments = QStringList::split('\n',_editor->commentEdit->text());
+
+ for( QStringList::Iterator it = comments.begin(); it != comments.end(); ++it )
+ {
+ if( !(*it).startsWith("#") )
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#include "headereditor.moc"
diff --git a/kbabel/kbabel/headereditor.h b/kbabel/kbabel/headereditor.h
new file mode 100644
index 00000000..9fb9d6fb
--- /dev/null
+++ b/kbabel/kbabel/headereditor.h
@@ -0,0 +1,85 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2003 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef HEADEREDITOR_H
+#define HEADEREDITOR_H
+
+#include <kdialogbase.h>
+
+namespace KBabel
+{
+ class Catalog;
+}
+
+class HeaderWidget;
+
+class HeaderEditor : public KDialogBase
+{
+ Q_OBJECT
+public:
+ /**
+ * constructor for the HeaderEditor
+ * @param cat The Catalog from which the header is edited
+ */
+ HeaderEditor(KBabel::Catalog* cat,const char* name=0);
+ virtual ~HeaderEditor();
+
+ bool isModified();
+
+public slots:
+ void readHeader(bool);
+
+protected slots:
+
+ /** update button */
+ virtual void slotUser1();
+ virtual void slotCancel();
+ virtual void slotOk();
+ virtual void slotDefault();
+
+ /** updates the header when header was changed by the catalog */
+ void updateHeader();
+
+private:
+ void saveSettings();
+ void restoreSettings();
+ bool isValid();
+
+ KBabel::Catalog* _catalog;
+ HeaderWidget* _editor;
+
+ QSize _editorSize;
+};
+
+#endif // HEADEREDITOR_H
diff --git a/kbabel/kbabel/headerwidget.ui b/kbabel/kbabel/headerwidget.ui
new file mode 100644
index 00000000..f74a9ef5
--- /dev/null
+++ b/kbabel/kbabel/headerwidget.ui
@@ -0,0 +1,64 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>HeaderWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>HeaderWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>401</width>
+ <height>380</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>commentLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Comment:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>commentEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KTextEdit">
+ <property name="name">
+ <cstring>commentEdit</cstring>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>headerLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Header:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>headerEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KTextEdit">
+ <property name="name">
+ <cstring>headerEdit</cstring>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>ktextedit.h</includehint>
+ <includehint>ktextedit.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabel/hi16-app-kbabel.png b/kbabel/kbabel/hi16-app-kbabel.png
new file mode 100644
index 00000000..3b062e51
--- /dev/null
+++ b/kbabel/kbabel/hi16-app-kbabel.png
Binary files differ
diff --git a/kbabel/kbabel/hi32-app-kbabel.png b/kbabel/kbabel/hi32-app-kbabel.png
new file mode 100644
index 00000000..b7f1e843
--- /dev/null
+++ b/kbabel/kbabel/hi32-app-kbabel.png
Binary files differ
diff --git a/kbabel/kbabel/hi48-app-kbabel.png b/kbabel/kbabel/hi48-app-kbabel.png
new file mode 100644
index 00000000..77bd3530
--- /dev/null
+++ b/kbabel/kbabel/hi48-app-kbabel.png
Binary files differ
diff --git a/kbabel/kbabel/hidingmsgedit.cpp b/kbabel/kbabel/hidingmsgedit.cpp
new file mode 100644
index 00000000..f18f8b81
--- /dev/null
+++ b/kbabel/kbabel/hidingmsgedit.cpp
@@ -0,0 +1,426 @@
+/***************************************************************************
+ hidingmsgedit.cpp - description
+ -------------------
+ begin : So nov 2 2002
+ copyright : (C) 2002 by Stanislav Visnovsky
+ email : visnovsky@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+ ***************************************************************************/
+
+#include "resources.h"
+#include "hidingmsgedit.h"
+#include "mymultilineedit.h"
+#include "editcmd.h"
+
+#include <qptrlist.h>
+#include <qsizepolicy.h>
+#include <qstringlist.h>
+#include <qtabwidget.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+using namespace KBabel;
+
+HidingMsgEdit::HidingMsgEdit(uint numberOfPlurals, QWidget* eventFilter, KSpell* spell, QWidget *parent, const char *name ) :
+ QWidgetStack(parent,name)
+ , _singleEdit(0)
+ , _multipleEdit(0)
+ , _eventFilter(eventFilter)
+ , _currentEdit(0)
+ , _numberOfPlurals(numberOfPlurals)
+ , _spell(spell)
+{
+
+ _allEdits.clear();
+ setNumberOfPlurals( _numberOfPlurals );
+
+ connect( _multipleEdit, SIGNAL(currentChanged( QWidget* )),
+ this, SLOT( newCurrentMultiple( QWidget* )));
+
+ showSingle();
+}
+
+HidingMsgEdit::~HidingMsgEdit(){
+}
+
+void HidingMsgEdit::setText(QStringList texts, QString msgctxt){
+ if( texts.count() == 0 )
+ {
+ kdWarning() << "HidingMsgEdit::setText with empty text" << endl;
+ _singleEdit->clear();
+ showSingle();
+ return;
+ }
+
+ if (!msgctxt.isEmpty())
+ msgctxt = "\n>>>>> " + i18n("Context inserted by KBabel, do not translate:") + "\n" + msgctxt;
+
+ if( texts.count() == 1 )
+ {
+ _singleEdit->setText(*texts.at(0) + msgctxt);
+ showSingle();
+ }
+ else
+ {
+ if( _numberOfPlurals )
+ {
+ QStringList::iterator text = texts.begin();
+ uint i;
+ for( i=0 ; i < _numberOfPlurals && text!= texts.end() ; i++, text++ )
+ {
+ static_cast<MsgMultiLineEdit *>(_multipleEdit->page(i))->setText(*text + msgctxt);
+ }
+
+ // clean the non-initialized ones
+ while (i < _numberOfPlurals)
+ {
+ static_cast<MsgMultiLineEdit *>(_multipleEdit->page(i))->setText("");
+ i++;
+ }
+ }
+ showMultiple();
+ }
+}
+
+void HidingMsgEdit::showSingle(){
+ raiseWidget(_singleEdit);
+ _currentEdit=_singleEdit;
+ _currentEdit->setFocus();
+
+ emit currentFormChanged ( 0 );
+}
+
+void HidingMsgEdit::showMultiple(){
+ raiseWidget(_multipleEdit);
+ _currentEdit=static_cast<MsgMultiLineEdit*>(_multipleEdit->currentPage());
+ _currentEdit->setFocus();
+
+ emit currentFormChanged ( _multipleEdit->currentPageIndex () );
+}
+
+void HidingMsgEdit::showPlurals( bool on )
+{
+ if( on ) showMultiple();
+ else showSingle();
+}
+
+void HidingMsgEdit::showForm(int form)
+{
+ if( _currentEdit==_singleEdit && form>0 )
+ {
+ showMultiple();
+ _multipleEdit->setCurrentPage(form);
+ _currentEdit=static_cast<MsgMultiLineEdit*>(_multipleEdit->currentPage());
+ emit currentFormChanged ( form );
+ }
+ else
+ if( _currentEdit!=_singleEdit )
+ {
+ _multipleEdit->setCurrentPage(form);
+ _currentEdit=static_cast<MsgMultiLineEdit*>(_multipleEdit->currentPage());
+ emit currentFormChanged ( 0 );
+ }
+ _currentEdit->setFocus();
+}
+
+void HidingMsgEdit::setNumberOfPlurals( uint numberOfPlurals )
+{
+ _numberOfPlurals = numberOfPlurals;
+
+ // find out the current shown version
+ bool plurals = _currentEdit != _singleEdit;
+ bool readonly = _currentEdit ? _currentEdit->isReadOnly () : true;
+
+ // cleanup old
+ _currentEdit=0;
+ _allEdits.clear();
+ if( _singleEdit )
+ {
+ removeWidget( _singleEdit );
+ delete _singleEdit;
+ }
+
+ if( _multipleEdit )
+ {
+ removeWidget( _multipleEdit );
+ delete _multipleEdit;
+ }
+
+ // create new
+ _singleEdit = new MsgMultiLineEdit( 0, _spell, this, "singleEdit" );
+ _allEdits.append( _singleEdit );
+ if( _eventFilter )
+ _singleEdit->installEventFilter(_eventFilter);
+
+ _multipleEdit = new QTabWidget( this );
+
+ MsgMultiLineEdit* pl;
+ for(uint i=0 ; i< _numberOfPlurals ; i++)
+ {
+ pl = new MsgMultiLineEdit( i, _spell, _multipleEdit, QString("multipleEdit %1").arg(i).local8Bit());
+ _allEdits.append(pl);
+ _multipleEdit->addTab( pl, i18n("Plural %1").arg(i+1));
+ if( _eventFilter )
+ pl->installEventFilter(_eventFilter);
+ }
+
+ addWidget(_singleEdit);
+ addWidget(_multipleEdit);
+
+ for( MsgMultiLineEdit* e = _allEdits.first() ; e ; e = _allEdits.next() )
+ {
+ connect( e, SIGNAL( signalUndoCmd( KBabel::EditCommand* )),
+ this, SIGNAL( signalUndoCmd( KBabel::EditCommand* )));
+ connect( e, SIGNAL( textChanged() ) , this, SIGNAL( textChanged() ));
+ connect( e, SIGNAL( textChanged() ) , this, SLOT( emitTextChanged() ));
+ connect( e, SIGNAL( cursorPositionChanged( int, int )),
+ this, SLOT( emitCursorPositionChanged( int, int )) );
+ }
+
+ showPlurals( plurals );
+
+ _currentEdit->setReadOnly (readonly);
+}
+
+void HidingMsgEdit::emitTextChanged()
+{
+ emit textChanged(_currentEdit->text());
+}
+
+uint HidingMsgEdit::currentForm()
+{
+ if( _currentEdit == _singleEdit ) return 0;
+ else return _multipleEdit->currentPageIndex();
+}
+
+void HidingMsgEdit::newCurrentMultiple( QWidget* widget )
+{
+ _currentEdit = dynamic_cast<MsgMultiLineEdit*>(widget);
+ emit currentFormChanged ( _multipleEdit->currentPageIndex () );
+}
+
+bool HidingMsgEdit::isModified() {
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ if( e->isModified() )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void HidingMsgEdit::setReadOnly(bool on) {
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setReadOnly( on );
+ }
+}
+
+void HidingMsgEdit::processCommand(EditCommand* cmd, bool undo)
+{
+ if( _currentEdit == _singleEdit )
+ {
+ _singleEdit->processCommand(cmd,undo);
+ }
+ else
+ {
+ if( cmd->terminator() == 0)
+ {
+ static_cast<MsgMultiLineEdit*>(
+ _multipleEdit->page(static_cast<DelTextCmd*>(cmd)->pluralNumber)
+ )->processCommand(cmd,undo);
+ }
+ }
+}
+
+void HidingMsgEdit::setSpacePoints(bool on)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setSpacePoints( on );
+ }
+}
+
+void HidingMsgEdit::setHighlightSyntax( bool on )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setHighlightSyntax( on );
+ }
+}
+
+void HidingMsgEdit::setQuotes(bool on)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setQuotes( on );
+ }
+}
+
+void HidingMsgEdit::setBgColor( const QColor& color)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setBgColor( color );
+ }
+}
+
+void HidingMsgEdit::setHighlightColors(const QColor& quoteColor, const QColor& unquoteColor
+ , const QColor& cformatColor, const QColor& accelColor, const QColor& tagColor)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setHighlightColors( quoteColor, unquoteColor, cformatColor,
+ accelColor, tagColor );
+ }
+}
+
+void HidingMsgEdit::setOverwriteMode( bool b )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setOverwriteMode( b );
+ }
+}
+
+void HidingMsgEdit::setModified( bool b )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setModified( b );
+ }
+}
+
+void HidingMsgEdit::setCleverEditing( bool on )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setCleverEditing( on );
+ }
+}
+
+void HidingMsgEdit::setHighlightBg( bool on )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setHighlightBg( on );
+ }
+}
+
+void HidingMsgEdit::setContextMenu( QPopupMenu *menu )
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setContextMenu( menu );
+ }
+}
+
+void HidingMsgEdit::setCurrentColor( const MsgMultiLineEdit::TextColor color)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setCurrentColor( color );
+ }
+}
+
+bool HidingMsgEdit::hasFocus ()
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ if( e->hasFocus() ) return true;
+ }
+
+ return _multipleEdit->hasFocus() || QWidgetStack::hasFocus();
+}
+
+void HidingMsgEdit::setDiffColors(const QColor& addColor, const QColor& delColor)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setDiffColors( addColor, delColor );
+ }
+}
+
+void HidingMsgEdit::setDiffMode(bool on)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setDiffMode( on );
+ }
+}
+
+void HidingMsgEdit::setDiffDisplayMode(bool underlineAdded, bool strikeOutDeleted)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setDiffDisplayMode( underlineAdded, strikeOutDeleted );
+ }
+}
+
+void HidingMsgEdit::setFont(const QFont& font)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setFont( font );
+ }
+}
+
+void HidingMsgEdit::setSpellChecker(KSpell* spell)
+{
+ for( MsgMultiLineEdit* e = _allEdits.first(); e ; e = _allEdits.next() )
+ {
+ e->setSpellChecker( spell );
+ }
+ _spell = spell;
+}
+
+void HidingMsgEdit::emitCursorPositionChanged(int line, int col )
+{
+ int linestart = 0;
+ int indexline = _currentEdit->lineOfChar( line, col );
+ if ( indexline > 0 )
+ {
+ int min = 0, max = col;
+ int i = (min + max)/2;
+ int iline = _currentEdit->lineOfChar( line, i );
+ while ( iline != indexline-1 ||
+ _currentEdit->lineOfChar( line, i+1 ) != indexline )
+ {
+ Q_ASSERT( min != max && min != i && max != i );
+ if ( iline < indexline )
+ min = i;
+ else
+ max = i;
+ i = (min + max)/2;
+ iline = _currentEdit->lineOfChar( line, i );
+ }
+ linestart = i+1;
+ }
+ Q_ASSERT( linestart >= 0 );
+
+ emit cursorPositionChanged(line + _currentEdit->lineOfChar( line, col ) ,col-linestart);
+}
+
+#include "hidingmsgedit.moc"
+
diff --git a/kbabel/kbabel/hidingmsgedit.h b/kbabel/kbabel/hidingmsgedit.h
new file mode 100644
index 00000000..38e5d750
--- /dev/null
+++ b/kbabel/kbabel/hidingmsgedit.h
@@ -0,0 +1,161 @@
+/***************************************************************************
+ hidingmsgedit.h - description
+ -------------------
+ begin : So nov 2 2002
+ copyright : (C) 2002 by Stanislav Visnovsky
+ email : visnovsky@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+ * *
+ ***************************************************************************/
+
+#ifndef HIDINGMSGEDIT_H
+#define HIDINGMSGEDIT_H
+
+#include <qwidgetstack.h>
+#include <qguardedptr.h>
+#include <qptrlist.h>
+
+#include "mymultilineedit.h"
+
+class KSpell;
+class QTabWidget;
+class QPopupMenu;
+
+namespace KBabel
+{
+ class EditCommand;
+}
+
+/**
+ *@author Stanislav Visnovsky <visnovsky@kde.org>
+ */
+
+class HidingMsgEdit : public QWidgetStack {
+ Q_OBJECT
+public:
+ HidingMsgEdit(uint numberOfPlurals, QWidget* eventFilter=0, KSpell* spell=0, QWidget *parent=0, const char *name=0);
+ ~HidingMsgEdit();
+
+ void setNumberOfPlurals(uint numberOfPlurals);
+
+ // return index number for a currently shown plural form (0=singular or no plurals)
+ uint currentForm();
+
+ // MsgMultiLineEdit interface
+ bool isOverwriteMode() const { return _currentEdit->isOverwriteMode(); }
+ bool isModified();
+ bool hasSelectedText() const { return _currentEdit->hasSelectedText(); }
+ QString selectedText () const { return _currentEdit->selectedText(); }
+ void processCommand(KBabel::EditCommand* cmd, bool undo=false);
+ void offset2Pos(int offset, int &row, int &col) const
+ { return _currentEdit->offset2Pos(offset, row, col ); }
+ void getCursorPosition(int *para, int *index) const
+ { _currentEdit->getCursorPosition(para,index); }
+ int currentIndex() const
+ { return _currentEdit->currentIndex(); }
+ int beginOfLastMarkedText() const
+ { return _currentEdit->beginOfLastMarkedText(); }
+ virtual void setFont ( const QFont & );
+ void setCurrentColor(const MsgMultiLineEdit::TextColor color);
+ bool spacePoints() const { return _currentEdit->spacePoints(); }
+ void setSpacePoints(bool on);
+ bool quotes() const { return _currentEdit->quotes(); }
+ void setQuotes(bool on);
+ void setBgColor( const QColor& color);
+ bool highlightBg() const { return _currentEdit->highlightBg(); }
+ bool highlightSyntax() const { return _currentEdit->highlightSyntax(); }
+ void setHighlightColors(const QColor& quoteColor, const QColor& unquoteColor
+ , const QColor& cformatColor, const QColor& accelColor, const QColor& tagColor);
+ int beginOfMarkedText() { return _currentEdit->beginOfMarkedText(); }
+ virtual void insertAt ( const QString & s, int line, int col, bool mark = false )
+ { _currentEdit->insertAt( s, line, col, mark ); }
+
+ void setDiffMode(bool on);
+ void setDiffDisplayMode(bool underlineAdded, bool strikeOutDeleted);
+ void setDiffColors(const QColor& addColor, const QColor& delColor);
+ QString text(int para) { return _currentEdit->text(para); }
+
+ void setSpellChecker(KSpell* spell);
+
+ void selectTag(int start, int length) { _currentEdit->selectTag(start,length); }
+
+ // reiplemented to return correct value
+ bool hasFocus ();
+public slots: // Public slots
+ void setText(QStringList texts, QString msgctxt = QString::null);
+ void showSingle();
+ void showMultiple();
+ void showPlurals( bool on );
+ void showForm(int form);
+ virtual void setFocus() { _currentEdit->setFocus(); }
+ void forceUpdate() { _currentEdit->forceUpdate(); }
+
+ // MsgMultiLineEdit interface
+ virtual void setReadOnly( bool b );
+ virtual void setOverwriteMode( bool b );
+ virtual void setModified( bool b );
+ void setCleverEditing( bool on );
+ void setHighlightBg( bool on );
+ void setHighlightSyntax( bool on );
+ virtual void clear() { _currentEdit->clear(); }
+ virtual void cut() { _currentEdit->cut(); }
+ virtual void copy() { _currentEdit->copy(); }
+ virtual void paste() { _currentEdit->paste(); }
+ virtual void setSelection( int paraFrom, int indexFrom, int paraTo, int indexTo, int selNum = 0 )
+ { _currentEdit->setSelection( paraFrom, indexFrom, paraTo, indexTo, selNum) ; }
+ virtual void selectAll(bool select=true) { _currentEdit->selectAll(select); }
+ virtual void setCursorPosition ( int para, int index )
+ { _currentEdit->setCursorPosition(para,index); }
+ virtual void setContextMenu( QPopupMenu *menu );
+
+signals:
+ void signalUndoCmd(KBabel::EditCommand*);
+ void textChanged();
+ void textChanged(const QString&);
+ void cursorPositionChanged ( int para, int pos );
+ void currentFormChanged ( uint form );
+
+private slots:
+
+ void emitTextChanged();
+
+ // invoked if TabWidget changes the shown widget
+ void newCurrentMultiple( QWidget * );
+ // invoked by inner cursorPositionChanged() to transform line/col for wrapping
+ void emitCursorPositionChanged( int para, int pos );
+
+private: // Private attributes
+ /** Used for editting non-plural messages */
+ MsgMultiLineEdit* _singleEdit;
+ /** Used for editting plural forms */
+ QTabWidget* _multipleEdit;
+ QWidget* _eventFilter;
+
+ MsgMultiLineEdit* _currentEdit;
+ QPtrList<MsgMultiLineEdit> _allEdits;
+
+ uint _numberOfPlurals;
+
+ QGuardedPtr<KSpell> _spell;
+};
+
+#endif
diff --git a/kbabel/kbabel/icons/Makefile.am b/kbabel/kbabel/icons/Makefile.am
new file mode 100644
index 00000000..07f64107
--- /dev/null
+++ b/kbabel/kbabel/icons/Makefile.am
@@ -0,0 +1,5 @@
+# Add all of your pixmaps here
+icons_ICON = msgid2msgstr nexterror nextfuzzy nextfuzzyuntrans nextuntranslated preverror prevfuzzy prevfuzzyuntrans prevuntranslated search2msgstr transsearch insert_tag diff autodiff togglefuzzy insert_arg spellcheck_all spellcheck_actual spellcheck_from_cursor spellcheck_selected catalogmanager
+
+# This is where it will all be installed
+iconsdir = $(kde_datadir)/kbabel/icons
diff --git a/kbabel/kbabel/icons/hi16-action-autodiff.png b/kbabel/kbabel/icons/hi16-action-autodiff.png
new file mode 100644
index 00000000..d79e471f
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-autodiff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-catalogmanager.png b/kbabel/kbabel/icons/hi16-action-catalogmanager.png
new file mode 100644
index 00000000..369ab591
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-catalogmanager.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-diff.png b/kbabel/kbabel/icons/hi16-action-diff.png
new file mode 100644
index 00000000..9e13d750
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-diff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-insert_arg.png b/kbabel/kbabel/icons/hi16-action-insert_arg.png
new file mode 100644
index 00000000..e133f0e4
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-insert_arg.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-insert_tag.png b/kbabel/kbabel/icons/hi16-action-insert_tag.png
new file mode 100644
index 00000000..e0757463
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-insert_tag.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png
new file mode 100644
index 00000000..6f5534fa
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-nexterror.png b/kbabel/kbabel/icons/hi16-action-nexterror.png
new file mode 100644
index 00000000..78876d16
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-nexterror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-nextfuzzy.png b/kbabel/kbabel/icons/hi16-action-nextfuzzy.png
new file mode 100644
index 00000000..6bcc43ed
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-nextfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png
new file mode 100644
index 00000000..d17b402f
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-nextuntranslated.png b/kbabel/kbabel/icons/hi16-action-nextuntranslated.png
new file mode 100644
index 00000000..317bb595
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-nextuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-preverror.png b/kbabel/kbabel/icons/hi16-action-preverror.png
new file mode 100644
index 00000000..630da7d7
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-preverror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-prevfuzzy.png b/kbabel/kbabel/icons/hi16-action-prevfuzzy.png
new file mode 100644
index 00000000..a381d93e
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-prevfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png
new file mode 100644
index 00000000..64995893
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-prevuntranslated.png b/kbabel/kbabel/icons/hi16-action-prevuntranslated.png
new file mode 100644
index 00000000..49610f03
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-prevuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-search2msgstr.png b/kbabel/kbabel/icons/hi16-action-search2msgstr.png
new file mode 100644
index 00000000..99986bba
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-search2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png b/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png
new file mode 100644
index 00000000..1a653f5e
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_all.png b/kbabel/kbabel/icons/hi16-action-spellcheck_all.png
new file mode 100644
index 00000000..c0b622d2
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-spellcheck_all.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png b/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png
new file mode 100644
index 00000000..0bbd0a61
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png b/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png
new file mode 100644
index 00000000..feacd83d
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-togglefuzzy.png b/kbabel/kbabel/icons/hi16-action-togglefuzzy.png
new file mode 100644
index 00000000..3538fde6
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-togglefuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi16-action-transsearch.png b/kbabel/kbabel/icons/hi16-action-transsearch.png
new file mode 100644
index 00000000..e1776a6e
--- /dev/null
+++ b/kbabel/kbabel/icons/hi16-action-transsearch.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-autodiff.png b/kbabel/kbabel/icons/hi22-action-autodiff.png
new file mode 100644
index 00000000..91988ede
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-autodiff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-catalogmanager.png b/kbabel/kbabel/icons/hi22-action-catalogmanager.png
new file mode 100644
index 00000000..48bbade3
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-catalogmanager.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-diff.png b/kbabel/kbabel/icons/hi22-action-diff.png
new file mode 100644
index 00000000..321ed59e
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-diff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-insert_arg.png b/kbabel/kbabel/icons/hi22-action-insert_arg.png
new file mode 100644
index 00000000..6aa1da61
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-insert_arg.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-insert_tag.png b/kbabel/kbabel/icons/hi22-action-insert_tag.png
new file mode 100644
index 00000000..cbd50021
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-insert_tag.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png
new file mode 100644
index 00000000..3323ada2
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-nexterror.png b/kbabel/kbabel/icons/hi22-action-nexterror.png
new file mode 100644
index 00000000..24a94589
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-nexterror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-nextfuzzy.png b/kbabel/kbabel/icons/hi22-action-nextfuzzy.png
new file mode 100644
index 00000000..2e302679
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-nextfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png
new file mode 100644
index 00000000..47a3c36a
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-nextuntranslated.png b/kbabel/kbabel/icons/hi22-action-nextuntranslated.png
new file mode 100644
index 00000000..eb4ea46c
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-nextuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-preverror.png b/kbabel/kbabel/icons/hi22-action-preverror.png
new file mode 100644
index 00000000..089e5a12
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-preverror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-prevfuzzy.png b/kbabel/kbabel/icons/hi22-action-prevfuzzy.png
new file mode 100644
index 00000000..aec1f219
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-prevfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png
new file mode 100644
index 00000000..4e7c88d4
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-prevuntranslated.png b/kbabel/kbabel/icons/hi22-action-prevuntranslated.png
new file mode 100644
index 00000000..8f5c764f
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-prevuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-search2msgstr.png b/kbabel/kbabel/icons/hi22-action-search2msgstr.png
new file mode 100644
index 00000000..9df8dfca
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-search2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-togglefuzzy.png b/kbabel/kbabel/icons/hi22-action-togglefuzzy.png
new file mode 100644
index 00000000..40227189
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-togglefuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi22-action-transsearch.png b/kbabel/kbabel/icons/hi22-action-transsearch.png
new file mode 100644
index 00000000..06d5852c
--- /dev/null
+++ b/kbabel/kbabel/icons/hi22-action-transsearch.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-autodiff.png b/kbabel/kbabel/icons/hi32-action-autodiff.png
new file mode 100644
index 00000000..471ece08
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-autodiff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-catalogmanager.png b/kbabel/kbabel/icons/hi32-action-catalogmanager.png
new file mode 100644
index 00000000..d527b872
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-catalogmanager.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-diff.png b/kbabel/kbabel/icons/hi32-action-diff.png
new file mode 100644
index 00000000..535d508a
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-diff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-insert_arg.png b/kbabel/kbabel/icons/hi32-action-insert_arg.png
new file mode 100644
index 00000000..ea8c8179
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-insert_arg.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-insert_tag.png b/kbabel/kbabel/icons/hi32-action-insert_tag.png
new file mode 100644
index 00000000..d11981ef
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-insert_tag.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png
new file mode 100644
index 00000000..8dc03384
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-nexterror.png b/kbabel/kbabel/icons/hi32-action-nexterror.png
new file mode 100644
index 00000000..ee458abc
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-nexterror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-nextfuzzy.png b/kbabel/kbabel/icons/hi32-action-nextfuzzy.png
new file mode 100644
index 00000000..089e6357
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-nextfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png
new file mode 100644
index 00000000..82f535e6
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-nextuntranslated.png b/kbabel/kbabel/icons/hi32-action-nextuntranslated.png
new file mode 100644
index 00000000..8b9db6f7
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-nextuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-preverror.png b/kbabel/kbabel/icons/hi32-action-preverror.png
new file mode 100644
index 00000000..7ff8da13
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-preverror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-prevfuzzy.png b/kbabel/kbabel/icons/hi32-action-prevfuzzy.png
new file mode 100644
index 00000000..0280c02f
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-prevfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png
new file mode 100644
index 00000000..bcfb55aa
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-prevuntranslated.png b/kbabel/kbabel/icons/hi32-action-prevuntranslated.png
new file mode 100644
index 00000000..e4bdb694
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-prevuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-search2msgstr.png b/kbabel/kbabel/icons/hi32-action-search2msgstr.png
new file mode 100644
index 00000000..3337b646
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-search2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-togglefuzzy.png b/kbabel/kbabel/icons/hi32-action-togglefuzzy.png
new file mode 100644
index 00000000..0a9492a0
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-togglefuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/hi32-action-transsearch.png b/kbabel/kbabel/icons/hi32-action-transsearch.png
new file mode 100644
index 00000000..19e766c5
--- /dev/null
+++ b/kbabel/kbabel/icons/hi32-action-transsearch.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-autodiff.png b/kbabel/kbabel/icons/lo16-action-autodiff.png
new file mode 100644
index 00000000..7cb56260
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-autodiff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-catalogmanager.png b/kbabel/kbabel/icons/lo16-action-catalogmanager.png
new file mode 100644
index 00000000..75a95c0c
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-catalogmanager.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-diff.png b/kbabel/kbabel/icons/lo16-action-diff.png
new file mode 100644
index 00000000..05b82b53
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-diff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-insert_arg.png b/kbabel/kbabel/icons/lo16-action-insert_arg.png
new file mode 100644
index 00000000..bc67bc15
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-insert_arg.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-insert_tag.png b/kbabel/kbabel/icons/lo16-action-insert_tag.png
new file mode 100644
index 00000000..283b0793
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-insert_tag.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png b/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png
new file mode 100644
index 00000000..8cb33ccb
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-nexterror.png b/kbabel/kbabel/icons/lo16-action-nexterror.png
new file mode 100644
index 00000000..a2d48527
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-nexterror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-nextfuzzy.png b/kbabel/kbabel/icons/lo16-action-nextfuzzy.png
new file mode 100644
index 00000000..828bfc3b
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-nextfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png
new file mode 100644
index 00000000..ad150c58
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-nextuntranslated.png b/kbabel/kbabel/icons/lo16-action-nextuntranslated.png
new file mode 100644
index 00000000..bbcda8c3
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-nextuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-preverror.png b/kbabel/kbabel/icons/lo16-action-preverror.png
new file mode 100644
index 00000000..10c2f7e5
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-preverror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-prevfuzzy.png b/kbabel/kbabel/icons/lo16-action-prevfuzzy.png
new file mode 100644
index 00000000..a19cb6ac
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-prevfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png
new file mode 100644
index 00000000..f63b3598
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-prevuntranslated.png b/kbabel/kbabel/icons/lo16-action-prevuntranslated.png
new file mode 100644
index 00000000..a3ad3431
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-prevuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-search2msgstr.png b/kbabel/kbabel/icons/lo16-action-search2msgstr.png
new file mode 100644
index 00000000..36d25867
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-search2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png b/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png
new file mode 100644
index 00000000..1a653f5e
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_all.png b/kbabel/kbabel/icons/lo16-action-spellcheck_all.png
new file mode 100644
index 00000000..c0b622d2
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-spellcheck_all.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png b/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png
new file mode 100644
index 00000000..0bbd0a61
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png b/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png
new file mode 100644
index 00000000..feacd83d
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-togglefuzzy.png b/kbabel/kbabel/icons/lo16-action-togglefuzzy.png
new file mode 100644
index 00000000..3538fde6
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-togglefuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo16-action-transsearch.png b/kbabel/kbabel/icons/lo16-action-transsearch.png
new file mode 100644
index 00000000..f933a6eb
--- /dev/null
+++ b/kbabel/kbabel/icons/lo16-action-transsearch.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-autodiff.png b/kbabel/kbabel/icons/lo32-action-autodiff.png
new file mode 100644
index 00000000..b6cb074a
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-autodiff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-catalogmanager.png b/kbabel/kbabel/icons/lo32-action-catalogmanager.png
new file mode 100644
index 00000000..1e9da58f
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-catalogmanager.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-diff.png b/kbabel/kbabel/icons/lo32-action-diff.png
new file mode 100644
index 00000000..8be1d0a4
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-diff.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-insert_arg.png b/kbabel/kbabel/icons/lo32-action-insert_arg.png
new file mode 100644
index 00000000..39fcf1fd
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-insert_arg.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-insert_tag.png b/kbabel/kbabel/icons/lo32-action-insert_tag.png
new file mode 100644
index 00000000..820bc66f
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-insert_tag.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png b/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png
new file mode 100644
index 00000000..7497c265
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-nexterror.png b/kbabel/kbabel/icons/lo32-action-nexterror.png
new file mode 100644
index 00000000..de06b7e8
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-nexterror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-nextfuzzy.png b/kbabel/kbabel/icons/lo32-action-nextfuzzy.png
new file mode 100644
index 00000000..9218c291
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-nextfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png
new file mode 100644
index 00000000..6efbd5a7
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-nextuntranslated.png b/kbabel/kbabel/icons/lo32-action-nextuntranslated.png
new file mode 100644
index 00000000..c6954974
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-nextuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-preverror.png b/kbabel/kbabel/icons/lo32-action-preverror.png
new file mode 100644
index 00000000..c8196a3e
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-preverror.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-prevfuzzy.png b/kbabel/kbabel/icons/lo32-action-prevfuzzy.png
new file mode 100644
index 00000000..4a078602
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-prevfuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png
new file mode 100644
index 00000000..902c84cb
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-prevuntranslated.png b/kbabel/kbabel/icons/lo32-action-prevuntranslated.png
new file mode 100644
index 00000000..32ea00c4
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-prevuntranslated.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-search2msgstr.png b/kbabel/kbabel/icons/lo32-action-search2msgstr.png
new file mode 100644
index 00000000..b2a83b66
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-search2msgstr.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-togglefuzzy.png b/kbabel/kbabel/icons/lo32-action-togglefuzzy.png
new file mode 100644
index 00000000..0a9492a0
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-togglefuzzy.png
Binary files differ
diff --git a/kbabel/kbabel/icons/lo32-action-transsearch.png b/kbabel/kbabel/icons/lo32-action-transsearch.png
new file mode 100644
index 00000000..e91eedcc
--- /dev/null
+++ b/kbabel/kbabel/icons/lo32-action-transsearch.png
Binary files differ
diff --git a/kbabel/kbabel/kbabel-difftoproject.upd b/kbabel/kbabel/kbabel-difftoproject.upd
new file mode 100644
index 00000000..183f6268
--- /dev/null
+++ b/kbabel/kbabel/kbabel-difftoproject.upd
@@ -0,0 +1,6 @@
+Id=kde34
+File=kbabelrc,kbabel.defaultproject
+Group=Editor,Misc
+Key=DiffBaseDir
+Key=UseDBForDiff
+#eof
diff --git a/kbabel/kbabel/kbabel-project.upd b/kbabel/kbabel/kbabel-project.upd
new file mode 100644
index 00000000..20fcb958
--- /dev/null
+++ b/kbabel/kbabel/kbabel-project.upd
@@ -0,0 +1,11 @@
+Id=kde33
+File=kbabelrc,kbabel.defaultproject
+Group=CatalogManager
+AllKeys
+Group=Header
+AllKeys
+Group=Misc
+AllKeys
+Group=SourceContext
+AllKeys
+#eof
diff --git a/kbabel/kbabel/kbabel.cpp b/kbabel/kbabel/kbabel.cpp
new file mode 100644
index 00000000..cae7bf77
--- /dev/null
+++ b/kbabel/kbabel/kbabel.cpp
@@ -0,0 +1,1825 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "kbabel.h"
+
+#include "kbabelsettings.h"
+#include "kbprojectsettings.h"
+#include "kbabelpref.h"
+#include "projectpref.h"
+#include "kbabelsplash.h"
+#include "regexpextractor.h"
+#include "toolaction.h"
+#include "commentview.h"
+#include "contextview.h"
+#include "charselectview.h"
+#include "taglistview.h"
+#include "sourceview.h"
+
+#include <qdragobject.h>
+#include <qlineedit.h>
+#include <qpopupmenu.h>
+#include <qhbox.h>
+#include <qwhatsthis.h>
+#include <qsize.h>
+#include <qtextcodec.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+
+#include <dcopclient.h>
+#include <kdatatool.h>
+#include <kpopupmenu.h>
+#include <kstatusbar.h>
+#include <kstdaccel.h>
+#include <kedittoolbar.h>
+#include <kglobal.h>
+#include <kled.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <ktoolbar.h>
+#include <kfiledialog.h>
+#include <kconfig.h>
+#include <kurl.h>
+#include <kdialogbase.h>
+#include <kprogress.h>
+#include <kpushbutton.h>
+#include <kmessagebox.h>
+#include <kwin.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kspelldlg.h>
+#include <ksqueezedtextlabel.h>
+#include <kurldrag.h>
+
+#include "resources.h"
+#include "kbcatalog.h"
+#include "dictionarymenu.h"
+#include "kbabeldictbox.h"
+#include "kbmailer.h"
+#include "kbbookmarkhandler.h"
+#include "kbprojectmanager.h"
+#include "projectpref.h"
+#include "projectwizard.h"
+
+#include "version.h"
+
+#define ID_STATUS_TOTAL 1
+#define ID_STATUS_CURRENT 2
+#define ID_STATUS_FUZZY 3
+#define ID_STATUS_UNTRANS 4
+#define ID_STATUS_EDITMODE 5
+#define ID_STATUS_READONLY 6
+#define ID_STATUS_CURSOR 7
+
+// maximum number of recent files
+#define MAX_RECENT 10
+
+using namespace KBabel;
+
+QPtrList<KBabelPreferences> KBabelMW::prefDialogs;
+
+class MyKProgress: public KProgress
+{
+public:
+ MyKProgress( QWidget *parent, const char *name ) : KProgress( parent, name )
+ {
+ setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
+ }
+ QSize sizeHint() const { return QSize( 1, 1);}
+};
+
+KBabelMW::KBabelMW(QString projectFile)
+ : KDockMainWindow (), m_charselectorview(0)
+{
+ if ( projectFile.isEmpty() )
+ projectFile = KBabel::ProjectManager::defaultProjectName();
+ _project = ProjectManager::open(projectFile);
+
+ if ( _project == NULL ) // FIXME should not happen anymore
+ {
+ KMessageBox::error( this, i18n("Cannot open project file\n%1").arg(projectFile)
+ , i18n("Project File Error"));
+ _project = ProjectManager::open(KBabel::ProjectManager::defaultProjectName());
+ }
+
+ KBCatalog* catalog=new KBCatalog(projectFile);
+ init(catalog);
+}
+
+KBabelMW::KBabelMW(KBCatalog* catalog, QString projectFile)
+ : KDockMainWindow (), m_charselectorview(0)
+{
+ if ( projectFile.isEmpty() )
+ projectFile = KBabel::ProjectManager::defaultProjectName();
+ _project = ProjectManager::open(projectFile);
+
+ if ( _project == NULL )
+ {
+ KMessageBox::error( this, i18n("Cannot open project file\n%1").arg(projectFile)
+ , i18n("Project File Error"));
+ _project = ProjectManager::open(KBabel::ProjectManager::defaultProjectName());
+ }
+
+ init(catalog);
+}
+
+void KBabelMW::init(KBCatalog* catalog)
+{
+ _config = KSharedConfig::openConfig( "kbabelrc" );
+
+ _toolsShortcuts.clear();
+
+ _fuzzyLed=0;
+ _untransLed=0;
+ _errorLed=0;
+
+ _projectDialog=0;
+
+ _prefDialog=0;
+ prefDialogs.setAutoDelete(true);
+
+ _statusbarTimer = new QTimer(this, "statusbartimer");
+ connect(_statusbarTimer,SIGNAL(timeout()),this
+ ,SLOT(clearStatusbarMsg()));
+
+ // FIXME:
+ Q_ASSERT(_project);
+
+ m_view=new KBabelView(catalog,this, _project);
+
+ setXMLFile ("kbabelui.rc");
+
+ createGUI (0);
+
+ // accept dnd
+ setAcceptDrops(true);
+
+
+ // setup our menubars and toolbars
+ setupStatusBar();
+ setupActions();
+ stateChanged( "fileopened" , StateReverse );
+ stateChanged( "readonly", StateNoReverse );
+
+ QPopupMenu* popup;
+ popup = (QPopupMenu*)(factory()->container("rmb_edit", this));
+ if(popup)
+ {
+ m_view->setRMBEditMenu(popup);
+ }
+ popup = (QPopupMenu*)(factory()->container("rmb_search", this));
+ if(popup)
+ {
+ m_view->setRMBSearchMenu(popup);
+ }
+
+
+ connect(catalog,SIGNAL(signalUndoAvailable(bool)),this
+ ,SLOT(enableUndo(bool)));
+ connect(catalog,SIGNAL(signalRedoAvailable(bool)),this
+ ,SLOT(enableRedo(bool)));
+ connect(catalog,SIGNAL(signalNumberOfFuzziesChanged(uint)),this
+ ,SLOT(setNumberOfFuzzies(uint)));
+ connect(catalog,SIGNAL(signalNumberOfUntranslatedChanged(uint)),this
+ ,SLOT(setNumberOfUntranslated(uint)));
+ connect(catalog,SIGNAL(signalTotalNumberChanged(uint)),this
+ ,SLOT(setNumberOfTotal(uint)));
+ connect(catalog,SIGNAL(signalProgress(int)),_progressBar,SLOT(setProgress(int)));
+ connect(catalog,SIGNAL(signalClearProgressBar()),this,SLOT(clearProgressBar()));
+ connect(catalog,SIGNAL(signalResetProgressBar(QString,int))
+ ,this,SLOT(prepareProgressBar(QString,int)));
+ connect(catalog,SIGNAL(signalFileOpened(bool)),this,SLOT(enableDefaults(bool)));
+ connect(catalog,SIGNAL(signalFileOpened(bool)),m_view,SLOT(newFileOpened(bool)));
+ connect(catalog,SIGNAL(signalModified(bool)),this,SLOT(showModified(bool)));
+
+ // allow the view to change the statusbar and caption
+ connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)),
+ this, SLOT(changeStatusbar(const QString&)));
+ connect(m_view, SIGNAL(signalChangeCaption(const QString&)),
+ this, SLOT(changeCaption(const QString&)));
+ connect(m_view,SIGNAL(signalFirstDisplayed(bool, bool)),this
+ ,SLOT(firstEntryDisplayed(bool, bool)));
+ connect(m_view,SIGNAL(signalLastDisplayed(bool, bool)),this
+ ,SLOT(lastEntryDisplayed(bool, bool)));
+ connect(m_view,SIGNAL(signalFuzzyDisplayed(bool)),this
+ ,SLOT(fuzzyDisplayed(bool)));
+ connect(m_view,SIGNAL(signalUntranslatedDisplayed(bool)),this
+ ,SLOT(untranslatedDisplayed(bool)));
+ connect(m_view,SIGNAL(signalFaultyDisplayed(bool)),this
+ ,SLOT(faultyDisplayed(bool)));
+ connect(m_view,SIGNAL(signalDisplayed(const KBabel::DocPosition&)),this
+ ,SLOT(displayedEntryChanged(const KBabel::DocPosition&)));
+ connect(m_view,SIGNAL(signalFuzzyAfterwards(bool)),this
+ ,SLOT(hasFuzzyAfterwards(bool)));
+ connect(m_view,SIGNAL(signalFuzzyInFront(bool)),this
+ ,SLOT(hasFuzzyInFront(bool)));
+ connect(m_view,SIGNAL(signalUntranslatedAfterwards(bool)),this
+ ,SLOT(hasUntranslatedAfterwards(bool)));
+ connect(m_view,SIGNAL(signalUntranslatedInFront(bool)),this
+ ,SLOT(hasUntranslatedInFront(bool)));
+ connect(m_view,SIGNAL(signalErrorAfterwards(bool)),this
+ ,SLOT(hasErrorAfterwards(bool)));
+ connect(m_view,SIGNAL(signalErrorInFront(bool)),this
+ ,SLOT(hasErrorInFront(bool)));
+ connect(m_view,SIGNAL(signalBackHistory(bool)),this
+ ,SLOT(enableBackHistory(bool)));
+ connect(m_view,SIGNAL(signalForwardHistory(bool)),this
+ ,SLOT(enableForwardHistory(bool)));
+
+
+ connect(m_view,SIGNAL(ledColorChanged(const QColor&)),this
+ ,SLOT(setLedColor(const QColor&)));
+
+
+ connect(m_view,SIGNAL(signalSearchActive(bool)),this,SLOT(enableStop(bool)));
+
+ connect(m_view,SIGNAL(signalProgress(int)),_progressBar,SLOT(setProgress(int)));
+ connect(m_view,SIGNAL(signalClearProgressBar()),this,SLOT(clearProgressBar()));
+ connect(m_view,SIGNAL(signalResetProgressBar(QString,int))
+ ,this,SLOT(prepareProgressBar(QString,int)));
+
+ connect(m_view,SIGNAL(signalDictionariesChanged())
+ , this, SLOT(buildDictMenus()));
+ connect(m_view,SIGNAL(signalCursorPosChanged(int,int)), this
+ , SLOT(updateCursorPosition(int,int)));
+
+ if(!catalog->currentURL().isEmpty())
+ {
+ enableDefaults(catalog->isReadOnly());
+ setNumberOfFuzzies(catalog->numberOfFuzzies());
+ setNumberOfUntranslated(catalog->numberOfUntranslated());
+ setNumberOfTotal(catalog->numberOfEntries());
+
+ enableUndo(catalog->isUndoAvailable());
+ enableUndo(catalog->isRedoAvailable());
+
+ m_view->emitEntryState();
+
+ changeCaption(catalog->currentURL().prettyURL() );
+ }
+
+ mailer = new KBabelMailer( this, _project );
+
+ bmHandler = new KBabelBookmarkHandler((QPopupMenu*)factory()->container("bookmark", this));
+ // the earlier created KAction for "clear_bookmarks" is now reconnected
+ KAction* action = actionCollection()->action("clear_bookmarks");
+ if (action) {
+ action->disconnect(SIGNAL(activated()));
+ connect(action, SIGNAL(activated()),
+ bmHandler, SLOT(slotClearBookmarks()));
+ }
+ connect(bmHandler, SIGNAL(signalBookmarkSelected(int)),
+ this, SLOT(slotOpenBookmark(int)));
+ connect(m_view, SIGNAL(signalNewFileOpened(KURL)),
+ bmHandler, SLOT(slotClearBookmarks()));
+
+ _config = KSharedConfig::openConfig( "kbabelrc" );
+ restoreSettings();
+
+ _config->setGroup("KBabel");
+
+ if(!_config->hasKey("Version"))
+ {
+ QString encodingStr;
+ switch(catalog->saveSettings().encoding)
+ {
+ case KBabel::ProjectSettingsBase::UTF8:
+ encodingStr=QTextCodec::codecForName("UTF-8")->name();
+ break;
+ case KBabel::ProjectSettingsBase::UTF16:
+ encodingStr=QTextCodec::codecForName("UTF-16")->name();
+ break;
+ default:
+ encodingStr=QTextCodec::codecForLocale()->name();
+ }
+
+ if( KBabelSplash::instance ) KBabelSplash::instance->close(); //close splash screen window, if there is one
+
+ KMessageBox::information(0,i18n("You have not run KBabel before. "
+ "To allow KBabel to work correctly you must enter some "
+ "information in the preferences dialog first.\n"
+ "The minimum requirement is to fill out the Identity page.\n"
+ "Also check the encoding on the Save page, which is currently "
+ "set to %1. You may want to change this setting "
+ "according to the settings of your language team.").arg(encodingStr));
+
+ QTimer::singleShot(1,this,SLOT(projectConfigure()));
+ }
+
+ _config->writeEntry("Version",VERSION);
+ _config->sync();
+
+}
+
+KBabelMW::~KBabelMW()
+{
+ if(_prefDialog)
+ {
+ prefDialogs.remove(_prefDialog);
+ }
+ if(_projectDialog)
+ {
+ delete _projectDialog;
+ }
+ delete mailer;
+ delete bmHandler;
+}
+
+
+void KBabelMW::setSettings(SaveSettings saveOpts,IdentitySettings idOpts)
+{
+ m_view->updateSettings();
+ m_view->catalog()->setSettings(saveOpts);
+ m_view->catalog()->setSettings(idOpts);
+
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(KBabelSettings::ledColor());
+ }
+
+}
+
+void KBabelMW::updateSettings()
+{
+ m_view->updateSettings();
+
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(KBabelSettings::ledColor());
+ }
+
+}
+
+
+void KBabelMW::setupActions()
+{
+ KAction* action;
+
+ // the file menu
+ action = KStdAction::open(this, SLOT(fileOpen()), actionCollection());
+
+ a_recent = KStdAction::openRecent(this, SLOT(openRecent(const KURL&)), actionCollection());
+ a_recent->setMaxItems(MAX_RECENT);
+
+ action = KStdAction::revert(m_view,SLOT(revertToSaved()),actionCollection());
+ action=KStdAction::save(this, SLOT(fileSave()), actionCollection());
+ action = KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
+ action = new KAction(i18n("Save Sp&ecial..."), 0, this, SLOT(fileSaveSpecial()),
+ actionCollection(), "save_special" );
+ action = new KAction(i18n("Set &Package..."), 0, m_view, SLOT(setFilePackage()),
+ actionCollection(), "set_package" );
+
+ action = KStdAction::mail(this, SLOT(fileMail()), actionCollection());
+
+ action = new KAction(i18n("&New View"), 0, this, SLOT(fileNewView()),
+ actionCollection(), "file_new_view");
+
+ action = new KAction(i18n("New &Window"), 0, this, SLOT(fileNewWindow()),
+ actionCollection(), "file_new_window");
+ action->setShortcut( KStdAccel::openNew() );
+
+ action = KStdAction::quit(this, SLOT(quit()), actionCollection());
+
+
+
+ // the edit menu
+ action = KStdAction::undo(m_view, SLOT(undo()), actionCollection());
+ action = KStdAction::redo(m_view, SLOT(redo()), actionCollection());
+ action = KStdAction::cut(m_view, SIGNAL(signalCut()), actionCollection());
+ action = KStdAction::copy(m_view, SIGNAL(signalCopy()), actionCollection());
+ action = KStdAction::paste(m_view, SIGNAL(signalPaste()), actionCollection());
+ action = KStdAction::selectAll(m_view, SIGNAL(signalSelectAll()), actionCollection());
+ action = KStdAction::find(m_view, SLOT(find()), actionCollection());
+ action = KStdAction::findNext(m_view, SLOT(findNext()), actionCollection());
+ action = KStdAction::findPrev(m_view, SLOT(findPrev()), actionCollection());
+ action = KStdAction::replace(m_view, SLOT(replace()), actionCollection());
+
+ action = KStdAction::clear( m_view, SLOT(clear()), actionCollection(), "clear" );
+
+ action = new KAction(i18n("Cop&y Msgid to Msgstr"), "msgid2msgstr", CTRL+Key_Space, m_view
+ ,SLOT(msgid2msgstr()), actionCollection(), "msgid2msgstr");
+ action = new KAction(i18n("Copy Searc&h Result to Msgstr"), "search2msgstr",
+ CTRL+ALT+Key_Space, m_view, SLOT(search2msgstr()),
+ actionCollection(), "search2msgstr");
+ action = new KAction(i18n("Copy Msgstr to Other &Plurals"), Key_F11, m_view
+ ,SLOT(plural2msgstr()), actionCollection(), "plural2msgstr");
+ action = new KAction(i18n("Copy Selected Character to Msgstr"), Key_F10, m_charselectorview
+ ,SLOT(emitChar()), actionCollection(), "char2msgstr");
+
+ a_unsetFuzzy = new KAction(i18n("To&ggle Fuzzy Status"), "togglefuzzy", CTRL+Key_U, m_view
+ , SLOT(removeFuzzyStatus()), actionCollection(), "edit_toggle_fuzzy");
+ action = new KAction(i18n("&Edit Header..."), 0, m_view, SLOT(editHeader()),
+ actionCollection(), "edit_edit_header");
+
+ action = new KAction(i18n("&Insert Next Tag"), "insert_tag", CTRL+ALT+Key_N
+ , m_view, SLOT(insertNextTag())
+ , actionCollection(),"insert_next_tag");
+ connect(m_view,SIGNAL(signalNextTagAvailable(bool)),action
+ ,SLOT(setEnabled(bool)));
+ action = new KAction(i18n("Insert Next Tag From Msgid P&osition"), "insert_tag", CTRL+Key_M
+ , m_view, SLOT(insertNextTagMsgid())
+ , actionCollection(),"insert_next_tag_msgid");
+ connect(m_view,SIGNAL(signalNextTagAvailable(bool)),action
+ ,SLOT(setEnabled(bool)));
+ KActionMenu *actionMenu= new KActionMenu(i18n("Inser&t Tag"), "insert_tag"
+ , actionCollection(),"insert_tag");
+ m_view->setTagsMenu(actionMenu->popupMenu());
+ connect(m_view,SIGNAL(signalTagsAvailable(bool)),actionMenu
+ ,SLOT(setEnabled(bool)));
+ connect(actionMenu,SIGNAL(activated()),m_view,SLOT(insertNextTag()));
+
+ action = new KAction(i18n("Show Tags Menu"),CTRL+Key_Less
+ , m_view, SLOT(showTagsMenu()), actionCollection(),"show_tags_menu");
+ action->setEnabled(false);
+
+ connect(m_view,SIGNAL(signalTagsAvailable(bool)),action
+ ,SLOT(setEnabled(bool)));
+
+ action = new KAction(i18n("Move to Next Tag"), 0, CTRL+ALT+Key_M
+ , m_view, SLOT(skipToNextTag())
+ , actionCollection(),"move_to_next_tag");
+
+ action = new KAction(i18n("Move to Previous Tag"), 0, CTRL+ALT+Key_B
+ , m_view, SLOT(skipToPreviousTag())
+ , actionCollection(),"move_to_prev_tag");
+
+ action = new KAction(i18n("Insert Next Argument"), "insert_arg", CTRL+ALT+Key_G
+ , m_view, SLOT(insertNextArg())
+ , actionCollection(),"insert_next_arg");
+ connect(m_view,SIGNAL(signalNextArgAvailable(bool)),action
+ ,SLOT(setEnabled(bool)));
+ actionMenu= new KActionMenu(i18n("Inser&t Argument"), "insert_arg"
+ , actionCollection(),"insert_arg");
+ m_view->setArgsMenu(actionMenu->popupMenu());
+ connect(m_view,SIGNAL(signalArgsAvailable(bool)),actionMenu
+ ,SLOT(setEnabled(bool)));
+ connect(actionMenu,SIGNAL(activated()),m_view,SLOT(insertNextArg()));
+
+ action = new KAction(i18n("Show Arguments Menu"),CTRL+Key_Percent
+ , m_view, SLOT(showArgsMenu()), actionCollection(),"show_args_menu");
+ action->setEnabled(false);
+
+ connect(m_view,SIGNAL(signalArgsAvailable(bool)),action
+ ,SLOT(setEnabled(bool)));
+
+ // next, the go-menu
+ action = new KAction(i18n("&Previous"), "previous",
+ KStdAccel::shortcut(KStdAccel::Prior), m_view , SLOT(gotoPrev()),
+ actionCollection(),"go_prev_entry");
+ action = new KAction(i18n("&Next"), "next",
+ KStdAccel::shortcut(KStdAccel::Next), m_view , SLOT(gotoNext()),
+ actionCollection(),"go_next_entry");
+ action = KStdAction::goTo(m_view, SLOT(gotoEntry()), actionCollection());
+ action->setShortcut( KStdAccel::gotoLine());
+ action = KStdAction::firstPage(m_view, SLOT(gotoFirst()),actionCollection());
+ action->setText(i18n("&First Entry"));
+ action->setShortcut(CTRL+ALT+Key_Home);
+ action = KStdAction::lastPage(m_view, SLOT(gotoLast()),actionCollection());
+ action->setText(i18n("&Last Entry"));
+ action->setShortcut(CTRL+ALT+Key_End);
+ a_prevFoU = new KAction(i18n("P&revious Fuzzy or Untranslated"),"prevfuzzyuntrans",
+ CTRL+SHIFT+Key_Prior, m_view,
+ SLOT(gotoPrevFuzzyOrUntrans()),actionCollection(), "go_prev_fuzzyUntr");
+ a_nextFoU = new KAction(i18n("N&ext Fuzzy or Untranslated"),"nextfuzzyuntrans",
+ CTRL+SHIFT+Key_Next, m_view,
+ SLOT(gotoNextFuzzyOrUntrans()),actionCollection(), "go_next_fuzzyUntr");
+ a_prevFuzzy = new KAction(i18n("Pre&vious Fuzzy"),"prevfuzzy",
+ CTRL+Key_Prior, m_view,
+ SLOT(gotoPrevFuzzy()),actionCollection(), "go_prev_fuzzy");
+ a_nextFuzzy = new KAction(i18n("Ne&xt Fuzzy"), "nextfuzzy",
+ CTRL+Key_Next, m_view,
+ SLOT(gotoNextFuzzy()),actionCollection(), "go_next_fuzzy");
+ a_prevUntrans = new KAction(i18n("Prev&ious Untranslated"), "prevuntranslated",
+ ALT+Key_Prior, m_view,
+ SLOT(gotoPrevUntranslated()),actionCollection(), "go_prev_untrans");
+ a_nextUntrans = new KAction(i18n("Nex&t Untranslated"), "nextuntranslated",
+ ALT+Key_Next, m_view,
+ SLOT(gotoNextUntranslated()),actionCollection(), "go_next_untrans");
+ action = new KAction(i18n("Previo&us Error"), "preverror",
+ SHIFT+Key_Prior, m_view,
+ SLOT(gotoPrevError()),actionCollection(), "go_prev_error");
+ action = new KAction(i18n("Next Err&or"), "nexterror",
+ SHIFT+Key_Next, m_view,
+ SLOT(gotoNextError()),actionCollection(), "go_next_error");
+ action = new KAction(i18n("&Back in History"), "back", ALT+Key_Left, m_view,
+ SLOT(backHistory()),actionCollection(), "go_back_history");
+ action = new KAction(i18n("For&ward in History"), "forward", ALT+Key_Right, m_view,
+ SLOT(forwardHistory()),actionCollection(), "go_forward_history");
+
+ // the search menu
+ actionMenu=new KActionMenu(i18n("&Find Text"),
+ "transsearch",actionCollection(),"dict_search_all");
+ connect(actionMenu,SIGNAL(activated()),m_view,SLOT(startSearch()));
+ dictMenu = new DictionaryMenu(actionMenu->popupMenu(),actionCollection(),this);
+ connect(dictMenu,SIGNAL(activated(const QString)), m_view
+ , SLOT(startSearch(const QString)));
+
+ actionMenu=new KActionMenu(i18n("F&ind Selected Text"),
+ "transsearch",actionCollection(),"dict_search_selected");
+ connect(actionMenu,SIGNAL(activated()),m_view,SLOT(startSelectionSearch()));
+ selectionDictMenu = new DictionaryMenu(actionMenu->popupMenu(),actionCollection(),this);
+ connect(selectionDictMenu,SIGNAL(activated(const QString)), m_view
+ , SLOT(startSelectionSearch(const QString)));
+
+ actionMenu=new KActionMenu(i18n("&Edit Dictionary"),
+ "transsearch",actionCollection(),"dict_edit");
+ editDictMenu = new DictionaryMenu(actionMenu->popupMenu(),actionCollection(),this);
+ connect(editDictMenu,SIGNAL(activated(const QString)), m_view
+ , SLOT(editDictionary(const QString)));
+
+
+ actionMenu=new KActionMenu(i18n("Con&figure Dictionary"),
+ "transsearch",actionCollection(),"dict_configure");
+ configDictMenu = new DictionaryMenu(actionMenu->popupMenu(),actionCollection(),this);
+ connect(configDictMenu,SIGNAL(activated(const QString)), m_view
+ , SLOT(configureDictionary(const QString)));
+
+ actionMenu=new KActionMenu(i18n("About Dictionary"), "transsearch",
+ actionCollection(), "dict_about");
+ aboutDictMenu = new DictionaryMenu(actionMenu->popupMenu(),actionCollection(),this);
+ connect(aboutDictMenu,SIGNAL(activated(const QString)), m_view
+ , SLOT(aboutDictionary(const QString)));
+
+ buildDictMenus();
+
+ // the project menu
+ action = new KAction(i18n("&New..."), "filenew"
+ , this, SLOT(projectNew()),actionCollection()
+ ,"project_new");
+
+ action = new KAction(i18n("&Open..."), "fileopen"
+ , this, SLOT(projectOpen()),actionCollection()
+ ,"project_open");
+
+ action = new KAction(i18n("C&lose"), "fileclose"
+ , this, SLOT(projectClose()),actionCollection()
+ ,"project_close");
+ action->setEnabled (_project->filename() != KBabel::ProjectManager::defaultProjectName() );
+
+ action = new KAction(i18n("&Configure..."), "configure"
+ , this, SLOT(projectConfigure()),actionCollection()
+ ,"project_settings");
+
+ a_recentprojects = new KRecentFilesAction(i18n("Open &Recent"), 0, this, SLOT(projectOpenRecent(const KURL&)), actionCollection(), "recent_projects");
+
+ // the tools menu
+ action = new KAction(i18n("&Spell Check..."), "spellcheck", CTRL+Key_I
+ , m_view, SLOT(spellcheckCommon()),actionCollection()
+ ,"spellcheck_common");
+ action = new KAction(i18n("&Check All..."), "spellcheck_all", 0
+ , m_view, SLOT(spellcheckAll()),actionCollection()
+ ,"spellcheck_all");
+ action = new KAction(i18n("C&heck From Cursor Position..."), "spellcheck_from_cursor", 0
+ , m_view, SLOT(spellcheckFromCursor()),actionCollection()
+ ,"spellcheck_from_cursor");
+ action = new KAction(i18n("Ch&eck Current..."), "spellcheck_actual", 0
+ , m_view, SLOT(spellcheckCurrent()),actionCollection()
+ ,"spellcheck_current");
+ action = new KAction(i18n("Check Fro&m Current to End of File..."), 0
+ , m_view, SLOT(spellcheckFromCurrent()),actionCollection()
+ ,"spellcheck_from_current");
+ action = new KAction(i18n("Chec&k Selected Text..."), "spellcheck_selected", 0
+ , m_view, SLOT(spellcheckMarked()),actionCollection()
+ ,"spellcheck_marked");
+
+ KToggleAction *toggleAction;
+
+ toggleAction = new KToggleAction(i18n("&Diffmode"), "autodiff", 0
+ ,actionCollection(), "diff_toggleDiff");
+ connect(toggleAction,SIGNAL(toggled(bool)), m_view, SLOT(toggleAutoDiff(bool)));
+ connect(m_view,SIGNAL(signalDiffEnabled(bool)), toggleAction
+ , SLOT(setChecked(bool)));
+ toggleAction->setChecked(m_view->autoDiffEnabled());
+
+ action = new KAction(i18n("&Show Diff"), "diff", Key_F5
+ , m_view, SLOT(diff()),actionCollection()
+ ,"diff_diff");
+ action = new KAction(i18n("S&how Original Text"), "contents", Key_F6
+ , m_view, SLOT(diffShowOrig()),actionCollection()
+ ,"diff_showOrig");
+
+ action = new KAction(i18n("&Open File for Diff"), "fileopen" ,0
+ , m_view, SLOT(openDiffFile()),actionCollection()
+ ,"diff_openFile");
+
+ action = new KAction(i18n("&Rough Translation..."), 0
+ , m_view, SLOT(roughTranslation()),actionCollection()
+ ,"rough_translation");
+
+ action = new KAction(i18n("&Catalog Manager..."),"catalogmanager", 0 , this,
+ SLOT(openCatalogManager()),actionCollection(), "open_catalog_manager");
+
+ new KAction( i18n("Toggle Edit Mode"), 0, Key_Insert,this,SLOT(toggleEditMode()), actionCollection(), "toggle_insert_mode");
+
+ new KAction( i18n("&Word Count"), 0, m_view, SLOT(wordCount()), actionCollection(), "word_count");
+
+ // next, the settings menu
+ createStandardStatusBarAction();
+
+ KStdAction::configureToolbars(this,SLOT(optionsEditToolbars()),actionCollection());
+
+ KStdAction::keyBindings(guiFactory(),SLOT(configureShortcuts()),actionCollection());
+ KStdAction::preferences(this,SLOT(optionsPreferences()),actionCollection());
+
+ setStandardToolBarMenuEnabled ( true );
+
+ action = new KAction(i18n("&Stop Searching"), "stop",Key_Escape, m_view,
+ SLOT(stopSearch()),actionCollection(), "stop_search");
+ action->setEnabled(false);
+
+ new KAction(i18n("&Gettext Info"), 0, this,
+ SLOT(gettextHelp()), actionCollection(), "help_gettext");
+
+
+ // the bookmarks menu
+
+ action = KStdAction::addBookmark(this, SLOT(slotAddBookmark()),
+ actionCollection(), "add_bookmark");
+ action->setEnabled(false);
+ // this action is now connected to dummySlot(), and later reconnected
+ // to bmHandler after that object actually is created
+ new KAction(i18n("Clear Bookmarks"), 0, this, SLOT(dummySlot()),
+ actionCollection(), "clear_bookmarks");
+
+ setupDynamicActions();
+
+ createGUI(0);
+
+ QPopupMenu *popup = static_cast<QPopupMenu*>(factory()->container("settings",this));
+ popup->insertItem( i18n("&Views"), dockHideShowMenu(), -1, 0 );
+}
+
+
+void KBabelMW::setupStatusBar()
+{
+ statusBar()->insertItem(i18n("Current: 0"),ID_STATUS_CURRENT);
+ statusBar()->insertItem(i18n("Total: 0"),ID_STATUS_TOTAL);
+ statusBar()->insertItem(i18n("Fuzzy: 0"),ID_STATUS_FUZZY);
+ statusBar()->insertItem(i18n("Untranslated: 0"),ID_STATUS_UNTRANS);
+
+ if(KBabelSettings::ledInStatusbar())
+ {
+ QColor ledColor=KBabelSettings::ledColor();
+ QHBox* statusBox = new QHBox(statusBar(),"statusBox");
+ statusBox->setSpacing(2);
+ new QLabel(" "+i18n("Status: "),statusBox);
+ _fuzzyLed = new KLed(ledColor,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,statusBox);
+ _fuzzyLed->setFixedSize(15,12);
+ new QLabel(i18n("fuzzy")+" ",statusBox);
+ _untransLed = new KLed(ledColor,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,statusBox);
+ _untransLed->setFixedSize(15,12);
+ new QLabel(i18n("untranslated")+" ",statusBox);
+ _errorLed = new KLed(ledColor,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,statusBox);
+ _errorLed->setFixedSize(15,12);
+ new QLabel(i18n("faulty")+" ",statusBox);
+
+ statusBox->setFixedWidth(statusBox->sizeHint().width());
+ statusBar()->addWidget(statusBox);
+ }
+
+ statusBar()->insertItem(i18n("INS"),ID_STATUS_EDITMODE);
+
+ statusBar()->insertItem(i18n("RW"),ID_STATUS_READONLY);
+
+ statusBar()->insertItem(i18n("Line: %1 Col: %2").arg(1).arg(1)
+ ,ID_STATUS_CURSOR);
+
+ QHBox* progressBox = new QHBox(statusBar(),"progressBox");
+ progressBox->setSpacing(2);
+ _progressLabel = new KSqueezedTextLabel( "", progressBox );
+ _progressBar=new MyKProgress(progressBox,"progressbar");
+ _progressBar->hide();
+ progressBox->setStretchFactor(_progressBar,1);
+
+ statusBar()->addWidget(progressBox,1);
+ statusBar()->setMinimumHeight(progressBox->sizeHint().height());
+
+ QWhatsThis::add(statusBar(),
+ i18n("<qt><p><b>Statusbar</b></p>\n\
+<p>The statusbar displays some information about the opened file,\n\
+like the total number of entries and the number of fuzzy and untranslated\n\
+messages. Also the index and the status of the currently displayed entry is shown.</p></qt>"));
+
+}
+
+void KBabelMW::setupDynamicActions()
+{
+ // dynamic validation tools
+ QValueList<KDataToolInfo> tools = ToolAction::validationTools();
+
+ QPtrList<KAction> actions = ToolAction::dataToolActionList(
+ tools, m_view, SLOT(validateUsingTool( const KDataToolInfo &, const QString & )),
+ "validate", false, actionCollection() );
+
+ KActionMenu* m_menu = new KActionMenu(i18n("&Validation"), actionCollection(), "dynamic_validation_tools");
+
+ KAction* ac = new KAction(i18n("Perform &All Checks"), CTRL+Key_E , m_view,
+ SLOT(checkAll()),actionCollection(), "check_all");
+ ac->setEnabled(false);
+ m_menu->insert(ac);
+
+ m_menu->insert( new KActionSeparator() );
+
+ ac = new KAction(i18n("C&heck Syntax"), CTRL+Key_T , m_view,
+ SLOT(checkSyntax()),actionCollection(), "check_syntax");
+ ac->setEnabled(false);
+ m_menu->insert(ac);
+
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ // dynamic modify tools
+
+ // query available tools
+ QValueList<KDataToolInfo> allTools = KDataToolInfo::query
+ ("CatalogItem", "application/x-kbabel-catalogitem", KGlobal::instance());
+
+ // skip read-only tools for single items
+ QValueList<KDataToolInfo> modifyTools;
+
+ QValueList<KDataToolInfo>::ConstIterator entry = allTools.begin();
+ for( ; entry != allTools.end(); ++entry )
+ {
+ if( !(*entry).isReadOnly() )
+ {
+ modifyTools.append( (*entry) );
+ }
+ }
+
+ // create corresponding actions
+ actions = ToolAction::dataToolActionList(
+ modifyTools, m_view, SLOT(modifyUsingTool( const KDataToolInfo &, const QString & )),
+ "validate", true, actionCollection() );
+
+ // skip validation actions
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ // insert tools
+ m_menu = new KActionMenu(i18n("&Modify"), actionCollection(), "dynamic_modify_tools");
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ // query available tools for whole catalog
+ allTools = KDataToolInfo::query
+ ("Catalog", "application/x-kbabel-catalog", KGlobal::instance());
+
+ // skip read-only tools
+ entry = allTools.begin();
+ for( ; entry != allTools.end(); ++entry )
+ {
+ if( !(*entry).isReadOnly() )
+ {
+ modifyTools.append( (*entry) );
+ }
+ }
+
+ // create corresponding actions
+ actions = ToolAction::dataToolActionList(
+ modifyTools, m_view, SLOT(modifyUsingTool( const KDataToolInfo &, const QString & )),
+ "validate", true, actionCollection() );
+
+ // skip validation actions
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ // create corresponding actions
+ actions = ToolAction::dataToolActionList(
+ modifyTools, m_view, SLOT(modifyCatalogUsingTool( const KDataToolInfo &, const QString & )),
+ "validate", true, actionCollection() );
+
+ // insert tools
+ m_menu = new KActionMenu(i18n("&Modify"), actionCollection(), "dynamic_modify_tools");
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+}
+
+void KBabelMW::saveSettings()
+{
+ {
+ saveMainWindowSettings(_config, "View");
+ writeDockConfig (_config, "View");
+ }
+
+ {
+ a_recent->saveEntries(_config);
+ a_recentprojects->saveEntries(_config,"Project");
+ }
+
+ _config->sync();
+}
+
+void KBabelMW::restoreSettings()
+{
+ {
+ applyMainWindowSettings(_config, "View");
+ KConfigGroupSaver saver(_config,"View");
+
+ _config->setGroup("View");
+ m_view->restoreView(_config);
+
+ readDockConfig (_config, "View");
+ }
+
+ {
+ a_recent->loadEntries(_config);
+
+ a_recentprojects->loadEntries(_config, "Project");
+ }
+}
+
+
+
+void KBabelMW::saveProperties(KConfig *config)
+{
+ m_view->saveSession(config);
+}
+
+void KBabelMW::readProperties(KConfig *config)
+{
+ m_view->restoreSession(config);
+
+ // need to ensure that the windows is propertly setup also
+ // for new views-only
+ if(!m_view->currentURL().isEmpty())
+ {
+ KBCatalog* catalog=m_view->catalog();
+ enableDefaults(catalog->isReadOnly());
+ setNumberOfFuzzies(catalog->numberOfFuzzies());
+ setNumberOfUntranslated(catalog->numberOfUntranslated());
+ setNumberOfTotal(catalog->numberOfEntries());
+
+ enableUndo(catalog->isUndoAvailable());
+ enableUndo(catalog->isRedoAvailable());
+
+ m_view->emitEntryState();
+
+ changeCaption(catalog->currentURL().prettyURL() );
+ }
+}
+
+bool KBabelMW::queryClose()
+{
+ if(m_view->isSearching())
+ {
+ connect(m_view,SIGNAL(signalSearchActive(bool)),this,SLOT(quit()));
+ m_view->stopSearch();
+ return false;
+ }
+
+ if(m_view->catalog()->isActive())
+ {
+ // stop the activity and try again
+ m_view->catalog()->stop();
+ QTimer::singleShot(0, this, SLOT( close() ));
+ return false;
+ }
+
+ if(m_view->isModified())
+ {
+ switch(KMessageBox::warningYesNoCancel(this,
+ i18n("The document contains unsaved changes.\n\
+Do you want to save your changes or discard them?"),i18n("Warning"),
+ KStdGuiItem::save(),KStdGuiItem::discard()))
+ {
+ case KMessageBox::Yes:
+ {
+ return m_view->saveFile();
+ }
+ case KMessageBox::No:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool KBabelMW::queryExit()
+{
+ saveSettings();
+ _config->setGroup("View");
+ m_view->saveView(_config);
+
+ m_view->saveSettings();
+ return true;
+}
+
+void KBabelMW::quit()
+{
+ close();
+}
+
+
+void KBabelMW::dragEnterEvent(QDragEnterEvent *event)
+{
+ // accept uri drops only
+ event->accept(KURLDrag::canDecode(event));
+}
+
+void KBabelMW::dropEvent(QDropEvent *event)
+{
+ KURL::List uri;
+ // see if we can decode a URI.. if not, just ignore it
+ if (KURLDrag::decode(event, uri))
+ {
+ m_view->processUriDrop(uri,mapToGlobal(event->pos()));
+ }
+}
+
+void KBabelMW::wheelEvent(QWheelEvent *e)
+{
+ m_view->wheelEvent(e);
+}
+
+void KBabelMW::openRecent(const KURL& url)
+{
+ KBabelView *view = KBabelView::viewForURL(url,QString::null);
+ if(view)
+ {
+ KWin::activateWindow(view->topLevelWidget()->winId());
+ return;
+ }
+
+ m_view->open(url);
+}
+
+void KBabelMW::open(const KURL& url)
+{
+ open(url,QString::null,false);
+}
+
+void KBabelMW::open(const KURL& url, const QString package, bool newWindow)
+{
+ kdDebug(KBABEL) << "opening file with project:" << _project->filename() << endl;
+ kdDebug(KBABEL) << "URL:" << url.prettyURL() << endl;
+ KBabelView *view = KBabelView::viewForURL(url, _project->filename());
+ if(view)
+ {
+ kdDebug(KBABEL) << "there is a such view" << endl;
+ KWin::activateWindow(view->topLevelWidget()->winId());
+ return;
+ }
+
+ addToRecentFiles(url);
+
+ if(newWindow)
+ {
+ kdDebug(KBABEL) << "creating new window"<< endl;
+ fileNewWindow()->open(url, package,false);
+ }
+ else
+ {
+ m_view->open(url,package);
+ }
+}
+
+void KBabelMW::openTemplate(const KURL& openURL,const KURL& saveURL,const QString& package, bool newWindow)
+{
+ if(newWindow)
+ {
+ fileNewWindow()->openTemplate(openURL,saveURL,package,false);
+ }
+ else
+ {
+ m_view->openTemplate(openURL,saveURL);
+ m_view->catalog()->setPackage(package);
+ }
+}
+
+void KBabelMW::fileOpen()
+{
+ m_view->open();
+
+ KURL url=m_view->currentURL();
+ addToRecentFiles(url);
+}
+
+
+void KBabelMW::addToRecentFiles(KURL url)
+{
+ if( url.isValid() && ! url.isEmpty() )
+ a_recent->addURL(url);
+}
+
+void KBabelMW::fileSave()
+{
+ // do it asynchronously due to kdelibs bug
+ QTimer::singleShot( 0, this, SLOT( fileSave_internal() ));
+}
+
+void KBabelMW::fileSave_internal()
+{
+ // this slot is called whenever the File->Save menu is selected,
+ // the Save shortcut is pressed (usually CTRL+S) or the Save toolbar
+ // button is clicked
+
+ if(!m_view->isModified())
+ {
+ statusBar()->message(i18n("There are no changes to save."),2000);
+ }
+ else
+ {
+ // disable save
+ KAction* saveAction=(KAction*)actionCollection()->action( KStdAction::name( KStdAction::Save) );
+ saveAction->setEnabled(false);
+
+ m_view->saveFile();
+
+ KURL url=m_view->currentURL();
+
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << ((url.directory(false)+url.fileName()).utf8()) ;
+ if( !client->send( "catalogmanager-*", "CatalogManagerIFace", "updatedFile(QCString)", data ))
+ kdDebug(KBABEL) << "Unable to send file update info via DCOP" << endl;
+
+ // reenable save action
+ saveAction->setEnabled(true);
+ }
+}
+
+void KBabelMW::fileSaveAs()
+{
+ m_view->saveFileAs();
+ KURL url=m_view->currentURL();
+
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << ((url.directory(false)+url.fileName()).utf8()) ;
+ if( !client->send( "catalogmanager-*", "CatalogManagerIFace", "updatedFile(QCString)", data ))
+ kdDebug(KBABEL) << "Unable to send file update info via DCOP" << endl;
+}
+
+void KBabelMW::fileSaveSpecial()
+{
+ if( !m_view->saveFileSpecial() ) return;
+
+ KURL url=m_view->currentURL();
+
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << ((url.directory(false)+url.fileName()).utf8()) ;
+ if( !client->send( "catalogmanager-*", "CatalogManagerIFace", "updatedFile(QCString)", data ))
+ kdDebug(KBABEL) << "Unable to send file update info via DCOP" << endl;
+}
+
+void KBabelMW::fileMail()
+{
+ if( m_view->isModified() ) fileSave();
+ mailer->sendOneFile( m_view->currentURL() );
+}
+
+void KBabelMW::fileNewView()
+{
+ KBabelMW* b=new KBabelMW(m_view->catalog(),_project->filename());
+ b->updateSettings();
+ b->initBookmarks(bmHandler->bookmarks());
+ b->show();
+}
+
+KBabelMW* KBabelMW::fileNewWindow()
+{
+ KBabelMW* b=new KBabelMW(_project->filename());
+ b->setSettings(m_view->catalog()->saveSettings(),m_view->catalog()->identitySettings());
+ b->show();
+
+ return b;
+}
+
+void KBabelMW::toggleEditMode()
+{
+ bool ovr=!m_view->isOverwriteMode();
+
+ m_view->setOverwriteMode(ovr);
+
+ if(ovr)
+ statusBar()->changeItem(i18n("OVR"),ID_STATUS_EDITMODE);
+ else
+ statusBar()->changeItem(i18n("INS"),ID_STATUS_EDITMODE);
+
+}
+
+void KBabelMW::optionsShowStatusbar(bool on)
+{
+ if(on)
+ {
+ statusBar()->show();
+ }
+ else
+ {
+ statusBar()->hide();
+ }
+}
+
+void KBabelMW::optionsEditToolbars()
+{
+ saveMainWindowSettings( KGlobal::config(), "View" );
+ KEditToolbar dlg(actionCollection());
+ connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(newToolbarConfig()));
+ dlg.exec();
+}
+
+void KBabelMW::newToolbarConfig()
+{
+ createGUI(0);
+ applyMainWindowSettings( KGlobal::config(), "View" );
+}
+
+void KBabelMW::optionsPreferences()
+{
+ if(!_prefDialog)
+ {
+ _prefDialog = new KBabelPreferences(m_view->dictionaries());
+ prefDialogs.append(_prefDialog);
+
+ connect(_prefDialog,SIGNAL(settingsChanged())
+ ,m_view,SLOT(updateSettings()));
+ }
+
+ int prefHeight=_prefDialog->height();
+ int prefWidth=_prefDialog->width();
+ int width=this->width();
+ int height=this->height();
+
+ int x=width/2-prefWidth/2;
+ int y=height/2-prefHeight/2;
+
+ _prefDialog->move(mapToGlobal(QPoint(x,y)));
+
+ if(!_prefDialog->isVisible())
+ {
+ _prefDialog->show();
+ }
+
+ _prefDialog->raise();
+ KWin::activateWindow(_prefDialog->winId());
+}
+
+void KBabelMW::setLedColor(const QColor& color)
+{
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(color);
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(color);
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(color);
+ }
+}
+
+void KBabelMW::openCatalogManager()
+{
+ QCString service;
+ QString result;
+
+ DCOPClient * client = kapp->dcopClient();
+
+ // find out, if there is a running catalog manager
+ QCStringList apps = client->registeredApplications();
+ for( QCStringList::Iterator it = apps.begin() ; it != apps.end() ; ++it )
+ {
+ QString clientID = *it;
+ if( clientID.startsWith("catalogmanager") )
+ {
+ service = *it;
+ break;
+ }
+ }
+
+ // if there is no running catalog manager, start one
+ if( service.isEmpty() )
+ {
+ QString prog = "catalogmanager";
+ QString url = "";
+ if( kapp->startServiceByDesktopName(prog,url, &result,&service))
+ {
+ KMessageBox::error(this, i18n("Unable to use KLauncher to start "
+ "Catalog Manager. You should check the installation of KDE.\n"
+ "Please start Catalog Manager manually."));
+ return;
+ }
+ }
+
+ // set preferred window
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << (this->winId()) ;
+ if( !client->send( service, "CatalogManagerIFace", "setPreferredWindow( WId )", data )) kdDebug(KBABEL) << "Unable to set preferred window via DCOP" << endl;
+}
+
+
+
+void KBabelMW::firstEntryDisplayed(bool firstEntry, bool firstForm)
+{
+ KAction* firstAction=(KAction*)actionCollection()->action(KStdAction::stdName(KStdAction::FirstPage));
+ KAction* prevAction=(KAction*)actionCollection()->action("go_prev_entry");
+
+ firstAction->setEnabled(!firstEntry);
+ prevAction->setEnabled(!(firstEntry && firstForm));
+
+}
+
+void KBabelMW::lastEntryDisplayed(bool lastEntry, bool lastForm)
+{
+ KAction* lastAction=(KAction*)actionCollection()->action(KStdAction::stdName(KStdAction::LastPage));
+ KAction* nextAction=(KAction*)actionCollection()->action("go_next_entry");
+
+ lastAction->setEnabled(!lastEntry);
+ nextAction->setEnabled(!(lastEntry && lastForm));
+}
+
+void KBabelMW::fuzzyDisplayed(bool flag)
+{
+ if(!_fuzzyLed)
+ return;
+
+ if(flag)
+ {
+ if(_fuzzyLed->state()==KLed::Off)
+ {
+ _fuzzyLed->on();
+ }
+ }
+ else
+ {
+ if(_fuzzyLed->state()==KLed::On)
+ _fuzzyLed->off();
+ }
+}
+
+void KBabelMW::untranslatedDisplayed(bool flag)
+{
+ if(!_untransLed)
+ return;
+
+ // do not allow fuzzy toggle for untranslated
+ KAction *action=actionCollection()->action("edit_toggle_fuzzy");
+ if(action)
+ action->setEnabled(!flag);
+
+
+ if(flag)
+ {
+ if(_untransLed->state()==KLed::Off)
+ _untransLed->on();
+ }
+ else
+ {
+ if(_untransLed->state()==KLed::On)
+ _untransLed->off();
+ }
+}
+
+
+void KBabelMW::faultyDisplayed(bool flag)
+{
+ if(!_errorLed)
+ return;
+
+ if(flag)
+ {
+ if(_errorLed->state()==KLed::Off)
+ _errorLed->on();
+ }
+ else
+ {
+ if(_errorLed->state()==KLed::On)
+ _errorLed->off();
+ }
+}
+
+
+void KBabelMW::displayedEntryChanged(const KBabel::DocPosition& pos)
+{
+ statusBar()->changeItem(i18n("Current: %1").arg(pos.item+1),ID_STATUS_CURRENT);
+ _currentIndex = pos.item;
+}
+
+void KBabelMW::setNumberOfTotal(uint number)
+{
+ statusBar()->changeItem(i18n("Total: %1").arg(number),ID_STATUS_TOTAL);
+}
+
+void KBabelMW::setNumberOfFuzzies(uint number)
+{
+ statusBar()->changeItem(i18n("Fuzzy: %1").arg(number),ID_STATUS_FUZZY);
+}
+
+void KBabelMW::setNumberOfUntranslated(uint number)
+{
+ statusBar()->changeItem(i18n("Untranslated: %1").arg(number),ID_STATUS_UNTRANS);
+}
+
+void KBabelMW::hasFuzzyAfterwards(bool flag)
+{
+ a_nextFuzzy->setEnabled(flag);
+
+ // check if there is a fuzzy or untranslated afterwards
+ if( flag || a_nextUntrans->isEnabled() )
+ {
+ a_nextFoU->setEnabled(true);
+ }
+ else
+ {
+ a_nextFoU->setEnabled(false);
+ }
+
+}
+
+void KBabelMW::hasFuzzyInFront(bool flag)
+{
+ a_prevFuzzy->setEnabled(flag);
+
+ // check if there is a fuzzy or untranslated in front
+ if( flag || a_prevUntrans->isEnabled() )
+ {
+ a_prevFoU->setEnabled(true);
+ }
+ else
+ {
+ a_prevFoU->setEnabled(false);
+ }
+}
+
+void KBabelMW::hasUntranslatedAfterwards(bool flag)
+{
+ a_nextUntrans->setEnabled(flag);
+
+ // check if there is a fuzzy or untranslated afterwards
+ if( flag || a_nextFuzzy->isEnabled() )
+ {
+ a_nextFoU->setEnabled(true);
+ }
+ else
+ {
+ a_nextFoU->setEnabled(false);
+ }
+}
+
+void KBabelMW::hasUntranslatedInFront(bool flag)
+{
+ a_prevUntrans->setEnabled(flag);
+
+ // check if there is a fuzzy or translated in front
+ if( flag || a_prevFuzzy->isEnabled() )
+ {
+ a_prevFoU->setEnabled(true);
+ }
+ else
+ {
+ a_prevFoU->setEnabled(false);
+ }
+}
+
+
+
+void KBabelMW::hasErrorAfterwards(bool flag)
+{
+ KAction* action=actionCollection()->action("go_next_error");
+ action->setEnabled(flag);
+}
+
+void KBabelMW::hasErrorInFront(bool flag)
+{
+ KAction* action=actionCollection()->action("go_prev_error");
+ action->setEnabled(flag);
+}
+
+
+void KBabelMW::enableBackHistory(bool on)
+{
+ KAction* action=actionCollection()->action("go_back_history");
+ action->setEnabled(on);
+}
+
+void KBabelMW::enableForwardHistory(bool on)
+{
+ KAction* action=actionCollection()->action("go_forward_history");
+ action->setEnabled(on);
+}
+
+
+void KBabelMW::prepareProgressBar(QString msg,int max)
+{
+ if(_statusbarTimer->isActive())
+ _statusbarTimer->stop();
+
+ _progressBar->show();
+ _progressLabel->setText(" "+msg);
+ _progressBar->setTotalSteps(max);
+ _progressBar->setProgress(0);
+
+}
+
+void KBabelMW::clearProgressBar()
+{
+ _progressBar->setProgress(0);
+ _progressBar->hide();
+ _progressLabel->setText(" ");
+}
+
+
+void KBabelMW::changeStatusbar(const QString& text)
+{
+ // display the text on the statusbar
+ _progressLabel->setText(" "+text);
+
+ if(_statusbarTimer->isActive())
+ _statusbarTimer->stop();
+
+ _statusbarTimer->start(5000,true);
+}
+
+void KBabelMW::clearStatusbarMsg()
+{
+ _progressLabel->setText("");
+}
+
+void KBabelMW::changeCaption(const QString& text)
+{
+ // display the text on the caption
+ setCaption(text + ( _project->filename () != KBabel::ProjectManager::defaultProjectName() ?
+ " (" + _project->name() + ")" : "" /* KDE 3.4: i18n("(No project)")*/ )
+ ,m_view->isModified());
+}
+
+
+void KBabelMW::showModified(bool on)
+{
+ // display the text on the caption
+ setCaption(m_view->catalog()->package(),on);
+
+ KAction *action=actionCollection()->action(
+ KStdAction::stdName(KStdAction::Save));
+ action->setEnabled(on);
+
+ action=actionCollection()->action(KStdAction::stdName(KStdAction::Revert));
+ action->setEnabled(on);
+}
+
+
+void KBabelMW::enableDefaults(bool readOnly)
+{
+ stateChanged( "readonly", readOnly ? StateNoReverse : StateReverse );
+ stateChanged( "fileopened", StateNoReverse );
+
+ if(readOnly)
+ statusBar()->changeItem(i18n("RO"),ID_STATUS_READONLY);
+ else
+ statusBar()->changeItem(i18n("RW"),ID_STATUS_READONLY);
+}
+
+void KBabelMW::enableUndo(bool on)
+{
+ KAction* action=actionCollection()->action(KStdAction::stdName(KStdAction::Undo));
+ action->setEnabled(on);
+}
+
+void KBabelMW::enableRedo(bool on)
+{
+ KAction* action=actionCollection()->action(KStdAction::stdName(KStdAction::Redo));
+ action->setEnabled(on);
+}
+
+void KBabelMW::enableStop(bool flag)
+{
+ KAction* action=(KAction*)actionCollection()->action("stop_search");
+ action->setEnabled(flag);
+}
+
+void KBabelMW::gettextHelp()
+{
+ QString error;
+ KApplication::startServiceByDesktopName("khelpcenter",
+ QString("info:/gettext"), &error);
+
+ if(!error.isEmpty())
+ {
+ KMessageBox::sorry(this,i18n("An error occurred while "
+ "trying to open the gettext info page:\n%1").arg(error));
+ }
+}
+
+void KBabelMW::buildDictMenus()
+{
+ QPtrList<ModuleInfo> dictList = m_view->dictionaries();
+ dictList.setAutoDelete(true);
+
+ dictMenu->clear();
+ selectionDictMenu->clear();
+ configDictMenu->clear();
+ editDictMenu->clear();
+ aboutDictMenu->clear();
+
+ ModuleInfo *info;
+ for(info = dictList.first(); info !=0; info = dictList.next())
+ {
+ QString accel="Ctrl+Alt+%1";
+ dictMenu->add(info->name,info->id, accel);
+
+ accel=QString("Ctrl+%1");
+ selectionDictMenu->add(info->name,info->id, accel);
+
+ configDictMenu->add(info->name,info->id);
+ aboutDictMenu->add(info->name,info->id);
+
+ if(info->editable)
+ {
+ dictMenu->add(info->name,info->id);
+ }
+ }
+}
+
+void KBabelMW::updateCursorPosition(int line, int col)
+{
+ statusBar()->changeItem(i18n("Line: %1 Col: %2").arg(line+1).arg(col+1)
+ ,ID_STATUS_CURSOR);
+}
+
+
+KBabelMW *KBabelMW::winForURL(const KURL& url, QString project)
+{
+ KBabelMW *kb=0;
+
+ KBabelView *v = KBabelView::viewForURL(url,project);
+ if(v)
+ {
+ QObject *p = v->parent();
+ while(p && !p->inherits("KBabelMW"))
+ {
+ p = p->parent();
+ }
+
+ if(p)
+ kb = static_cast<KBabelMW*>(p);
+ }
+
+ return kb;
+}
+
+KBabelMW *KBabelMW::emptyWin(QString project)
+{
+ KBabelMW *kb=0;
+
+ KBabelView *v = KBabelView::emptyView(project);
+ if(v)
+ {
+ QObject *p = v->parent();
+ while(p && !p->inherits("KBabelMW"))
+ {
+ p = p->parent();
+ }
+
+ if(p)
+ kb = static_cast<KBabelMW*>(p);
+ }
+
+ return kb;
+}
+
+void KBabelMW::spellcheckMoreFiles(QStringList filelist)
+{
+ if( filelist.isEmpty() ) return;
+ _toSpellcheck = filelist;
+ connect( m_view, SIGNAL( signalSpellcheckDone(int) ), this, SLOT( spellcheckDone(int)));
+ spellcheckDone( KS_IGNORE ); // use something else than KS_STOP
+}
+
+void KBabelMW::spellcheckDone( int result)
+{
+ if( _toSpellcheck.isEmpty() || result == KS_STOP)
+ {
+ disconnect( m_view, SIGNAL( signalSpellcheckDone(int)), this, SLOT(spellcheckDone( int)));
+ KMessageBox::information( this, i18n("MessageBox text", "Spellchecking of multiple files is finished."),
+ i18n("MessageBox caption", "Spellcheck Done"));
+ }
+ else
+ {
+ QString file = _toSpellcheck.first();
+ _toSpellcheck.pop_front();
+ if( m_view->isModified() ) fileSave();
+ open(KURL( file ), QString::null, false);
+ kdDebug(KBABEL) << "Starting another spellcheck" << endl;
+ QTimer::singleShot( 1, m_view, SLOT(spellcheckAllMulti()));
+ }
+}
+
+void KBabelMW::initBookmarks(QPtrList<KBabelBookmark> list)
+{
+ bmHandler->setBookmarks(list);
+}
+
+void KBabelMW::slotAddBookmark()
+{
+ bmHandler->addBookmark(_currentIndex+1, m_view->catalog()->msgid(_currentIndex).first());
+}
+
+void KBabelMW::slotOpenBookmark(int index)
+{
+ DocPosition pos;
+ pos.item=index-1;
+ pos.form=0;
+ m_view->gotoEntry(pos);
+}
+
+void KBabelMW::projectNew()
+{
+ KBabel::Project::Ptr p = KBabel::ProjectWizard::newProject();
+ if( p )
+ {
+ _project = p;
+ m_view->useProject(p);
+ changeProjectActions(p->filename());
+ }
+}
+
+void KBabelMW::projectOpen()
+{
+ QString oldproject = m_view->project();
+ if( oldproject == KBabel::ProjectManager::defaultProjectName() )
+ {
+ oldproject = QString();
+ }
+ const QString file = KFileDialog::getOpenFileName(oldproject, QString::null, this);
+ if (file.isEmpty())
+ {
+ return;
+ }
+
+ projectOpen (file);
+}
+
+void KBabelMW::projectOpenRecent(const KURL& url)
+{
+ projectOpen (url.path());
+ KBabel::Project::Ptr p = KBabel::ProjectManager::open(url.path());
+ if( p )
+ {
+ _project = p;
+ m_view->useProject(p);
+ changeProjectActions(url.path());
+ }
+}
+
+void KBabelMW::projectOpen(const QString& file)
+{
+ QString oldproject = m_view->project();
+ if( oldproject == KBabel::ProjectManager::defaultProjectName() )
+ {
+ oldproject = "";
+ }
+ if (file.isEmpty())
+ {
+ return;
+ }
+ KBabel::Project::Ptr p = KBabel::ProjectManager::open(file);
+ if( p )
+ {
+ _project = p;
+ m_view->useProject(p);
+ changeProjectActions(file);
+ }
+ else
+ {
+ KMessageBox::error( this, i18n("Cannot open project file\n%1").arg(file)
+ , i18n("Project File Error"));
+ _project = ProjectManager::open(KBabel::ProjectManager::defaultProjectName());
+ m_view->useProject(_project);
+ changeProjectActions(KBabel::ProjectManager::defaultProjectName());
+ }
+}
+
+void KBabelMW::projectClose()
+{
+ QString defaultProject = KBabel::ProjectManager::defaultProjectName();
+ m_view->useProject( KBabel::ProjectManager::open(defaultProject) );
+ _project = ProjectManager::open(defaultProject);
+ changeProjectActions(defaultProject);
+}
+
+void KBabelMW::changeProjectActions(const QString& project)
+{
+ bool def = (project == KBabel::ProjectManager::defaultProjectName());
+
+ KAction* saveAction=(KAction*)actionCollection()->action( "project_close" );
+ saveAction->setEnabled( ! def );
+
+ if (!def)
+ {
+ addToRecentProjects(project);
+ }
+
+ // if there is a project dialog, delete it (we have a different project now
+ if (_projectDialog)
+ {
+ delete _projectDialog;
+ _projectDialog = NULL;
+ }
+}
+
+void KBabelMW::projectConfigure()
+{
+ if(!_projectDialog)
+ {
+ _projectDialog = new ProjectDialog(_project);
+ connect (_projectDialog, SIGNAL (settingsChanged())
+ , m_view, SLOT (updateProjectSettings()));
+ }
+
+ int prefHeight=_projectDialog->height();
+ int prefWidth=_projectDialog->width();
+ int width=this->width();
+ int height=this->height();
+
+ int x=width/2-prefWidth/2;
+ int y=height/2-prefHeight/2;
+
+ _projectDialog->move(mapToGlobal(QPoint(x,y)));
+
+ if(!_projectDialog->isVisible())
+ {
+ _projectDialog->show();
+ }
+
+ _projectDialog->raise();
+ KWin::activateWindow(_projectDialog->winId());
+}
+
+void KBabelMW::addToRecentProjects(KURL url)
+{
+ if( url.isValid() && ! url.isEmpty() )
+ a_recentprojects->addURL(url);
+}
+
+
+#include "kbabel.moc"
diff --git a/kbabel/kbabel/kbabel.desktop b/kbabel/kbabel/kbabel.desktop
new file mode 100644
index 00000000..950e0dbd
--- /dev/null
+++ b/kbabel/kbabel/kbabel.desktop
@@ -0,0 +1,83 @@
+[Desktop Entry]
+Name=KBabel
+Name[af]=Kbabel
+Name[eo]=Babelo-tradukilo
+Name[hi]=के-बेबल
+Name[ko]=K바벨
+Name[ne]=केब्याबल
+Name[pa]=ਕੇਬਬੇਲ
+Name[pt_BR]=Editor de POTFiles
+Name[sv]=Kbabel
+Name[ta]=Kபாபேல்
+Exec=kbabel %i %m -caption "%c" %U
+Icon=kbabel
+Type=Application
+DocPath=kbabel/index.html
+MimeType=application/x-gettext;
+GenericName=Translation Tool
+GenericName[af]=Vertaling Program
+GenericName[ar]=أداة الترجمة
+GenericName[bg]=Инструмент за превод
+GenericName[br]=Ostilh troidigezh
+GenericName[bs]=Alat za prevođenje
+GenericName[ca]=Eina de traducció
+GenericName[cs]=Překladatelský nástroj
+GenericName[cy]=Erfyn Cyfieithu
+GenericName[da]=Oversættelsesværktøj
+GenericName[de]=Übersetzungsprogramm
+GenericName[el]=Εργαλείο μετάφρασης
+GenericName[eo]=Tradukilo por Qt-programoj
+GenericName[es]=Herramienta de traducción
+GenericName[et]=Tõlkimise rakendus
+GenericName[eu]=Itzulpen tresna
+GenericName[fa]=ابزار ترجمه
+GenericName[fi]=Käännöstyökalu
+GenericName[fo]=Umsetingaramboð
+GenericName[fr]=Outil de traduction
+GenericName[ga]=Uirlis Aistriúcháin
+GenericName[gl]=Ferramenta de tradución
+GenericName[he]=כלי תרגום
+GenericName[hi]=अनुवाद औज़ार
+GenericName[hr]=Uslužni program za prevođenje
+GenericName[hu]=Fordítássegítő eszköz
+GenericName[is]=Þýðingaforrit
+GenericName[it]=Strumento di traduzione
+GenericName[ja]=翻訳ツール
+GenericName[ka]=თარგმნის ხელსაწყო
+GenericName[kk]=Аудару құралы
+GenericName[lt]=Vertimo įrankis
+GenericName[lv]=Tulkošanas Rīks
+GenericName[ms]=Perkakasan Penterjemahan
+GenericName[mt]=Għodda tat-traduzzjoni
+GenericName[nb]=Oversettingsverktøy
+GenericName[nds]=Översettenwarktüüch
+GenericName[ne]=अनुबाद उपकरण
+GenericName[nl]=Vertaalprogramma
+GenericName[nn]=Omsetjingsverktøy
+GenericName[nso]=Sebereka sa Thlathollo
+GenericName[pa]=ਅਨੁਵਾਦ ਸੰਦ
+GenericName[pl]=Narzędzie dla tłumaczy
+GenericName[pt]=Ferramenta de Tradução
+GenericName[pt_BR]=Ferramenta de Tradução
+GenericName[ro]=Utilitar de traducere
+GenericName[ru]=Локализация приложений
+GenericName[sk]=Prekladací nástroj
+GenericName[sl]=Orodje za prevajanje
+GenericName[sr]=Алат за превођење
+GenericName[sr@Latn]=Alat za prevođenje
+GenericName[sv]=Översättningsverktyg
+GenericName[ta]=மொழிபெயர்ப்பு கருவி
+GenericName[tg]=Утилитаи маҳалликунонии гузориш
+GenericName[th]=เครื่องมือแปลภาษา
+GenericName[tr]=Çeviri Aracı
+GenericName[uk]=Засіб для перекладів
+GenericName[ven]=Zwishumiswa zwau Dologa
+GenericName[vi]=Công cụ dịch
+GenericName[xh]=Isixhobo Soguqulelo lomsebenzi kolunye ulwimi
+GenericName[zh_CN]=翻译工具
+GenericName[zh_TW]=翻譯工具
+GenericName[zu]=Ithuluzi Lokuguqulela
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Unique
+Categories=Qt;KDE;Development;Translation;
diff --git a/kbabel/kbabel/kbabel.h b/kbabel/kbabel/kbabel.h
new file mode 100644
index 00000000..4ff184c1
--- /dev/null
+++ b/kbabel/kbabel/kbabel.h
@@ -0,0 +1,325 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBABEL_H
+#define KBABEL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kapplication.h>
+#include <kdeversion.h>
+#include <kdockwidget.h>
+#include <qstringlist.h>
+#include <qptrlist.h>
+#include <kmdimainfrm.h>
+
+#include "kbabelview.h"
+#include "kbproject.h"
+
+class KAction;
+class KRecentFilesAction;
+class KLed;
+class KProgress;
+class QHBox;
+class QLabel;
+class QTimer;
+
+class KBCatalog;
+class KBabelPreferences;
+class DictionaryMenu;
+class KBabelBookmark;
+class KBabelBookmarkHandler;
+class CommentView;
+class CharacterSelectorView;
+
+namespace KBabel
+{
+ class KBabelMailer;
+ class ProjectDialog;
+}
+
+/**
+ * This class serves as the main window for KBabel. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author Matthias Kiefer <matthias.kiefer@gmx.de>
+ * @version 0.1
+ */
+class KBabelMW : public KDockMainWindow
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ KBabelMW(QString projectFile = QString());
+
+ /** use this contructor, if you just want to create a new view of an existing catalog*/
+ KBabelMW(KBCatalog* catalog, QString projectFile = QString());
+
+ /**
+ * Default Destructor
+ */
+ virtual ~KBabelMW();
+
+ QString project() const { return _project->filename(); }
+
+ void open(const KURL& url, const QString package, bool newWindow);
+ void openTemplate(const KURL& openURL,const KURL& saveURL,const QString& package, bool newWindow=false);
+ void projectOpen(const QString& filename);
+
+ void spellcheckMoreFiles( QStringList filelist);
+
+ void setSettings(KBabel::SaveSettings,KBabel::IdentitySettings);
+ void updateSettings();
+
+ /**
+ * @return A pointer to a KBabel, that has opened file URL or 0 if no
+ * KBabel was found
+ */
+ static KBabelMW *winForURL(const KURL& url, QString projectFile = QString::null);
+
+ /**
+ * @return A pointer to a KBabel, that has opened no file URL or 0 if no
+ * KBabel was found
+ */
+ static KBabelMW *emptyWin(QString projectFile = QString::null);
+
+public slots:
+ void toggleEditMode();
+
+protected:
+ /**
+ * Overridden virtuals for Qt drag 'n drop (XDND)
+ */
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+
+ /**
+ * Overrriden virtual for wheel event handling to forward to KBabelView
+ */
+ virtual void wheelEvent(QWheelEvent *e);
+
+ /**
+ * This function is called when it is time for the app to save its
+ * properties for session management purposes.
+ */
+ virtual void saveProperties(KConfig *);
+
+ /**
+ * This function is called when this app is restored. The KConfig
+ * object points to the session management config file that was saved
+ * with @ref saveProperties
+ */
+ virtual void readProperties(KConfig *);
+
+ virtual bool queryExit();
+ virtual bool queryClose();
+
+private slots:
+ void quit();
+
+ void open(const KURL& url);
+ void openRecent(const KURL& url);
+ void fileOpen();
+ void fileSave();
+ void fileSave_internal();
+ void fileSaveAs();
+ void fileSaveSpecial();
+ void fileMail();
+ void fileNewView();
+ KBabelMW* fileNewWindow();
+
+ void projectNew();
+ void projectOpen();
+ void projectClose();
+ void projectConfigure();
+ void projectOpenRecent(const KURL& url);
+
+ void addToRecentFiles(KURL url);
+ void addToRecentProjects(KURL url);
+
+ void optionsShowStatusbar(bool);
+ void optionsEditToolbars();
+ void newToolbarConfig();
+ void optionsPreferences();
+
+ /** opens the gettext info page */
+ void gettextHelp();
+
+ void firstEntryDisplayed(bool firstEntry, bool firstForm);
+ void lastEntryDisplayed(bool lastEntry, bool lastForm);
+ void fuzzyDisplayed(bool);
+ void untranslatedDisplayed(bool);
+ void faultyDisplayed(bool);
+ void displayedEntryChanged(const KBabel::DocPosition& pos);
+ void setNumberOfTotal(uint number);
+ void setNumberOfFuzzies(uint number);
+ void setNumberOfUntranslated(uint number);
+ void hasFuzzyAfterwards(bool);
+ void hasFuzzyInFront(bool);
+ void hasUntranslatedAfterwards(bool);
+ void hasUntranslatedInFront(bool);
+ void hasErrorAfterwards(bool);
+ void hasErrorInFront(bool);
+ void updateCursorPosition(int line, int col);
+
+ void enableBackHistory(bool);
+ void enableForwardHistory(bool);
+
+ void enableUndo(bool);
+ void enableRedo(bool);
+ void enableStop(bool);
+
+ void openCatalogManager();
+
+ /**
+ * prepare the window and the progressbar for showing
+ * activity. message is displayed left to the progressbar
+ * and max is the maximum number for the progressbar
+ */
+ void prepareProgressBar(QString message,int max);
+ /**
+ * resets the progressBar and enables the window
+ */
+ void clearProgressBar();
+
+ void changeStatusbar(const QString& text);
+ void clearStatusbarMsg();
+ void changeCaption(const QString& text);
+ void showModified(bool);
+
+ /**
+ * enables menu- and toolbar items that are always enabled when a cat is opened
+ */
+ void enableDefaults(bool readOnly);
+
+ void setLedColor(const QColor& color);
+
+
+ void buildDictMenus();
+
+ /**
+ * used when creating standard toggle actions, because I prefer
+ * using signal toggled(bool)
+ */
+ void dummySlot(){}
+
+ void spellcheckDone( int result);
+
+ /**
+ * Create a new bookmark for the current msgid and add it to the list.
+ */
+ void slotAddBookmark();
+ /**
+ * Open the bookmark whose entry was just clicked in the menu.
+ */
+ void slotOpenBookmark(int index);
+
+private:
+ void init(KBCatalog* catalog);
+ void setupActions();
+ void setupDynamicActions();
+ void changeProjectActions(const QString& project);
+ void setupStatusBar();
+ void saveSettings();
+ void restoreSettings();
+ /**
+ * Init a new view of the current window with this window's bookmarks.
+ *
+ * @param list the list of bookmarks.
+ */
+ void initBookmarks(QPtrList<KBabelBookmark> list);
+
+private:
+ KBabelView *m_view;
+ CharacterSelectorView * const m_charselectorview;
+ CommentView * m_commentview;
+
+ int _currentIndex;
+
+ KProgress* _progressBar;
+ QLabel* _progressLabel;
+ KLed* _fuzzyLed;
+ KLed* _untransLed;
+ KLed* _errorLed;
+
+ QTimer *_statusbarTimer;
+
+ KBabelPreferences* _prefDialog;
+
+ QStringList _toSpellcheck;
+
+ /**
+ * used for updating preferences, that are common in
+ * the whole application
+ */
+ static QPtrList<KBabelPreferences> prefDialogs;
+
+
+ // frequently used actions
+ KAction* a_unsetFuzzy;
+ KAction* a_prevFoU;
+ KAction* a_nextFoU;
+ KAction* a_prevFuzzy;
+ KAction* a_nextFuzzy;
+ KAction* a_prevUntrans;
+ KAction* a_nextUntrans;
+
+ KRecentFilesAction* a_recent;
+ KRecentFilesAction* a_recentprojects;
+
+ DictionaryMenu *dictMenu;
+ DictionaryMenu *selectionDictMenu;
+ DictionaryMenu *configDictMenu;
+ DictionaryMenu *editDictMenu;
+ DictionaryMenu *aboutDictMenu;
+
+ friend class KBabelInterface;
+
+ // project file
+ KBabel::Project::Ptr _project;
+ KSharedConfig::Ptr _config;
+ KBabel::ProjectDialog* _projectDialog;
+
+ QMap<QString,QString> _toolsShortcuts;
+
+ KBabel::KBabelMailer* mailer;
+ KBabelBookmarkHandler* bmHandler;
+};
+
+#endif // KBABEL_H
diff --git a/kbabel/kbabel/kbabel.kcfg b/kbabel/kbabel/kbabel.kcfg
new file mode 100644
index 00000000..0da6949c
--- /dev/null
+++ b/kbabel/kbabel/kbabel.kcfg
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <group name="Editor">
+ <entry name="AccelColor" type="Color">
+ <label>
+ </label>
+ <default>128,0,128</default>
+ </entry>
+ <entry name="AutoCheckColorError" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="AutoCheckTools" type="StringList">
+ <label>
+ </label>
+ <default></default>
+ </entry>
+ <entry name="AutoDiff" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="AutoUnsetFuzzy" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="BackgroundColor" type="Color">
+ <label>
+ </label>
+ <default>255,255,192</default>
+ </entry>
+ <entry name="BeepOnError" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="CformatColor" type="Color">
+ <label>
+ </label>
+ <default>0,0,255</default>
+ </entry>
+ <entry name="CleverEditing" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="DiffAddColor" type="Color">
+ <label>
+ </label>
+ <default>192,192,255</default>
+ </entry>
+ <entry name="DiffAddUnderline" type="Enum">
+ <label>
+ </label>
+ <choices>
+ <choice name="Highlighted"/>
+ <choice name="Underlined"/>
+ </choices>
+ <default>Underlined</default>
+ </entry>
+ <entry name="DiffDelColor" type="Color">
+ <label>
+ </label>
+ <default>255,128,128</default>
+ </entry>
+ <entry name="DiffDelStrikeOut" type="Enum">
+ <label>
+ </label>
+ <choices>
+ <choice name="Highlighted"/>
+ <choice name="StrokedOut"/>
+ </choices>
+ <default>StrokedOut</default>
+ </entry>
+ <entry name="EnableQuotes" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="ErrorColor" type="Color">
+ <label>
+ </label>
+ <default>255,0,0</default>
+ </entry>
+ <entry name="HighlightBackground" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="HighlightSyntax" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="LedColor" type="Color">
+ <label>
+ </label>
+ <default>255,0,0</default>
+ </entry>
+ <entry name="LedInStatusbar" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="MsgFont" type="Font">
+ <label>Font for Messages</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry name="OnFlySpellCheck" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="SpellcheckErrorColor" type="Color">
+ <label>
+ </label>
+ <default>255,128,0</default>
+ </entry>
+ <entry name="QuotedColor" type="Color">
+ <label>
+ </label>
+ <default>0,128,0</default>
+ </entry>
+ <entry name="TagColor" type="Color">
+ <label>
+ </label>
+ <default>0,0,128</default>
+ </entry>
+ <entry name="WhitespacePoints" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ </group>
+ <group name="FindDialog">
+ <entry name="Backwards" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="CaseSensitive" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="FromCursor" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="IgnoreAccelMarker" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="IgnoreContextInfo" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="InComment" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="InMsgid" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="InMsgstr" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="List" type="String">
+ <label>
+ </label>
+ <default>right as,Record here,sidereal,altitu</default>
+ </entry>
+ <entry name="RegExp" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="WholeWords" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ </group>
+ <group name="KBCharSelector">
+ <entry name="SelectedChar" type="String">
+ <label>
+ </label>
+ <default> </default>
+ </entry>
+ <entry name="TableNum" type="UInt">
+ <label>
+ </label>
+ <default>0</default>
+ </entry>
+ </group>
+ <group name="KBabel">
+ <entry name="Version" type="String">
+ <label>
+ </label>
+ <default>1.3</default>
+ </entry>
+ </group>
+ <group name="KFileDialog Settings">
+ <entry name="AutomaticPreview" key="Automatic Preview" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="PreviewSize" key="Preview Size" type="UInt">
+ <label>
+ </label>
+ <default>60</default>
+ </entry>
+ <entry name="RecentFiles" key="Recent Files" type="String">
+ <label>
+ </label>
+ <default></default>
+ </entry>
+ <entry name="ShowPreviews" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="ViewMode" type="String">
+ <label>
+ </label>
+ <default>SmallColumns</default>
+ </entry>
+ </group>
+ <group name="KFileDialog Speedbar">
+ <entry name="SpeedbarIconSize" key="Speedbar IconSize" type="UInt">
+ <label>
+ </label>
+ <default>32</default>
+ </entry>
+ </group>
+ <group name="Search">
+ <entry name="AutoSearch" type="Bool">
+ <label>
+ </label>
+ <default>false</default>
+ </entry>
+ <entry name="DefaultModule" type="String">
+ <label>
+ </label>
+ <default>pocompendium</default>
+ </entry>
+ </group>
+ <group name="View">
+ <entry name="Comments" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="EditSplitter" type="IntList">
+ <label>
+ </label>
+ <default>242,257</default>
+ </entry>
+ <entry name="Height768" key="Height 768" type="UInt">
+ <label>
+ </label>
+ <default>624</default>
+ </entry>
+ <entry name="MainSplitter" type="IntList">
+ <label>
+ </label>
+ <default>427,307</default>
+ </entry>
+ <entry name="Toolbox" type="UInt">
+ <label>
+ </label>
+ <default>0</default>
+ </entry>
+ <entry name="ToolboxSplitter" type="IntList">
+ <label>
+ </label>
+ <default>122,377</default>
+ </entry>
+ <entry name="Tools" type="Bool">
+ <label>
+ </label>
+ <default>true</default>
+ </entry>
+ <entry name="Width1024" key="Width 1024" type="UInt">
+ <label>
+ </label>
+ <default>739</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kbabel/kbabel/kbabeliface.h b/kbabel/kbabel/kbabeliface.h
new file mode 100644
index 00000000..d03b927d
--- /dev/null
+++ b/kbabel/kbabel/kbabeliface.h
@@ -0,0 +1,81 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2001-2002 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBABELIFACE_H
+#define KBABELIFACE_H
+
+#include <dcopobject.h>
+#include <qstringlist.h>
+
+class KBabelIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+
+k_dcop:
+ virtual void openURL(QCString url, QCString package, WId window, int newWindow) { url = ""; window = 0; newWindow = 0; package= "";}
+ virtual void openURL(QCString url, QCString package, WId window, int newWindow, QCString projectFile)
+ { url = ""; window = 0; newWindow = 0; projectFile=""; package= "";}
+ virtual void openTemplate(QCString openFilename, QCString package, QCString saveFilename, int newWindow) { openFilename = ""; saveFilename = ""; newWindow = 0; package= "";}
+ virtual void openTemplate(QCString openFilename, QCString package, QCString saveFilename, int newWindow, QCString projectFile)
+ { openFilename = ""; saveFilename = ""; newWindow = 0; projectFile=""; package= "";}
+ /**
+ * open file url, if not already opened and goto entry
+ * that is equal msgid
+ */
+ virtual void gotoFileEntry(QCString url, QCString msgid)=0;
+ virtual void gotoFileEntry(QCString url, QCString package, int msgid)=0;
+ virtual void gotoFileEntry(QCString url, QCString package, int msgid, QCString projectFile)=0;
+
+
+ virtual bool findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave)=0;
+ virtual bool replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment, int ignoreAccelMarker,
+ int ignoreContextInfo, int ask, int askForNextFile, int askForSave)=0;
+ virtual bool findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave, QCString project )=0;
+ virtual bool replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment, int ignoreAccelMarker,
+ int ignoreContextInfo, int ask, int askForNextFile, int askForSave, QCString project )=0;
+ virtual void spellcheck(QStringList fileList)=0;
+};
+
+#endif // KBABELIFACE_H
diff --git a/kbabel/kbabel/kbabelpref.cpp b/kbabel/kbabel/kbabelpref.cpp
new file mode 100644
index 00000000..2907f060
--- /dev/null
+++ b/kbabel/kbabel/kbabelpref.cpp
@@ -0,0 +1,198 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2004-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#include "kbabelpref.h"
+#include "kbabeldictbox.h"
+#include "kbabelsettings.h"
+#include "fontpreferences.h"
+#include "editordiffpreferences.h"
+#include "editorpreferences.h"
+#include "searchpreferences.h"
+#include "colorpreferences.h"
+#include "toolaction.h"
+#include "toolselectionwidget.h"
+#include "qcombobox.h"
+
+#include <klocale.h>
+#include <kapplication.h>
+
+using namespace KBabel;
+
+KBabelPreferences::KBabelPreferences(QPtrList<ModuleInfo> ml)
+ : KConfigDialog(0, "Preferences", KBabelSettings::self())
+{
+ _editorPage = new EditorPreferences(0, "editor");
+ addPage( _editorPage
+ , i18n("title of page in preferences dialog","Edit")
+ , "edit"
+ , i18n("Options for Editing"));
+
+ // this contains a custom widget for tool selection, set it up
+ QValueList<KDataToolInfo> tools = ToolAction::validationTools();
+ _editorPage->_kcfg_AutoCheckTools->loadTools( "validate", tools );
+ connect( _editorPage->_kcfg_AutoCheckTools, SIGNAL( added( QListBoxItem * ) ),
+ this, SLOT (updateButtons()));
+ connect( _editorPage->_kcfg_AutoCheckTools, SIGNAL( removed( QListBoxItem * ) ),
+ this, SLOT (updateButtons()));
+
+ addPage(_searchPage = new SearchPreferences(0, "search")
+ , i18n("title of page in preferences dialog","Search")
+ , "transsearch"
+ , i18n("Options for Searching Similar Translations"));
+
+ // setup the dictionary combobox contents
+ ModuleInfo *info;
+ for(info = ml.first(); info != 0; info = ml.next())
+ {
+ _searchPage->_kcfg_DefaultModule->insertItem(info->name);
+ }
+ moduleList = ml;
+ connect( _searchPage->_kcfg_DefaultModule, SIGNAL( activated(int) ),
+ this, SLOT (updateButtons()));
+
+ addPage(new EditorDiffPreferences(0, "diff")
+ ,i18n("title of page in preferences dialog","Diff")
+ , "diff"
+ , i18n("Options for Showing Differences"));
+
+ addPage(new FontPreferences(0, "fonts")
+ , i18n("name of page in preferences dialog icon list","Fonts")
+ , "font"
+ , i18n("title of page in preferences dialog","Font Settings"));
+
+ addPage(new ColorPreferences(0, "colors")
+ , i18n("name of page in preferences dialog icon list","Colors")
+ , "colorize"
+ , i18n("title of page in preferences dialog","Color Settings"));
+
+ adjustSize();
+}
+
+
+void KBabelPreferences::slotHelp()
+{
+ //TODO
+ kapp->invokeHelp("Preferences","");
+}
+
+bool KBabelPreferences::hasChanged()
+{
+ ModuleInfo *info = moduleList.at(_searchPage->_kcfg_DefaultModule->currentItem());
+
+ bool module_ret = true;
+ if( info )
+ {
+ module_ret = info->id != KBabelSettings::defaultModule();
+ }
+
+ return KConfigDialog::hasChanged()
+ || (_editorPage->_kcfg_AutoCheckTools->selectedTools() != KBabelSettings::autoCheckTools())
+ || (module_ret);
+}
+
+bool KBabelPreferences::isDefault()
+{
+ bool old_useDefault = KBabelSettings::self()->useDefaults(true);
+
+ ModuleInfo *info = moduleList.at(_searchPage->_kcfg_DefaultModule->currentItem());
+ bool module_ret = ( info && info->id == KBabelSettings::defaultModule() );
+
+ bool ret = KConfigDialog::isDefault()
+ && (_editorPage->_kcfg_AutoCheckTools->selectedTools().empty())
+ && (module_ret);
+
+ KBabelSettings::self()->useDefaults(old_useDefault);
+ return ret;
+}
+
+void KBabelPreferences::updateSettings()
+{
+ KConfigDialog::updateSettings();
+
+ KBabelSettings::setAutoCheckTools(_editorPage->_kcfg_AutoCheckTools->selectedTools());
+
+ int i=_searchPage->_kcfg_DefaultModule->currentItem();
+ ModuleInfo *info = moduleList.at(i);
+
+ if(info)
+ {
+ KBabelSettings::setDefaultModule(info->id);
+ }
+
+ emit settingsChanged();
+}
+
+void KBabelPreferences::updateWidgets()
+{
+ KConfigDialog::updateWidgets();
+ _editorPage->_kcfg_AutoCheckTools->setSelectedTools(KBabelSettings::autoCheckTools());
+
+ int i=0;
+ ModuleInfo *info;
+ for(info = moduleList.first(); info != 0; info = moduleList.next())
+ {
+ if(KBabelSettings::defaultModule() == info->id)
+ break;
+
+ i++;
+ }
+ _searchPage->_kcfg_DefaultModule->setCurrentItem(i);
+}
+
+void KBabelPreferences::updateWidgetsDefault()
+{
+ KConfigDialog::updateWidgetsDefault();
+
+ bool old_useDefault = KBabelSettings::self()->useDefaults(true);
+
+ kdDebug () << "Default tools: " << KBabelSettings::autoCheckTools() << endl;
+
+ _editorPage->_kcfg_AutoCheckTools->setSelectedTools(KBabelSettings::autoCheckTools());
+
+ int i=0;
+ ModuleInfo *info;
+ for(info = moduleList.first(); info != 0; info = moduleList.next())
+ {
+ if(KBabelSettings::defaultModule() == info->id)
+ break;
+
+ i++;
+ }
+
+ _searchPage->_kcfg_DefaultModule->setCurrentItem(i);
+
+ KBabelSettings::self()->useDefaults(old_useDefault);
+}
+
+#include "kbabelpref.moc"
diff --git a/kbabel/kbabel/kbabelpref.h b/kbabel/kbabel/kbabelpref.h
new file mode 100644
index 00000000..a275e11e
--- /dev/null
+++ b/kbabel/kbabel/kbabelpref.h
@@ -0,0 +1,69 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBABELPREF_H
+#define KBABELPREF_H
+
+#include <kconfigdialog.h>
+#include <qptrlist.h>
+
+class SearchPreferences;
+class EditorPreferences;
+struct ModuleInfo;
+
+class KBabelPreferences : public KConfigDialog
+{
+ Q_OBJECT
+public:
+ KBabelPreferences(QPtrList<ModuleInfo>);
+
+protected slots:
+ virtual void slotHelp();
+ virtual void updateSettings();
+ virtual void updateWidgets();
+ virtual void updateWidgetsDefault();
+
+protected:
+ virtual bool hasChanged(); // reimplemented from KConfigDialog for our ToolSelectionWidget
+ virtual bool isDefault(); // reimplemented from KConfigDialog for our ToolSelectionWidget
+
+private:
+ SearchPreferences* _searchPage;
+ EditorPreferences* _editorPage;
+
+ QPtrList<ModuleInfo> moduleList;
+};
+
+
+#endif // KBABELPREF_H
diff --git a/kbabel/kbabel/kbabelsettings.kcfgc b/kbabel/kbabel/kbabelsettings.kcfgc
new file mode 100644
index 00000000..93c75552
--- /dev/null
+++ b/kbabel/kbabel/kbabelsettings.kcfgc
@@ -0,0 +1,5 @@
+File=kbabel.kcfg
+ClassName=KBabelSettings
+Singleton=true
+Mutators=true
+
diff --git a/kbabel/kbabel/kbabelsplash.cpp b/kbabel/kbabel/kbabelsplash.cpp
new file mode 100644
index 00000000..a13d8cd7
--- /dev/null
+++ b/kbabel/kbabel/kbabelsplash.cpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ * 2003 Stanislav Visnovsky <visnovsky@kde.org>
+ *
+ * This file is part of the KBabel project. It's taken from the K3b project,
+ * Copyright (C) 1998-2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+ */
+
+#include "kbabelsplash.h"
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qevent.h>
+#include <qstring.h>
+#include <qfontmetrics.h>
+#include <qpainter.h>
+
+#include <kstandarddirs.h>
+
+KBabelSplash* KBabelSplash::instance = 0;
+
+KBabelSplash::KBabelSplash( QWidget* parent, const char* name )
+ : QVBox( parent, name, WType_Dialog|WShowModal|WStyle_Customize|WStyle_NoBorder|WDestructiveClose )
+{
+ setMargin( 0 );
+ setSpacing( 0 );
+
+ QLabel* picLabel = new QLabel( this );
+ QPixmap pixmap;
+ if( pixmap.load( locate( "data", "kbabel/pics/splash.png" ) ) )
+ picLabel->setPixmap( pixmap );
+
+ picLabel->setFrameStyle(QFrame::WinPanel | QFrame::Raised);
+
+ // Set geometry, with support for Xinerama systems
+ QRect r;
+ r.setSize(sizeHint());
+ int ps = QApplication::desktop()->primaryScreen();
+ r.moveCenter( QApplication::desktop()->screenGeometry(ps).center() );
+ setGeometry(r);
+
+ delete instance;
+ instance = this;
+}
+
+
+void KBabelSplash::mousePressEvent( QMouseEvent* )
+{
+ close();
+}
+
+#include "kbabelsplash.moc"
diff --git a/kbabel/kbabel/kbabelsplash.h b/kbabel/kbabel/kbabelsplash.h
new file mode 100644
index 00000000..3ae14c9a
--- /dev/null
+++ b/kbabel/kbabel/kbabelsplash.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ * 2003 Stanislav Visnovsky <visnovsky@kde.org>
+ *
+ * This file is part of the KBabel project. It's taken from the K3b project,
+ * Copyright (C) 1998-2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+ */
+
+
+#ifndef KBABELSPLASH_H
+#define KBABELSPLASH_H
+
+#include <qvbox.h>
+
+class QLabel;
+class QMouseEvent;
+class QPaintEvent;
+class QString;
+
+
+class KBabelSplash : public QVBox
+{
+Q_OBJECT
+
+ public:
+ KBabelSplash( QWidget* parent = 0, const char* name = 0 );
+ ~KBabelSplash() { instance = 0; }
+
+ static KBabelSplash* instance;
+
+ protected:
+ void mousePressEvent( QMouseEvent* );
+};
+
+#endif
diff --git a/kbabel/kbabel/kbabelui.rc b/kbabel/kbabel/kbabelui.rc
new file mode 100644
index 00000000..40b52241
--- /dev/null
+++ b/kbabel/kbabel/kbabelui.rc
@@ -0,0 +1,235 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kbabel" version="21">
+ <MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="save_special" append="save_merge"/>
+ <Action name="set_package" append="open_merge"/>
+ <Action name="file_new_view"/>
+ <Action name="file_new_window"/>
+ </Menu>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="clear"/>
+ <Action name="msgid2msgstr"/>
+ <Action name="search2msgstr"/>
+ <Action name="plural2msgstr"/>
+ <Action name="char2msgstr"/>
+ <Action name="edit_toggle_fuzzy"/>
+ <Separator/>
+ <Action name="insert_next_tag"/>
+ <Action name="insert_next_tag_msgid"/>
+ <Action name="insert_tag"/>
+ <Action name="move_to_next_tag"/>
+ <Action name="move_to_prev_tag"/>
+ <Separator/>
+ <Action name="insert_next_arg"/>
+ <Action name="insert_arg"/>
+ <Separator/>
+ <Action name="edit_edit_header"/>
+ </Menu>
+ <Menu noMerge="1" name="go_document"><text>&amp;Go</text>
+ <Action name="go_prev_entry"/>
+ <Action name="go_next_entry"/>
+ <Action name="go_goto"/>
+ <Separator/>
+ <Action name="go_first"/>
+ <Action name="go_last"/>
+ <Separator/>
+ <Action name="go_prev_fuzzyUntr"/>
+ <Action name="go_next_fuzzyUntr"/>
+ <Action name="go_prev_fuzzy"/>
+ <Action name="go_next_fuzzy"/>
+ <Action name="go_prev_untrans"/>
+ <Action name="go_next_untrans"/>
+ <Separator/>
+ <Action name="go_prev_error"/>
+ <Action name="go_next_error"/>
+ <Separator/>
+ <Action name="go_back_history"/>
+ <Action name="go_forward_history"/>
+ </Menu>
+ <Menu name="projects"><text>&amp;Project</text>
+ <Action name="project_new"/>
+ <Action name="project_open"/>
+ <Action name="project_close"/>
+ <Action name="project_settings"/>
+ <Action name="recent_projects"/>
+ </Menu>
+ <Menu name="tools"><text>&amp;Tools</text>
+ <Menu name="spellcheck" icon="spellcheck"><text>&amp;Spelling</text>
+ <Action name="spellcheck_common"/>
+ <Separator/>
+ <Action name="spellcheck_all"/>
+ <Action name="spellcheck_from_cursor"/>
+ <Action name="spellcheck_current"/>
+ <Action name="spellcheck_from_current" />
+ <Action name="spellcheck_marked"/>
+ </Menu>
+ <Action name="dynamic_validation_tools"/>
+ <Menu name="diff" icon="diff"><text>D&amp;iff</text>
+ <Action name="diff_diff"/>
+ <Action name="diff_showOrig"/>
+ <Action name="diff_openFile"/>
+ <Separator/>
+ <Action name="diff_toggleDiff"/>
+ </Menu>
+ <Action name="dynamic_modify_tools"/>
+ <Separator/>
+ <Action name="rough_translation"/>
+ <Action name="word_count"/>
+ <Separator/>
+ <Action name="open_catalog_manager"/>
+ </Menu>
+ <Menu name="dictionaries"><text>&amp;Dictionaries</text>
+ <Action name="dict_search_all"/>
+ <Action name="dict_search_selected"/>
+ <Action name="dict_edit"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="dict_configure" append="configure_merge"/>
+ </Menu>
+ <Menu name="bookmark"><text>&amp;Bookmarks</text>
+ <Action name="add_bookmark"/>
+ <Action name="clear_bookmarks"/>
+ <Separator/>
+ </Menu>
+ <Menu name="help"><text>&amp;Help</text>
+ <Action name="help_gettext"/>
+ <Action name="dict_about" append="about_merge"/>
+ </Menu>
+ </MenuBar>
+ <ToolBar name="mainToolBar"><text>Main</text>
+ <Action name="msgid2msgstr"/>
+ <Action name="search2msgstr"/>
+ <Action name="insert_tag"/>
+ <Action name="insert_arg"/>
+ <Separator/>
+ <Action name="spellcheck_common"/>
+ <Action name="diff_toggleDiff"/>
+ <Action name="dict_search_selected"/>
+ <Action name="stop_search"/>
+ <Separator/>
+ <Action name="open_catalog_manager"/>
+ </ToolBar>
+ <ToolBar name="navigationbar"><text>Navigationbar</text>
+ <Action name="go_prev_entry"/>
+ <Action name="go_next_entry"/>
+ <Separator/>
+ <Action name="go_first"/>
+ <Action name="go_last"/>
+ <Action name="go_prev_fuzzyUntr"/>
+ <Action name="go_next_fuzzyUntr"/>
+ <Action name="go_prev_fuzzy"/>
+ <Action name="go_next_fuzzy"/>
+ <Action name="go_prev_untrans"/>
+ <Action name="go_next_untrans"/>
+ <Separator/>
+ <Action name="go_prev_error"/>
+ <Action name="go_next_error"/>
+ <Separator/>
+ <Action name="go_back_history"/>
+ <Action name="go_forward_history"/>
+ </ToolBar>
+ <Menu name="rmb_edit">
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Action name="edit_select_all"/>
+ <Separator/>
+ <Action name="msgid2msgstr"/>
+ <Action name="search2msgstr"/>
+ <Action name="edit_unset_fuzzy"/>
+ <Separator/>
+ <Action name="insert_next_tag"/>
+ <Action name="insert_tag"/>
+ <Separator/>
+ <Action name="dict_search_all"/>
+ <Action name="dict_search_selected"/>
+ </Menu>
+ <Menu name="rmb_search">
+ <Action name="edit_copy"/>
+ <Action name="search2msgstr"/>
+ <Separator/>
+ <Action name="dict_search_all"/>
+ <Action name="dict_search_selected"/>
+ <Separator/>
+ <Action name="dict_edit"/>
+ <Action name="dict_configure"/>
+ <Separator/>
+ <Action name="stop_search"/>
+ </Menu>
+ <State name="readonly">
+ <Disable>
+ <Action name="file_save"/>
+ <Action name="file_revert"/>
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Action name="edit_replace"/>
+ <Action name="insert_next_tag"/>
+ <Action name="insert_next_tag_msgid"/>
+ <Action name="insert_tag"/>
+ <Action name="insert_next_arg"/>
+ <Action name="insert_arg"/>
+ <Action name="plural2msgstr"/>
+ <Action name="char2msgstr"/>
+ <Action name="clear"/>
+ <Action name="msgid2msgstr"/>
+ <Action name="search2msgstr"/>
+ <Action name="edit_edit_header"/>
+ <Action name="edit_toggle_fuzzy"/>
+ <Action name="spellcheck_common"/>
+ <Action name="spellcheck_all"/>
+ <Action name="spellcheck_from_cursor"/>
+ <Action name="spellcheck_current"/>
+ <Action name="spellcheck_from_current" />
+ <Action name="spellcheck_marked"/>
+ <Action name="rough_translation"/>
+ </Disable>
+ </State>
+ <State name="fileopened">
+ <Enable>
+ <Action name="file_save_as"/>
+ <Action name="save_special"/>
+ <Action name="set_package"/>
+ <Action name="file_mail"/>
+ <Action name="edit_find"/>
+ <Action name="edit_find_next"/>
+ <Action name="edit_find_last"/>
+ <Action name="edit_select_all"/>
+ <Action name="move_to_next_tag"/>
+ <Action name="move_to_prev_tag"/>
+ <Action name="go_goto"/>
+ <Action name="go_prev_entry"/>
+ <Action name="go_next_entry"/>
+ <Action name="go_first"/>
+ <Action name="go_last"/>
+ <Action name="go_prev_fuzzyUntr"/>
+ <Action name="go_next_fuzzyUntr"/>
+ <Action name="go_prev_fuzzy"/>
+ <Action name="go_next_fuzzy"/>
+ <Action name="go_prev_untrans"/>
+ <Action name="go_next_untrans"/>
+ <Action name="go_prev_error"/>
+ <Action name="go_next_error"/>
+ <Action name="go_back_history"/>
+ <Action name="go_forward_history"/>
+ <Action name="dict_search_selected"/>
+ <Action name="dict_search_all"/>
+ <Action name="diff_toggleDiff"/>
+ <Action name="diff_diff"/>
+ <Action name="diff_showOrig"/>
+ <Action name="diff_openFile"/>
+ <Action name="check_syntax"/>
+ <Action name="check_all"/>
+ <Action name="dynamic_validation_tools"/>
+ <Action name="dynamic_modify_tools"/>
+ <Action name="add_bookmark"/>
+ <Action name="word_found"/>
+ </Enable>
+ </State>
+</kpartgui>
diff --git a/kbabel/kbabel/kbabelview.cpp b/kbabel/kbabel/kbabelview.cpp
new file mode 100644
index 00000000..2e9ebfa3
--- /dev/null
+++ b/kbabel/kbabel/kbabelview.cpp
@@ -0,0 +1,4473 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+ 2002-2005 by Stanislav Visnovsky <visnovsky@kde.org>
+ Copyright (C) 2006 by Nicolas GOUTTE <goutte@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "kbabelview.h"
+
+#include "catalogfileplugin.h"
+#include "toolaction.h"
+#include "kbabelsettings.h"
+#include "kbprojectsettings.h"
+
+#include <qlayout.h>
+
+#include <qlabel.h>
+#include <qframe.h>
+#include <qfileinfo.h>
+#include <qvariant.h>
+#include <qwhatsthis.h>
+#include <qdragobject.h>
+#include <qpopupmenu.h>
+#include <qstylesheet.h>
+#include <qtabwidget.h>
+#include <qtextview.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qvbox.h>
+
+#include <dcopclient.h>
+#include <kdeversion.h>
+#include <kcharsets.h>
+#include <kcmenumngr.h>
+#include <kconfigdialog.h>
+#include <kdatatool.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kcursor.h>
+#include <kfiledialog.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kled.h>
+#include <klistbox.h>
+#include <kio/netaccess.h>
+#include <knotifyclient.h>
+#include <ktempfile.h>
+#include <kspell.h>
+#include <kwin.h>
+#include <kstdaccel.h>
+#include <kurldrag.h>
+#include <kglobalsettings.h>
+
+#include "resources.h"
+
+#include "editcmd.h"
+#include "finddialog.h"
+#include "gotodialog.h"
+#include "headereditor.h"
+#include "hidingmsgedit.h"
+#include "kbabeldictbox.h"
+#include "kbcatalog.h"
+#include "msgfmt.h"
+#include "spelldlg.h"
+#include "regexpextractor.h"
+#include "projectprefwidgets.h"
+#include "kbabel.h"
+#include "kbprojectmanager.h"
+
+#include "commentview.h"
+#include "contextview.h"
+#include "kbcataloglistview.h"
+#include "charselectview.h"
+#include "taglistview.h"
+#include "sourceview.h"
+#include "errorlistview.h"
+
+#include "version.h"
+
+
+#define ID_DROP_OPEN 1
+#define ID_DROP_OPEN_TEMPLATE 2
+
+#define MAX_HISTORY 50
+
+using namespace KBabel;
+
+QPtrList<KBabelView> *KBabelView::viewList = 0;
+
+KBabelView::KBabelView(KBCatalog* catalog,KBabelMW *parent, Project::Ptr project)
+ : QWidget(parent)
+ , _redirectedBackSearch (false)
+ , _project (project)
+ , m_mainwindow (parent)
+ , m_sourceview (0)
+{
+ if(!viewList)
+ viewList = new QPtrList<KBabelView>;
+
+ viewList->append(this);
+
+ if (catalog == 0)
+ kdFatal(KBABEL) << "catalog==0" << endl;
+
+ _catalog=catalog;
+ _catalog->registerView(this);
+
+ _config = KSharedConfig::openConfig ("kbabelrc");
+
+ KConfigGroupSaver gs(_config,"Editor");
+ bool buildLeds=! KBabelSettings::ledInStatusbar();
+
+ _fuzzyLed=0;
+ _untransLed=0;
+ _errorLed=0;
+ _currentIndex=0;
+ _currentPos.item=1; // to ensure update
+ _currentPos.form=0;
+ _gotoDialog=0;
+ _findDialog=0;
+ _replaceDialog=0;
+ _replaceAskDialog=0;
+ _tagsMenu=0;
+ _argsMenu=0;
+ _autoSearchTempDisabled=false;
+ _diffEnabled=false;
+ _loadingDiffFile=false;
+ _diffing=false;
+ _dontBeep=false;
+
+ m_overwrite = false;
+
+ autoSaveTimer = 0;
+
+ _showTryLaterBox=true;
+ _tagExtractor = new RegExpExtractor( catalog->tagSettings().tagExpressions );
+ _argExtractor = new RegExpExtractor( catalog->tagSettings().argExpressions );
+
+ _editingDocumentation=false;
+
+ _autocheckTools.clear();
+ _autocheckTools.setAutoDelete(true);
+
+ spell.posDict.setAutoDelete(true);
+ spell.active=false;
+
+ spell2.kspell = 0;
+ spell2.config = 0;
+
+ setAcceptDrops(true);
+
+ // this widget does not contain anything, we should hide it
+ hide();
+
+ dictBox = new KBabelDictBox(this,"dictBox");
+ QWhatsThis::add(dictBox,
+ i18n("<qt><p><b>Search results</b></p>"
+ "<p>This part of the window shows the results of searching in "
+ "dictionaries.<p>"
+ "<p>In the top is displayed the number of entries found and "
+ "where the currently displayed entry is found. Use the buttons "
+ "at the bottom to navigate through the search results.</p>"
+ "<p>Search is either started automatically when switching to "
+ "another entry in the editor window or by choosing the desired "
+ "dictionary in <b>Dictionaries->Find...</b>.</p>"
+ "<p>The common options can be configured in the preferences dialog "
+ "in section <b>Search</b> and the options for the different "
+ "dictionaries can be changed with "
+ "<b>Settings->Configure Dictionary</b>.</p></qt>"));
+
+ initDockWidgets();
+
+ msgstrEdit->setReadOnly(true);
+ dictBox->setEnabled(false);
+
+ connect(this, SIGNAL(signalNewFileOpened(KURL)),
+ m_cataloglistview, SLOT(slotNewFileOpened()));
+
+ connect(msgstrEdit,SIGNAL(signalUndoCmd(KBabel::EditCommand*)),this,SLOT(forwardMsgstrEditCmd(KBabel::EditCommand*)));
+ connect(msgstrEdit,SIGNAL(textChanged()),this
+ ,SIGNAL(signalMsgstrChanged()));
+
+ connect(msgstrEdit,SIGNAL(textChanged(const QString&)),m_cataloglistview
+ ,SLOT(msgstrChanged(const QString&)));
+
+ connect(this,SIGNAL(signalMsgstrChanged()),this,SLOT(autoCheck()));
+ connect(msgstrEdit,SIGNAL(currentFormChanged(uint)), this
+ ,SLOT(msgstrPluralFormChanged(uint)));
+
+ connect(msgidLabel,SIGNAL(cursorPositionChanged(int,int))
+ , this, SIGNAL(signalCursorPosChanged(int,int)));
+ connect(msgstrEdit,SIGNAL(cursorPositionChanged(int,int))
+ , this, SIGNAL(signalCursorPosChanged(int,int)));
+
+ connect(dictBox,SIGNAL(searchStarted()),this
+ ,SLOT(forwardSearchStart()));
+ connect(dictBox, SIGNAL(progressStarts(const QString&)), this
+ ,SLOT(forwardProgressStart(const QString&)));
+ connect(dictBox,SIGNAL(progressed(int)),this
+ ,SIGNAL(signalProgress(int)));
+ connect(dictBox,SIGNAL(searchStopped()),this
+ ,SLOT(forwardSearchStop()));
+ connect(dictBox,SIGNAL(progressEnds()),this
+ ,SIGNAL(signalClearProgressBar()));
+
+ connect(dictBox,SIGNAL(modulesChanged()),this,
+ SIGNAL(signalDictionariesChanged()));
+ connect(dictBox,SIGNAL(errorInModule(const QString&)),this
+ ,SLOT(showError(const QString&)));
+
+ connect(_catalog,SIGNAL(signalSettingsChanged(KBabel::IdentitySettings)),
+ this, SLOT(setNewLanguage()));
+
+ connect(_catalog,SIGNAL(signalNumberOfFuzziesChanged(uint)),
+ this, SLOT(checkFuzzies()));
+ connect(_catalog,SIGNAL(signalNumberOfUntranslatedChanged(uint)),
+ this, SLOT(checkUntranslated()));
+
+ if(buildLeds)
+ {
+ connect(this,SIGNAL(signalFuzzyDisplayed(bool))
+ ,this,SLOT(toggleFuzzyLed(bool)));
+ connect(this,SIGNAL(signalUntranslatedDisplayed(bool))
+ ,this,SLOT(toggleUntransLed(bool)));
+ connect(this,SIGNAL(signalFaultyDisplayed(bool))
+ ,this,SLOT(toggleErrorLed(bool)));
+ }
+
+ _dropMenu = new QPopupMenu(this);
+ _dropMenu->insertItem(i18n("Menu item", "Open"),ID_DROP_OPEN);
+ _dropMenu->insertItem(i18n("Open Template"),ID_DROP_OPEN_TEMPLATE);
+
+ readSettings(_config);
+ readProject(_project);
+
+ connect (project, SIGNAL(signalSpellcheckSettingsChanged()),
+ this, SLOT(updateProjectSettings()));
+
+ if(!_catalog->currentURL().isEmpty())
+ {
+ newFileOpened(_catalog->isReadOnly());
+ }
+
+ // take over the language settings from the catalog
+ setNewLanguage();
+}
+
+KBabelView::~KBabelView()
+{
+ viewList->remove(this);
+ if(viewList->isEmpty())
+ {
+ delete viewList;
+ viewList=0;
+ }
+
+ _catalog->removeView(this);
+
+ // check if this view was the last view and delete the catalog if necessary
+ if(!_catalog->hasView())
+ {
+ delete _catalog;
+ }
+
+ delete _argExtractor;
+ delete _tagExtractor;
+
+ if( spell2.kspell )
+ {
+ spell2.kspell = 0;
+ delete spell2.config;
+ spell2.config = 0;
+ }
+}
+
+void KBabelView::initDockWidgets()
+{
+ // setup main dock widget - original text
+ QWidget *tempWidget=new QWidget(this,"msgidWidget");
+ tempWidget->setMinimumSize(350,150);
+
+ QVBoxLayout *layout=new QVBoxLayout(tempWidget);
+
+ msgidLabel = new HidingMsgEdit(2, this, 0, tempWidget,"msgidLabel");
+ msgidLabel->installEventFilter(this);
+ msgidLabel->setReadOnly(true);
+ msgidLabel->setDiffMode(true);
+ KCursor::setAutoHideCursor(msgidLabel,true);
+
+ msgidLabel->setText(i18n("KBabel Version %1\n"
+"Copyright 1999-%2 by KBabel developers.\n"
+" Matthias Kiefer <kiefer@kde.org>\n"
+" Stanislav Visnovsky <visnovsky@kde.org>\n"
+" Marco Wegner <dubbleu@web.de>\n"
+" Dwayne Bailey <dwayne@translate.org.za>\n"
+" Andrea Rizzi <rizzi@kde.org>\n\n"
+"Any comments, suggestions, etc. should be sent to the mailing list <kbabel@kde.org>.\n\n"
+"This program is licensed under the terms of the GNU GPL.\n\n"
+"Special thanks to Thomas Diehl for many hints to the GUI\n"
+"and the behavior of KBabel and to Stephan Kulow, who always\n"
+"lends me a helping hand.\n\n"
+"Many good ideas, especially for the Catalog Manager, are taken\n"
+"from KTranslator by Andrea Rizzi.").arg(VERSION).arg(2006));
+
+ QLabel *label=new QLabel(msgidLabel,i18n("O&riginal string (msgid):"),tempWidget);
+
+ QHBoxLayout* hb=new QHBoxLayout(layout);
+ hb->addSpacing(KDialog::marginHint());
+ hb->addWidget(label);
+
+ layout->addWidget(msgidLabel);
+ layout->setStretchFactor(msgidLabel,1);
+
+ QWhatsThis::add(tempWidget,
+ i18n("<qt><p><b>Original String</b></p>\n\
+<p>This part of the window shows the original message\n\
+of the currently displayed entry.</p></qt>"));
+
+ KDockWidget* mainDock;
+ mainDock = m_mainwindow->createDockWidget( "Original", QPixmap ());
+ //i18n: translators: Dock window caption
+ mainDock->setCaption(i18n("Original Text"));
+ mainDock->setGeometry(50, 50, 100, 100);
+ // forbit docking abilities of mainDock itself
+ mainDock->setEnableDocking(KDockWidget::DockFullSite);
+
+ mainDock->setWidget(tempWidget);
+ m_mainwindow->setMainDockWidget(mainDock); // master dockwidget
+ mainDock->show ();
+ m_mainwindow->setView (mainDock);
+ connect (this, SIGNAL (signalCopy ()), this, SLOT (textCopy ()));
+ connect (this, SIGNAL (signalCut ()), this, SLOT (textCut ()));
+ connect (this, SIGNAL (signalPaste ()), this, SLOT (textPaste ()));
+ connect (this, SIGNAL (signalSelectAll ()), this, SLOT (selectAll ()));
+
+ KDockWidget* comment_dock = m_mainwindow->createDockWidget( "Comment", QPixmap ());
+ //i18n: translators: Dock window caption
+ comment_dock->setCaption(i18n("Comment"));
+ comment_dock->setGeometry(50, 50, 100, 100);
+ comment_dock->setEnableDocking(KDockWidget::DockCorner);
+ m_commentview = new CommentView(_catalog, comment_dock, _project);
+ comment_dock->setWidget(m_commentview);
+ comment_dock->manualDock( mainDock, // dock target
+ KDockWidget::DockRight, // dock site
+ 20 ); // relation target/this (in percent)
+ comment_dock->show ();
+ connect (this, SIGNAL (signalCopy ()), m_commentview, SLOT (textCopy ()));
+ connect (this, SIGNAL (signalCut ()), m_commentview, SLOT (textCut ()));
+ connect (this, SIGNAL (signalPaste ()), m_commentview, SLOT (textPaste ()));
+ connect (this, SIGNAL (signalSelectAll ()), m_commentview, SLOT (textSelectAll ()));
+ m_commentview->installEventFilter( this );
+
+ // build the msgstr widget
+ tempWidget=new QWidget(this,"msgstrWidget");
+ tempWidget->setMinimumSize(350,150);
+
+ layout=new QVBoxLayout(tempWidget);
+
+ // if undefined number of plural forms, use 1
+ int pf = _catalog->defaultNumberOfPluralForms();
+ if( pf < 1 )
+ pf = 1;
+
+ msgstrEdit = new HidingMsgEdit( pf,this,spell2.kspell,tempWidget,"msgstrEdit");
+ msgstrEdit->installEventFilter(this);
+ KCursor::setAutoHideCursor(msgstrEdit,true);
+
+ label=new QLabel(msgstrEdit,i18n("Trans&lated string (msgstr):"),tempWidget);
+
+ hb=new QHBoxLayout(layout);
+ hb->setSpacing(KDialog::spacingHint());
+
+ hb->addSpacing(KDialog::marginHint());
+ hb->addWidget(label);
+ hb->addStretch(1);
+
+ if(! KBabelSettings::ledInStatusbar())
+ {
+ _fuzzyLed = new KLed(Qt::red,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,tempWidget);
+ _fuzzyLed->setFixedSize(15,12);
+ label = new QLabel(i18n("fuzzy"),tempWidget);
+ hb->addWidget(_fuzzyLed);
+ hb->addWidget(label);
+
+ hb->addSpacing(KDialog::spacingHint());
+
+ _untransLed = new KLed(Qt::red,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,tempWidget);
+ _untransLed->setFixedSize(15,12);
+ label = new QLabel(i18n("untranslated"),tempWidget);
+ hb->addWidget(_untransLed);
+ hb->addWidget(label);
+
+ hb->addSpacing(KDialog::marginHint());
+
+ _errorLed = new KLed(Qt::red,KLed::Off,KLed::Sunken,KLed::Rectangular
+ ,tempWidget);
+ _errorLed->setFixedSize(15,12);
+ label = new QLabel(i18n("faulty"),tempWidget);
+ hb->addWidget(_errorLed);
+ hb->addWidget(label);
+
+ hb->addSpacing(KDialog::marginHint());
+
+ hb->addStretch(1);
+
+ // ### TODO: perhaps it should be moreprecise where the setting can be changed
+ QString ledMsg=i18n("<qt><p><b>Status LEDs</b></p>\n"
+ "<p>These LEDs display the status of the currently displayed message.\n"
+ "You can change their color in the preferences dialog section\n"
+ "<b>Editor</b> on page <b>Appearance</b></p></qt>");
+ QWhatsThis::add(_fuzzyLed,ledMsg);
+ QWhatsThis::add(_untransLed,ledMsg);
+ QWhatsThis::add(_errorLed,ledMsg);
+ }
+
+ layout->addWidget(msgstrEdit);
+ layout->setStretchFactor(msgstrEdit,1);
+
+ QWhatsThis::add(tempWidget,
+ i18n("<qt><p><b>Translation Editor</b></p>\n\
+<p>This editor displays and lets you edit the translation of the currently displayed message.<p></qt>"));
+
+
+ KDockWidget* msgstr_dock = m_mainwindow->createDockWidget( "Msgstr", QPixmap ());
+ //i18n: translators: Dock window caption
+ msgstr_dock->setCaption(i18n("Translated String"));
+ msgstr_dock->setEnableDocking(KDockWidget::DockCorner);
+ msgstr_dock->setWidget(tempWidget);
+ msgstr_dock->manualDock( mainDock, // dock target
+ KDockWidget::DockBottom, // dock site
+ 50 ); // relation target/this (in percent)
+ msgstr_dock->show ();
+
+ KDockWidget* dock = m_mainwindow->createDockWidget( "Search", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("the search (noun)","Search"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("the search (noun)","Se&arch"));
+ dock->setGeometry(50, 50, 100, 100);
+ dock->setWidget(dictBox);
+ dock->manualDock( comment_dock, // dock target
+ KDockWidget::DockBottom, // dock site
+ 20 ); // relation target/this (in percent)
+ dock->show ();
+
+ KDockWidget* tools = dock;
+
+ dock = m_mainwindow->createDockWidget( "PO context", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("PO Context"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("PO C&ontext"));
+ dock->setGeometry(50, 50, 100, 100);
+ ContextView * m_contextview = new ContextView(_catalog, dock, _project);
+ dock->setWidget(m_contextview);
+ dock->manualDock( tools, // dock target
+ KDockWidget::DockCenter, // dock site
+ 20 ); // relation target/this (in percent)
+ dock->show ();
+
+ dock = m_mainwindow->createDockWidget( "Charselector", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("Character Table"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("C&hars"));
+ dock->setGeometry(50, 50, 100, 100);
+ m_charselectorview = new CharacterSelectorView(_catalog, dock, _project);
+ dock->setWidget(m_charselectorview);
+ dock->manualDock( tools, // dock target
+ KDockWidget::DockCenter, // dock site
+ 20 ); // relation target/this (in percent)
+ dock->show ();
+
+
+ dock = m_mainwindow->createDockWidget( "Tag List", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("Tag List"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("Tags"));
+ dock->setGeometry(50, 50, 100, 100);
+ TagListView* m_taglistview = new TagListView(_catalog, dock, _project);
+ dock->setWidget(m_taglistview);
+ dock->manualDock( tools, // dock target
+ KDockWidget::DockCenter, // dock site
+ 20 ); // relation target/this (in percent)
+ dock->show ();
+
+ dock = m_mainwindow->createDockWidget( "Source Context", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("Source Context"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("Source"));
+ dock->setGeometry(50, 50, 100, 100);
+ m_sourceview = new SourceView(_catalog, dock, _project);
+ dock->setWidget(m_sourceview);
+ dock->manualDock( tools, // dock target
+ KDockWidget::DockCenter, // dock site
+ 20 ); // relation target/this (in percent)
+ dock->show ();
+
+ KDockWidget* translist_dock = m_mainwindow->createDockWidget( "Translation List", QPixmap ());
+ translist_dock->setCaption(i18n("Translation List"));
+ translist_dock->setGeometry(50, 50, 100, 100);
+ translist_dock->setEnableDocking(KDockWidget::DockFullSite);
+ m_cataloglistview = new KBCatalogListView(_catalog, translist_dock, _project);
+ translist_dock->setWidget(m_cataloglistview);
+ translist_dock->manualDock( mainDock, KDockWidget::DockTop,100);
+ translist_dock->show ();
+
+ dock = m_mainwindow->createDockWidget( "Error List", QPixmap ());
+ //i18n: translators: Dock window caption
+ dock->setCaption(i18n("Error List"));
+ //i18n: translators: Dock tab caption
+ dock->setTabPageLabel(i18n("Errors"));
+ dock->setGeometry(50, 50, 100, 100);
+ ErrorListView* m_errorlistview = new ErrorListView(_catalog, dock, _project);
+ dock->setWidget(m_errorlistview);
+ dock->manualDock( tools, // dock target
+ KDockWidget::DockCenter, // dock site
+ 20 );
+ dock->show ();
+
+ connect(m_cataloglistview,SIGNAL(signalSelectionChanged(const KBabel::DocPosition&))
+ ,this,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalDisplayed(const KBabel::DocPosition&))
+ ,m_commentview,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalDisplayed(const KBabel::DocPosition&))
+ ,m_contextview,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalDisplayed(const KBabel::DocPosition&))
+ ,m_taglistview,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalDisplayed(const KBabel::DocPosition&))
+ ,m_sourceview,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalDisplayed(const KBabel::DocPosition&))
+ ,m_errorlistview,SLOT(gotoEntry(const KBabel::DocPosition&)));
+ connect(this,SIGNAL(signalFaultyDisplayed(bool))
+ ,m_errorlistview,SLOT(updateView()));
+ connect(m_charselectorview, SIGNAL( characterDoubleClicked(QChar) )
+ ,this, SLOT( insertChar(QChar) ));
+ connect(m_taglistview,SIGNAL(signalTagSelected(const QString&))
+ , this, SLOT(insertTagFromTool(const QString&)));
+ connect(m_taglistview,SIGNAL(signalHighlightedTagChanged(int))
+ , this, SLOT(skipToTagFromTool(int)));
+ connect(this, SIGNAL(signalNextTag(int))
+ , m_taglistview, SLOT(highlightTag(int)));
+ connect(m_commentview,SIGNAL(signalCursorPosChanged(int,int))
+ , m_mainwindow, SLOT(updateCursorPosition(int,int)));
+}
+
+KBabelView *KBabelView::viewForURL(const KURL& url, const QString project)
+{
+ if(url.isEmpty())
+ return 0;
+
+ if(!viewList)
+ return 0;
+
+ KURL u = url;
+ u.cleanPath();
+
+ QPtrListIterator<KBabelView> it(*viewList);
+ KBabelView *view=0;
+ while( it.current() && !view)
+ {
+ KURL cu = it.current()->currentURL();
+ cu.cleanPath();
+
+ if(cu == u && it.current()->project()==project)
+ {
+ view = it.current();
+ }
+
+ ++it;
+ }
+
+ return view;
+}
+
+KBabelView *KBabelView::emptyView(const QString)
+{
+ if(!viewList)
+ return 0;
+
+ QPtrListIterator<KBabelView> it(*viewList);
+ KBabelView *view=0;
+ while( it.current() && !view)
+ {
+ KURL cu = it.current()->currentURL();
+ if( cu.isEmpty() )
+ return it.current();
+ ++it;
+ }
+
+ return 0;
+}
+
+KURL KBabelView::currentURL() const
+{
+ return _catalog->currentURL();
+}
+
+bool KBabelView::isLastView() const
+{
+ return _catalog->isLastView();
+}
+
+bool KBabelView::isModified() const
+{
+ return _catalog->isModified();
+}
+
+bool KBabelView::isReadOnly() const
+{
+ return _catalog->isReadOnly();
+}
+
+bool KBabelView::isOverwriteMode() const
+{
+ return m_overwrite;
+}
+
+
+void KBabelView::setOverwriteMode(bool ovr)
+{
+ m_overwrite = ovr;
+ msgstrEdit->setOverwriteMode(ovr);
+ m_commentview->setOverwriteMode(ovr);
+}
+
+
+bool KBabelView::isSearching() const
+{
+ return dictBox->isSearching();
+}
+
+
+void KBabelView::update(EditCommand* cmd, bool undo)
+{
+ if((int)_currentIndex==cmd->index())
+ {
+ emitEntryState();
+
+ if(cmd->part()==Msgstr)
+ {
+ msgstrEdit->processCommand(cmd,undo);
+ emit signalMsgstrChanged();
+ }
+ }
+}
+
+
+
+void KBabelView::readSettings(KConfig* config)
+{
+
+ if(KBabelSettings::autoUnsetFuzzy())
+ {
+ connect(msgstrEdit,SIGNAL(textChanged())
+ ,this,SLOT(autoRemoveFuzzyStatus()));
+ }
+
+ setupAutoCheckTools();
+
+ KConfigGroupSaver saver(config,"Editor");
+
+ _diffEnabled = config->readBoolEntry("AutoDiff", false);
+ emit signalDiffEnabled(_diffEnabled);
+
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(KBabelSettings::ledColor());
+ }
+
+ msgstrEdit->setCleverEditing(KBabelSettings::cleverEditing());
+
+ msgstrEdit->setHighlightBg(KBabelSettings::highlightBackground());
+ msgidLabel->setHighlightBg(KBabelSettings::highlightBackground());
+
+ msgstrEdit->setHighlightSyntax(KBabelSettings::highlightSyntax());
+ msgidLabel->setHighlightSyntax(KBabelSettings::highlightSyntax());
+
+ msgstrEdit->setQuotes(KBabelSettings::enableQuotes());
+ msgidLabel->setQuotes(KBabelSettings::enableQuotes());
+
+ msgstrEdit->setSpacePoints(KBabelSettings::whitespacePoints());
+ msgidLabel->setSpacePoints(KBabelSettings::whitespacePoints());
+
+ msgstrEdit->setFont(KBabelSettings::msgFont());
+ msgidLabel->setFont(KBabelSettings::msgFont());
+
+ msgstrEdit->setBgColor(KBabelSettings::backgroundColor());
+ msgidLabel->setBgColor(KBabelSettings::backgroundColor());
+
+ msgstrEdit->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+ msgidLabel->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+
+ msgidLabel->setDiffDisplayMode( KBabelSettings::diffAddUnderline()
+ ,KBabelSettings::diffDelStrikeOut() );
+ msgidLabel->setDiffColors(KBabelSettings::diffAddColor(), KBabelSettings::diffDelColor() );
+}
+
+void KBabelView::updateProjectSettings()
+{
+ readProject(_project);
+}
+
+void KBabelView::readProject(Project::Ptr project)
+{
+ _spellcheckSettings = project->spellcheckSettings();
+
+ if( _spellcheckSettings.onFlySpellcheck )
+ {
+
+ // if there is a spellchecker already, free it
+ if( spell2.kspell )
+ {
+ // ensure the spellchecker is not used anymore
+ msgstrEdit->setSpellChecker(0L);
+
+ // free it
+ spell2.kspell->cleanUp();
+
+ delete spell2.kspell;
+ spell2.kspell = 0;
+ }
+
+ spell2.config = new KSpellConfig(0L, "tempSpellConfig");
+ spell2.config->setNoRootAffix(_spellcheckSettings.noRootAffix);
+ spell2.config->setRunTogether(_spellcheckSettings.runTogether);
+ spell2.config->setClient(_spellcheckSettings.spellClient);
+ spell2.config->setEncoding(_spellcheckSettings.spellEncoding);
+ spell2.config->setDictionary(_spellcheckSettings.spellDict);
+
+ spell2.kspell= new KSpell(this, "", this, SLOT(dummy(KSpell *)),
+ spell2.config, false, false);
+ if(spell2.kspell->status() == KSpell::Error)
+ kdWarning(KBABEL) << "Something's wrong with KSpell, can't start on-the-fly checking" << endl;
+ else
+ {
+ kdDebug() << "On the fly spellchecker: "
+ << spell2.kspell << endl;
+ msgstrEdit->setSpellChecker(spell2.kspell);
+ }
+
+ // spell2.kspell->setAutoDelete(true); // let KSpell handle delete
+ //on-the-fly spellcheck end
+ }
+ else
+ {
+ // turn off spellchecker
+ msgstrEdit->setSpellChecker(0);
+ // invalidate the current settings, to make sure they are updated when needed
+ _spellcheckSettings.valid = false;
+ }
+
+ dictBox->readSettings(project->config());
+
+ m_sourceview->setProject(project);
+}
+
+void KBabelView::saveSettings()
+{
+ KConfigGroupSaver saver(_config,"Editor");
+
+ _config->writeEntry("AutoDiff",_diffEnabled);
+
+ dictBox->saveSettings( _project->config() );
+
+ _catalog->savePreferences();
+
+ _config->sync();
+ _project->config()->sync();
+
+ KBabelSettings::writeConfig();
+}
+
+void KBabelView::updateSettings()
+{
+ msgstrEdit->setFont(KBabelSettings::msgFont());
+ msgidLabel->setFont(KBabelSettings::msgFont());
+
+ msgidLabel->setDiffDisplayMode( KBabelSettings::diffAddUnderline()
+ ,KBabelSettings::diffDelStrikeOut());
+ msgidLabel->setDiffColors(KBabelSettings::diffAddColor(), KBabelSettings::diffDelColor());
+
+ if( _diffEnabled && !_catalog->currentURL().isEmpty() )
+ {
+ diffShowOrig ();
+ diff();
+ }
+
+ msgstrEdit->setBgColor(KBabelSettings::backgroundColor());
+ msgidLabel->setBgColor(KBabelSettings::backgroundColor());
+
+ msgstrEdit->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+ msgidLabel->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+
+ msgidLabel->setDiffDisplayMode( KBabelSettings::diffAddUnderline()
+ ,KBabelSettings::diffDelStrikeOut());
+ msgidLabel->setDiffColors(KBabelSettings::diffAddColor(), KBabelSettings::diffDelColor());
+
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(KBabelSettings::ledColor());
+ }
+
+ disconnect(msgstrEdit,SIGNAL(textChanged())
+ ,this,SLOT(autoRemoveFuzzyStatus()));
+
+ if(KBabelSettings::autoUnsetFuzzy())
+ {
+ connect(msgstrEdit,SIGNAL(textChanged())
+ ,this,SLOT(autoRemoveFuzzyStatus()));
+ }
+
+ msgstrEdit->setCleverEditing(KBabelSettings::cleverEditing());
+
+ msgstrEdit->setHighlightBg(KBabelSettings::highlightBackground());
+ msgidLabel->setHighlightBg(KBabelSettings::highlightBackground());
+ msgstrEdit->setHighlightSyntax(KBabelSettings::highlightSyntax());
+ msgidLabel->setHighlightSyntax(KBabelSettings::highlightSyntax());
+
+ msgstrEdit->setQuotes(KBabelSettings::enableQuotes());
+ msgidLabel->setQuotes(KBabelSettings::enableQuotes());
+
+ msgstrEdit->setSpacePoints(KBabelSettings::whitespacePoints());
+ msgidLabel->setSpacePoints(KBabelSettings::whitespacePoints());
+
+ msgstrEdit->setFont(KBabelSettings::msgFont());
+ msgidLabel->setFont(KBabelSettings::msgFont());
+
+ msgstrEdit->setBgColor(KBabelSettings::backgroundColor());
+ msgidLabel->setBgColor(KBabelSettings::backgroundColor());
+
+ msgstrEdit->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+ msgidLabel->setHighlightColors(KBabelSettings::quotedColor(),KBabelSettings::errorColor()
+ ,KBabelSettings::cformatColor(),KBabelSettings::accelColor(),KBabelSettings::tagColor());
+
+ msgidLabel->setDiffDisplayMode( KBabelSettings::diffAddUnderline()
+ ,KBabelSettings::diffDelStrikeOut());
+ msgidLabel->setDiffColors(KBabelSettings::diffAddColor(), KBabelSettings::diffDelColor());
+
+ // if errors should not use special color, reset the color of the text
+ if(! KBabelSettings::autoCheckColorError())
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::NormalColor);
+ }
+
+ if(_fuzzyLed)
+ {
+ _fuzzyLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_untransLed)
+ {
+ _untransLed->setColor(KBabelSettings::ledColor());
+ }
+ if(_errorLed)
+ {
+ _errorLed->setColor(KBabelSettings::ledColor());
+ }
+
+ emit ledColorChanged(KBabelSettings::ledColor());
+
+ setupAutoCheckTools();
+
+ if( _catalog->numberOfEntries() > 0 )
+ autoCheck(false);
+
+}
+
+void KBabelView::setupAutoCheckTools()
+{
+ _autocheckTools.clear();
+
+ kdDebug () << "Autocheck tools: " << KBabelSettings::autoCheckTools().join(",") << endl;
+
+ if(!KBabelSettings::autoCheckTools().isEmpty() )
+ {
+ QValueList<KDataToolInfo> tools = ToolAction::validationTools();
+
+ QValueList<KDataToolInfo>::Iterator it;
+ for( it=tools.begin(); it!=tools.end() ; ++it )
+ {
+ if(KBabelSettings::autoCheckTools().contains((*it).service()->library()) )
+ {
+ // maybe we can reuse the tools
+ KDataTool* t = (*it).createTool();
+
+ if( t ) _autocheckTools.append( t );
+ }
+ }
+ }
+}
+
+void KBabelView::setRMBEditMenu(QPopupMenu* popup)
+{
+ msgidLabel->setContextMenu( popup );
+ msgstrEdit->setContextMenu( popup );
+ KContextMenuManager::insert(this,popup);
+}
+
+void KBabelView::setRMBSearchMenu(QPopupMenu* popup)
+{
+ dictBox->setRMBMenu(popup);
+}
+
+
+void KBabelView::saveView(KConfig *)
+{
+}
+
+void KBabelView::restoreView(KConfig *)
+{
+}
+
+void KBabelView::saveSession(KConfig* config)
+{
+ QString focus;
+ int line=0,col=0;
+ if(msgstrEdit->hasFocus())
+ {
+ focus="msgstr";
+ msgstrEdit->getCursorPosition(&line,&col);
+ }
+ else if(msgidLabel->hasFocus())
+ {
+ focus="msgid";
+ msgidLabel->getCursorPosition(&line,&col);
+ }
+ else if(dictBox->hasFocus())
+ {
+ focus="searchbox";
+ }
+
+ config->writeEntry("Focus",focus);
+ config->writeEntry("CursorLine",line);
+ config->writeEntry("CursorCol",col);
+ config->writeEntry("Index",_currentIndex);
+ config->writeEntry("PluralForm",_currentPos.form);
+
+ config->writePathEntry("URL",currentURL().url());
+
+ config->writeEntry("AutoDiff",_diffEnabled);
+
+ if( _spellcheckSettings.valid )
+ {
+ KConfigGroupSaver (config, "Spellcheck");
+ config->writeEntry("NoRootAffix",_spellcheckSettings.noRootAffix);
+ config->writeEntry("RunTogether",_spellcheckSettings.runTogether);
+ config->writeEntry("SpellEncoding",_spellcheckSettings.spellEncoding);
+ config->writeEntry("SpellClient",_spellcheckSettings.spellClient);
+ config->writeEntry("SpellDictionary",_spellcheckSettings.spellDict);
+ config->writeEntry("RememberIgnored",_spellcheckSettings.rememberIgnored);
+ config->writePathEntry("IgnoreURL",_spellcheckSettings.ignoreURL);
+ }
+
+ saveView(config);
+}
+
+void KBabelView::restoreSession(KConfig* config)
+{
+ QString url=config->readPathEntry("URL");
+
+ if(!url.isEmpty())
+ {
+ open(KURL( url ), QString::null, false,true);
+ }
+
+
+ _diffEnabled = config->readBoolEntry("AutoDiff", false);
+ emit signalDiffEnabled(_diffEnabled);
+
+ msgidLabel->setDiffDisplayMode( KBabelSettings::diffAddUnderline()
+ , KBabelSettings::diffDelStrikeOut() );
+ msgidLabel->setDiffColors( KBabelSettings::diffAddColor()
+ , KBabelSettings::diffDelColor() );
+
+ // go to last displayed entry
+ DocPosition pos;
+ pos.item=config->readNumEntry("Index");
+ pos.form=config->readNumEntry("PluralForm");
+ gotoEntry(pos);
+
+ QString focus=config->readEntry("Focus");
+ int line=config->readNumEntry("CursorLine");
+ int col=config->readNumEntry("CursorCol");
+ if(focus=="msgstr")
+ {
+ msgstrEdit->setFocus();
+ msgstrEdit->setCursorPosition(line,col);
+ }
+ else if(focus=="msgid")
+ {
+ msgidLabel->setFocus();
+ msgstrEdit->setCursorPosition(line,col);
+ }
+ else if(focus=="searchbox")
+ {
+ dictBox->setFocus();
+ }
+
+ restoreView(config);
+}
+
+void KBabelView::newFileOpened(bool readOnly)
+{
+ // disable editing for empty files
+ if(_catalog->numberOfEntries() == 0)
+ readOnly = true;
+
+ if(_gotoDialog)
+ {
+ _gotoDialog->setMax(_catalog->numberOfEntries());
+ }
+
+ dictBox->setDisabled(readOnly);
+ msgstrEdit->setReadOnly(readOnly);
+ msgstrEdit->setFocus();
+
+ QString caption=_catalog->package();
+ if(readOnly)
+ caption+=i18n(" [readonly]");
+ emit signalChangeCaption(caption);
+ emit signalNewFileOpened(_catalog->currentURL());
+
+ dictBox->setEditedPackage(_catalog->packageDir()+_catalog->packageName());
+ dictBox->setEditedFile(_catalog->currentURL().url());
+
+ _editingDocumentation = _catalog->isGeneratedFromDocbook();
+
+ _backHistory.clear();
+ emit signalBackHistory(false);
+ _forwardHistory.clear();
+ emit signalForwardHistory(false);
+
+ DocPosition pos;
+ pos.item=0;
+ pos.form=0;
+ _autoSearchTempDisabled=true;
+ gotoEntry(pos,false);
+ _autoSearchTempDisabled=false;
+
+ emit signalDisplayed(pos);
+
+ if(isActiveWindow() && KBabelSettings::autoSearch())
+ {
+ startSearch(true);
+ }
+}
+
+void KBabelView::open()
+{
+ open(KURL());
+}
+
+void KBabelView::open(const KURL& _url, const QString & package, bool checkIfModified, bool newView)
+{
+#if KDE_IS_VERSION( 3, 5, 0)
+ KURL url = KIO::NetAccess::mostLocalURL(_url,this);
+#else
+ KURL url = _url;
+#endif
+ url.cleanPath();
+
+ KURL cu = currentURL();
+ cu.cleanPath();
+ if(checkIfModified && !url.isEmpty() && cu==url)
+ {
+ KWin::activateWindow(topLevelWidget()->winId());
+ return;
+ }
+
+ stopSearch();
+
+ if(!checkIfModified || checkModified())
+ {
+ if(url.isEmpty())
+ {
+ QString filename;
+ if ((url = KFileDialog::getOpenURL(currentURL().url(), CatalogImportPlugin::availableImportMimeTypes().join(" ")
+ ,this)).isEmpty())
+ {
+ return;
+ }
+ }
+ // deactive editor
+ /*setEnabled(false);
+ setCursor(KCursor::waitCursor());*/
+
+ KBabelView *v = viewForURL(url,_project->filename());
+
+ if(v && v != this)
+ {
+ if( newView )
+ {
+ // unregister old catalog
+ _catalog->removeView(this);
+ if( !_catalog->hasView() )
+ delete _catalog;
+
+ // setup new one
+ _catalog = v->catalog();
+ _catalog->registerView(this);
+ newFileOpened(_catalog->isReadOnly());
+ return;
+ }
+ else {
+ KWin::activateWindow(v->topLevelWidget()->winId());
+ return;
+ }
+ }
+
+ ConversionStatus stat=_catalog->openURL(url, package);
+
+ switch(stat)
+ {
+ case OK:
+ {
+ break;
+ }
+ case RECOVERED_HEADER_ERROR: // Old name HEADER_ERROR
+ {
+ KMessageBox::sorry(this,
+ i18n("There was an error while reading the file header. "
+ "Please check the header." ));
+ editHeader();
+ break;
+ }
+ case PARSE_ERROR:
+ {
+ KMessageBox::error(this
+ ,i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid PO file.").arg(url.prettyURL()));
+ break;
+ }
+ case NO_ENTRY_ERROR:
+ {
+ KMessageBox::error(this
+ ,i18n("Error while reading the file:\n %1\n"
+ "No entry found.").arg(url.prettyURL()));
+ break;
+ }
+ case RECOVERED_PARSE_ERROR:
+ {
+ QString msg=i18n(
+ "The file contained syntax errors and an attempt has been "
+ "made to recover it.\n"
+ "Please check the questionable entries by using "
+ "Go->Next error");
+ KMessageBox::sorry(this,msg);
+ emitEntryState();
+ break;
+ }
+ case NO_PERMISSIONS:
+ {
+ KMessageBox::error(this,i18n(
+ "You do not have permissions to read file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ case NO_FILE:
+ {
+ KMessageBox::error(this,i18n(
+ "You have not specified a valid file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ case NO_PLUGIN:
+ {
+ KMessageBox::error(this,i18n(
+ "KBabel cannot find a corresponding plugin for the MIME type of the file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ case UNSUPPORTED_TYPE:
+ {
+ KMessageBox::error(this,i18n(
+ "The import plugin cannot handle this type of the file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ case STOPPED:
+ break;
+ default:
+ {
+ KMessageBox::error(this,i18n(
+ "Error while trying to open file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+
+ }
+ /*
+ //activate editor
+ setEnabled(true);
+ setCursor(KCursor::arrowCursor());*/
+
+ _autoSaveDelay = _catalog->saveSettings( ).autoSaveDelay;
+ if ( _autoSaveDelay ) {
+ if ( !autoSaveTimer ) {
+ autoSaveTimer = new QTimer( this, "AUTOSAVE TIMER" );
+ connect( autoSaveTimer, SIGNAL( timeout( ) ), this, SLOT( slotAutoSaveTimeout( ) ) );
+ }
+ autoSaveTimer->stop( );
+ autoSaveTimer->start( 1000 * 60 * _autoSaveDelay );
+ }
+
+ }
+}
+
+void KBabelView::revertToSaved()
+{
+ if(isModified())
+ {
+ // ### TODO: "Cancel" should be the default
+ if(KMessageBox::warningContinueCancel(this
+ ,i18n("All changes will be lost if the file "
+ "is reverted to its last saved state.")
+ ,i18n("Warning"),i18n("&Revert"))
+ == KMessageBox::Cancel)
+ {
+ return;
+ }
+ }
+
+ open(_catalog->currentURL(),QString::null,false);
+}
+
+void KBabelView::openTemplate(const KURL& openURL, const KURL& saveURL)
+{
+ stopSearch();
+
+ if(checkModified())
+ {
+ // deactive editor
+ /*setEnabled(false);
+ setCursor(KCursor::waitCursor());*/
+
+
+ ConversionStatus stat=_catalog->openURL(openURL,saveURL);
+
+ switch(stat)
+ {
+ case OK:
+ {
+ break;
+ }
+ case RECOVERED_HEADER_ERROR:
+ {
+ // For a template, recoverable errors are disqualifying
+ KMessageBox::sorry(this,
+ i18n("There was an error while reading the file header of file:\n %1")
+ .arg(openURL.prettyURL()));
+ break;
+ }
+ case PARSE_ERROR:
+ {
+ KMessageBox::error(this
+ ,i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid PO file.").arg(openURL.prettyURL()));
+ break;
+ }
+ case NO_ENTRY_ERROR:
+ {
+ KMessageBox::error(this
+ ,i18n("Error while reading the file:\n %1\n"
+ "No entry found.").arg(openURL.prettyURL()));
+ break;
+ }
+ case RECOVERED_PARSE_ERROR:
+ {
+ // For a template, recoverable errors are disqualifying
+ KMessageBox::sorry(this,
+ i18n("Minor syntax errors were found while reading file:\n %1")
+ .arg(openURL.prettyURL()));
+ break;
+ }
+ case NO_PERMISSIONS:
+ {
+ KMessageBox::error(this,i18n("You do not have permissions to read file:\n %1").arg(openURL.prettyURL()));
+ break;
+ }
+ case NO_FILE:
+ {
+ KMessageBox::error(this,i18n("You have not specified a valid file:\n %1").arg(openURL.prettyURL()));
+ break;
+ }
+ case NO_PLUGIN:
+ {
+ KMessageBox::error(this,i18n(
+ "KBabel cannot find a corresponding plugin for the MIME type of the file:\n %1").arg(openURL.prettyURL()));
+ break;
+ }
+ case UNSUPPORTED_TYPE:
+ {
+ KMessageBox::error(this,i18n(
+ "The import plugin cannot handle this type of the file:\n %1").arg(openURL.prettyURL()));
+ break;
+ }
+ case STOPPED:
+ break;
+ default:
+ {
+ KMessageBox::error(this,i18n("Error while trying to open file:\n %1").arg(openURL.prettyURL()));
+ break;
+ }
+
+ }
+
+ /*
+ //activate editor
+ setEnabled(true);
+
+ setCursor(KCursor::arrowCursor());*/
+ }
+}
+
+bool KBabelView::saveFile(bool syntaxCheck)
+{
+ if(_catalog->isReadOnly())
+ {
+ return saveFileAs();
+ }
+ else
+ {
+ ConversionStatus stat=_catalog->saveFile();
+
+ int whatToDo = -1;
+
+ switch(stat)
+ {
+ case OK:
+ {
+ informDictionary();
+ if(syntaxCheck && _catalog->saveSettings().autoSyntaxCheck )
+ return checkSyntax(true,false);
+ else
+ return true;
+ }
+ case NO_PERMISSIONS:
+ {
+ whatToDo=KMessageBox::warningContinueCancel(this,
+ i18n("You do not have permission to write to file:\n%1\n"
+ "Do you want to save to another file or cancel?").arg(_catalog->currentURL().prettyURL()),
+ i18n("Error"),KStdGuiItem::save());
+ break;
+ }
+ case NO_PLUGIN:
+ {
+ KMessageBox::error(this,i18n(
+ "KBabel cannot find a corresponding plugin for the MIME type of file:\n %1").arg(_catalog->currentURL().prettyURL()));
+ break;
+ }
+ case UNSUPPORTED_TYPE:
+ {
+ KMessageBox::error(this,i18n(
+ "The export plugin cannot handle this type of file:\n %1").arg(_catalog->currentURL().prettyURL()));
+ break;
+ }
+ case BUSY:
+ {
+ KMessageBox::error(this,i18n(
+ "KBabel has not finished the last operation yet.\n"
+ "Please wait."));
+ break;
+ }
+ case STOPPED:
+ break;
+ default:
+ {
+ whatToDo=KMessageBox::warningContinueCancel(this,
+ i18n("An error occurred while trying to write to file:\n%1\n"
+ "Do you want to save to another file or cancel?").arg(_catalog->currentURL().prettyURL()),
+ i18n("Error"),KStdGuiItem::save());
+ break;
+ }
+ }
+ switch(whatToDo)
+ {
+ case KMessageBox::Continue:
+ return saveFileAs();
+ default:
+ return false;
+
+ }
+
+ }
+
+ return true;
+}
+
+bool KBabelView::saveFileAs(KURL url, bool syntaxCheck)
+{
+ bool newName=false;
+ if(url.isEmpty())
+ {
+ if((url = KFileDialog::getSaveURL(currentURL().url(), CatalogExportPlugin::availableExportMimeTypes().join(" "),this)).isEmpty())
+ {
+ return false;
+ }
+ newName=true;
+ }
+
+ if (KIO::NetAccess::exists(url, false, this))
+ {
+ if(KMessageBox::warningContinueCancel(this,QString("<qt>%1</qt>").arg(i18n("The file %1 already exists. "
+ "Do you want to overwrite it?").arg(url.prettyURL())),i18n("Warning"),i18n("&Overwrite"))==KMessageBox::Cancel)
+ {
+ return false;
+ }
+
+ }
+
+ bool wasReadOnly=_catalog->isReadOnly();
+
+ ConversionStatus stat=_catalog->saveFileAs(url,true);
+
+
+ // if the file was not saved sucessfully ask for saving to another file
+ if(stat!=OK)
+ {
+ bool cancelLoop=false; // flag, if the saving loop should be canceled
+ do
+ {
+ // select the right error message
+ QString message;
+ switch(stat)
+ {
+ case NO_PERMISSIONS:
+ {
+ message=i18n("You do not have permission to write to file:\n%1\n"
+ "Do you want to save to another file or cancel?").arg(url.prettyURL());
+ break;
+ }
+ case NO_FILE:
+ {
+ message=i18n("You have specified a folder:\n%1\n"
+ "Do you want to save to another file or cancel?").arg(url.prettyURL());
+ break;
+ }
+ case NO_PLUGIN:
+ {
+ message=i18n("KBabel cannot find a corresponding plugin for the MIME type of the file:\n %1").arg(url.prettyURL());
+ break;
+ }
+ case UNSUPPORTED_TYPE:
+ {
+ message=i18n(
+ "The export plugin cannot handle this type of the file:\n %1").arg(url.prettyURL());
+ break;
+ }
+ default:
+ {
+ message=i18n("An error occurred while trying to write to file:\n%1\n"
+ "Do you want to save to another file or cancel?").arg(url.prettyURL());
+ break;
+ }
+ }
+
+ // now ask, if the user wants to save to another file or cancel
+ switch(KMessageBox::warningContinueCancel(this,message,i18n("Error"),KStdGuiItem::save()))
+ {
+ // save to another file
+ case KMessageBox::Continue:
+ {
+ // ask for new filename
+ if ((url = KFileDialog::getSaveURL(currentURL().url(), CatalogExportPlugin::availableExportMimeTypes().join(" "), this)).isEmpty())
+ {
+ // if no filename was given cancel all
+ return false;
+ }
+
+ if (KIO::NetAccess::exists(url, false, this))
+ {
+ if(KMessageBox::warningContinueCancel(this,i18n("The file %1 already exists.\n"
+ "Do you want to overwrite it?").arg(url.prettyURL()),i18n("Warning"),i18n("&Overwrite"))==KMessageBox::Continue)
+ {
+ stat=_catalog->saveFileAs(url);
+ if(stat!=OK)
+ cancelLoop=false;
+ else
+ cancelLoop=true;
+ }
+ }
+ else
+ {
+ stat=_catalog->saveFileAs(url);
+ if(stat!=OK)
+ cancelLoop=false;
+ else
+ cancelLoop=true;
+ }
+ break;
+ }
+ default: // the user do not want to save to another file
+ return false;
+ }
+ }
+ while(!cancelLoop);
+ }
+
+
+ if(wasReadOnly)
+ {
+ msgstrEdit->setReadOnly(false);
+ }
+
+ emit signalChangeCaption(_catalog->package());
+
+ if(newName)
+ {
+ dictBox->setEditedPackage(_catalog->packageName());
+ dictBox->setEditedFile(_catalog->currentURL().url());
+ }
+
+ // after save put current edit into dictionary as well
+ informDictionary();
+
+ if(syntaxCheck && _catalog->saveSettings().autoSyntaxCheck)
+ return checkSyntax(true,false);
+ else
+ return true;
+}
+
+bool KBabelView::saveFileSpecial()
+{
+ QString tmpname;
+ bool result = false;
+
+ {
+ // generate temporary name
+ KTempFile tmp;
+ tmp.setAutoDelete (true);
+ tmpname = tmp.name ();
+ }
+
+ {
+ // make sure the project is freed (pointer going out of scope)
+ KBabel::Project::Ptr project = KBabel::ProjectManager::open (tmpname);
+
+ project->setSettings( _catalog->saveSettings() );
+ KConfigDialog *_prefDialog = new KConfigDialog(this, "project dialog", project->settings(),
+ KDialogBase::IconList, KDialogBase::Cancel|KDialogBase::Ok|KDialogBase::Help);
+
+ _prefDialog->setCaption( i18n("Special Save Settings") );
+ _prefDialog->setHelp("preferences_save");
+
+ SavePreferences* _prefWidget = new SavePreferences(_prefDialog);
+ _prefWidget->setAutoSaveVisible(false);
+ _prefDialog->addPage(_prefWidget, i18n("title of page in preferences dialog","Save")
+ , "filesave"
+ , i18n("Options for File Saving"));
+
+ if( _prefDialog->exec() == QDialog::Accepted )
+ {
+ SaveSettings settings = project->saveSettings();
+ SaveSettings originalSettings = _catalog->saveSettings();
+ _catalog->setSettings(settings);
+ result = saveFileAs();
+
+ _catalog->setSettings(originalSettings);
+ }
+ }
+
+ QFile::remove( tmpname );
+
+ return result;
+}
+
+bool KBabelView::checkSyntax()
+{
+ return checkSyntax(false,false);
+}
+
+bool KBabelView::checkSyntax(bool msgOnlyAtError,bool question)
+{
+ if(currentURL().isEmpty())
+ return false;
+
+ bool returnCode=true;
+ QString output;
+
+ Msgfmt::Status result=_catalog->checkSyntax( output );
+
+ const QStringList outputLines = QStringList::split("\n",output);
+
+ switch(result)
+ {
+ case Msgfmt::Ok:
+ {
+ if(!msgOnlyAtError)
+ {
+ KMessageBox::informationList( this, i18n("The file is syntactically correct.\n\n"
+ "Output of \"msgfmt --statistics\":\n"), outputLines );
+ }
+ returnCode=true;
+ break;
+ }
+ case Msgfmt::Unsupported:
+ {
+ if(!msgOnlyAtError)
+ {
+ KMessageBox::sorry(this
+ ,i18n("You can use gettext tools only for checking PO files."));
+ }
+ returnCode=true;
+ break;
+ }
+ case Msgfmt::HeaderError:
+ case Msgfmt::SyntaxError:
+ {
+ QString msg = ( result == Msgfmt::SyntaxError )
+ ? i18n("msgfmt detected a syntax error.\n")
+ : i18n("msgfmt detected a header syntax error.\n");
+
+ if(question)
+ {
+ msg += i18n("\nDo you want to continue or cancel and edit the file again?");
+ msg += "\n\n";
+ msg += i18n("Output of \"msgfmt --statistics\":\n");
+ switch( KMessageBox::warningContinueCancelList( this, msg,
+ outputLines, i18n("Warning"), KStdGuiItem::cont()) )
+ {
+ case KMessageBox::Continue:
+ returnCode=true;
+ break;
+ default:
+ returnCode=false;
+ }
+ }
+ else
+ {
+#if KDE_IS_VERSION ( 3, 4, 0 )
+ msg += "\n";
+ msg += i18n("Please edit the file again.");
+ msg += "\n\n";
+ msg += i18n("Output of \"msgfmt --statistics\":\n");
+ KMessageBox::errorList( this, msg, outputLines );
+#else
+ msg += i18n("Output of \"msgfmt --statistics\":\n");
+ msg += output;
+ msg += "\n\n";
+ msg += i18n("Please edit the file again.");
+ KMessageBox::error( this, msg );
+#endif
+ returnCode=false;
+ }
+ break;
+ }
+ case Msgfmt::NoExecutable:
+ case Msgfmt::Error:
+ {
+ QString msg = i18n("While trying to check syntax with msgfmt an error occurred.\n"
+ "Please make sure that you have installed\n"
+ "the GNU gettext package properly.");
+ if(question)
+ {
+ msg += i18n("\nDo you want to continue or cancel and edit the file again?");
+ switch( KMessageBox::warningContinueCancelList( this, msg,
+ outputLines, i18n("Warning"), KStdGuiItem::cont() ))
+ {
+ case KMessageBox::Continue:
+ returnCode=true;
+ break;
+ default:
+ returnCode=false;
+ }
+ }
+ else
+ {
+#if KDE_IS_VERSION ( 3, 4, 0 )
+ msg += "\n";
+ msg += i18n("Please edit the file again.");
+ KMessageBox::errorList( this, msg, outputLines );
+#else
+ msg += output;
+ msg += "\n\n";
+ msg += i18n("Please edit the file again.");
+ KMessageBox::error( this, msg );
+#endif
+ returnCode=false;
+ }
+
+ break;
+ }
+ }
+
+ emitEntryState();
+
+ return returnCode;
+}
+
+bool KBabelView::checkAll()
+{
+ if(currentURL().isEmpty())
+ return false;
+
+ bool a,badresult=false;
+
+ QValueList<KDataToolInfo> tools = ToolAction::validationTools();
+
+ QValueList<KDataToolInfo>::ConstIterator entry = tools.begin();
+ for( ; entry != tools.end(); ++entry )
+ {
+ KDataTool* tool = (*entry).createTool();
+ if( tool )
+ {
+ a = _catalog->checkUsingTool(tool,entry==tools.begin());
+ badresult = badresult || !a;
+ delete tool;
+ }
+ }
+
+ QString output;
+
+ a = (_catalog->checkSyntax(output, false)!=Msgfmt::Ok);
+ badresult=badresult||a;
+
+ emitEntryState();
+
+ if(!badresult)
+ {
+ KMessageBox::information(this
+ ,i18n("No mismatch has been found.")
+ , i18n("Title in Dialog: Perform all checks","Perform All Checks"));
+ }
+ else
+ {
+ int index=0;
+ DocPosition pos;
+ if(!_catalog->hasError(0,pos))
+ index = _catalog->nextError(0, pos);
+ if(index>=0)
+ {
+ gotoEntry(pos);
+ }
+
+ KMessageBox::error(this
+ ,i18n("Some mismatches have been found.\n"
+ "Please check the questionable entries by using "
+ "Go->Next error")
+ , i18n("Title in Dialog: Perform all checks","Perform All Checks"));
+
+ }
+
+ return !badresult;
+}
+
+
+
+bool KBabelView::checkModified()
+{
+ bool flag=true;
+
+ if(isModified())
+ {
+ switch(KMessageBox::warningYesNoCancel(this,
+ i18n("The document contains unsaved changes.\n"
+ "Do you want to save your changes or discard them?"),i18n("Warning"),
+ KStdGuiItem::save(),KStdGuiItem::discard()))
+ {
+ case KMessageBox::Yes:
+ {
+ flag = saveFile(false);
+ if(flag && _catalog->saveSettings().autoSyntaxCheck)
+ {
+ flag = checkSyntax(true,true);
+ }
+ break;
+ }
+ case KMessageBox::No:
+ flag = true;
+ break;
+ default: // canceled
+ flag = false;
+ break;
+ }
+ }
+
+ return flag;
+}
+
+void KBabelView::updateEditor(int form, bool delay)
+{
+ msgstrEdit->blockSignals(true);
+
+ if(KBabelSettings::autoUnsetFuzzy() && !msgstrEdit->isModified())
+ {
+ disconnect(msgstrEdit,SIGNAL(textChanged()),this,SLOT(autoRemoveFuzzyStatus()));
+ }
+
+ msgidLabel->setText(_catalog->msgid(_currentIndex), _catalog->msgctxt(_currentIndex));
+ msgidLabel->repaint();
+
+ msgstrEdit->setText(_catalog->msgstr(_currentIndex));
+ msgstrEdit->showForm( form );
+ msgstrEdit->repaint();
+ m_cataloglistview->setSelectedItem(_currentIndex);
+
+ if(KBabelSettings::autoUnsetFuzzy() && _catalog->isFuzzy(_currentIndex))
+ {
+ connect(msgstrEdit,SIGNAL(textChanged()),this,SLOT(autoRemoveFuzzyStatus()));
+ }
+
+ msgstrEdit->blockSignals(false);
+
+ autoCheck(false);
+
+ // no need to display diff if this message wasn't translated
+ if(_diffEnabled && !(_catalog->isUntranslated(_currentIndex)))
+ {
+ autoDiff();
+ }
+
+ if(isActiveWindow() && KBabelSettings::autoSearch()
+ && !_autoSearchTempDisabled)
+ {
+ if (delay)
+ {
+ QTimer::singleShot(0, this, SLOT (startSearch()));
+ }
+ else
+ {
+ startSearch();
+ }
+ }
+
+ msgstrEdit->setFocus();
+ msgstrEdit->setModified(false);
+}
+
+
+void KBabelView::undo()
+{
+ if(!_catalog->isUndoAvailable())
+ return;
+
+ int newIndex=_catalog->undo();
+
+ if(newIndex != (int)_currentIndex)
+ {
+ DocPosition pos;
+ pos.item=newIndex;
+ pos.form=0;
+ gotoEntry(pos);
+ }
+}
+
+void KBabelView::redo()
+{
+ if(!_catalog->isRedoAvailable())
+ return;
+
+ int newIndex=_catalog->redo();
+
+ if(newIndex != (int)_currentIndex)
+ {
+ DocPosition pos;
+ pos.item=newIndex;
+ pos.form=0;
+ gotoEntry(pos);
+ }
+}
+
+void KBabelView::textCut()
+{
+ if(msgstrEdit->hasFocus())
+ {
+ msgstrEdit->cut();
+ }
+}
+
+void KBabelView::textCopy()
+{
+ if(msgstrEdit->hasSelectedText())
+ {
+ msgstrEdit->copy();
+ }
+ else if(msgidLabel->hasSelectedText())
+ {
+ msgidLabel->copy();
+ }
+ else if(dictBox->isVisible() && dictBox->hasSelectedText())
+ {
+ dictBox->copy();
+ }
+}
+
+void KBabelView::textPaste()
+{
+ msgstrEdit->paste();
+}
+
+
+bool KBabelView::findNext()
+{
+ if(!_findDialog)
+ return false;
+
+ if( !_redirectedBackSearch && _findDialog->findOpts().backwards )
+ {
+ _redirectedBackSearch = true;
+ bool res = findPrev();
+ _redirectedBackSearch = false;
+ return res;
+ }
+
+ DocPosition pos;
+ pos.item=_currentIndex;
+ pos.form=0;
+
+ if( m_commentview->hasFocus() ) {
+ pos.part = Comment;
+ pos.offset = m_commentview->currentIndex();
+ }
+ else
+ if(msgidLabel->hasFocus() ) {
+ pos.part = Msgid;
+ pos.offset = msgidLabel->currentIndex();
+ }
+ else {
+ pos.part = Msgstr;
+ pos.offset = msgstrEdit->currentIndex();
+ pos.form = msgstrEdit->currentForm();
+ }
+
+ _findStartPos=pos;
+ _findBreakAtEnd=false;
+
+ return findNext_internal(pos);
+}
+
+bool KBabelView::findPrev()
+{
+ if(!_findDialog)
+ return false;
+
+ if( !_redirectedBackSearch && _findDialog->findOpts().backwards )
+ {
+ _redirectedBackSearch = true;
+ bool res = findNext();
+ _redirectedBackSearch = false;
+ return res;
+ }
+
+ DocPosition pos;
+ pos.item=_currentIndex;
+
+ if( m_commentview->hasFocus()) {
+ pos.part = Comment;
+ pos.offset = m_commentview->currentIndex();
+ }
+ else
+ if(msgidLabel->hasFocus() ) {
+ pos.part = Msgid;
+ pos.offset = msgidLabel->currentIndex();
+ }
+ else {
+ pos.part = Msgstr;
+ pos.offset = msgstrEdit->currentIndex();
+ pos.form = msgstrEdit->currentForm();
+ }
+
+ _findStartPos=pos;
+ _findBreakAtEnd=false;
+
+ return findPrev_internal(pos);
+}
+
+
+bool KBabelView::findNext_internal(DocPosition& pos, bool forReplace, bool gui)
+{
+ FindOptions opts;
+ if(forReplace)
+ opts = _replaceDialog->replaceOpts();
+ else
+ opts = _findDialog->findOpts();
+ int len=0;
+ deselectAll();
+
+ bool success=false;
+ if( !opts.askFile ) // for find in all files ignore return to the beginning
+ if(!_findBreakAtEnd && !(success=_catalog->findNext(&opts,pos,len))) {
+ int r;
+ if(forReplace) {
+ _replaceWasAtEnd=true;
+ _findBreakAtEnd=true;
+ if(gui) {
+ r = KMessageBox::questionYesNo(this,
+ i18n("<qt>%n replacement made.<br>End of document reached.<br>Continue from the beginning?</qt>",
+ "<qt>%n replacements made.<br>End of document reached.<br>Continue from the beginning?</qt>",
+ _replacesTotal), QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel());
+ }
+ else {
+ r = KMessageBox::Yes;
+ }
+ }
+ else {
+ r = KMessageBox::questionYesNo(this,i18n("End of document reached.\n"
+ "Continue from the beginning?"), QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel());
+ }
+ if(r == KMessageBox::Yes) {
+ if(opts.inMsgid && !forReplace)
+ pos.part = Msgid;
+ else if(opts.inComment)
+ pos.part = Comment;
+ else
+ pos.part = Msgstr;
+
+ pos.item = 0;
+ pos.offset = 0;
+ pos.form = 0;
+
+ }
+ else
+ return false;
+ }
+
+
+ if(!success && !_catalog->findNext(&opts,pos,len)) { // reached end the second time
+ if( !opts.askFile )
+ {
+ if(forReplace) {
+ KMessageBox::information(this,i18n("%n replacement made","%n replacements made",_replacesTotal));
+ }
+ else {
+ KMessageBox::information(this,i18n("Search string not found."));
+ }
+ return false;
+ }
+ else
+ {
+ if( opts.askForNextFile )
+ {
+ int r = KMessageBox::questionYesNo(this,i18n("End of document reached.\n"
+ "Continue in the next file?"), QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel());
+ if( r != KMessageBox::Yes ) return false;
+
+ }
+ if( isModified() && !opts.askForSave ) saveFile();
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data, replyData;
+ QCString replyType;
+ bool morefiles = false; // more files to lookup in
+ if( !client->call( _fileSource,"CatalogManagerIFace",
+ "findNextFile()", data, replyType, replyData) ) kdDebug(KBABEL) << "unable to call, reply type is " << replyType << endl;
+ else if( replyType == "QCString" )
+ {
+ QDataStream rep( replyData, IO_ReadOnly);
+ QCString f;
+ rep >> f;
+ QString foundFile = QString::fromUtf8(f);
+ morefiles = !f.isEmpty() && !f.isNull();
+ if( morefiles )
+ {
+ emit open( KURL(foundFile) );
+ pos.item = 0;
+ pos.part = Msgid;
+ pos.offset = 0;
+ _catalog->findNext(&opts,pos,len);
+ } else {
+ if( f.isNull() ) // is there possibility to get a new file?
+ {
+ // no, this is the end finally
+ if( forReplace )
+ KMessageBox::information(this,i18n("%n replacement made","%n replacements made",_replacesTotal));
+ else
+ KMessageBox::information(this,i18n("Search string not found."));
+ return false;
+ }
+ else
+ {
+ // there can be a new file, let user know
+ showTryLaterMessageBox();
+ if( forReplace ) return true; // let replace dialog stay
+ else return false;
+ }
+ }
+ } else {
+ KMessageBox::error(this,i18n("DCOP communication with Catalog Manager failed."));
+ return false;
+ }
+ }
+ }
+ if(gui) {
+ if( _currentIndex != pos.item
+ || (pos.part==Msgstr && msgstrEdit->currentForm() != pos.form) )
+ {
+ gotoEntry(pos);
+ }
+
+ int line,col,endline,endcol;
+ switch(pos.part) {
+ case Msgid:
+ msgidLabel->selectAll(false);
+ msgidLabel->setFocus();
+ msgidLabel->offset2Pos(pos.offset,line,col);
+ msgidLabel->offset2Pos(pos.offset+len,endline,endcol);
+
+ msgidLabel->setSelection(line,col,endline,endcol);
+ msgidLabel->setCursorPosition(endline,endcol);
+
+ _lastFoundString=msgidLabel->selectedText();
+ break;
+ case Msgstr:
+ msgstrEdit->selectAll(false);
+ msgstrEdit->setFocus();
+ msgstrEdit->offset2Pos(pos.offset,line,col);
+ msgstrEdit->offset2Pos(pos.offset+len,endline,endcol);
+
+ msgstrEdit->setSelection(line,col,endline,endcol);
+ msgstrEdit->setCursorPosition(endline,endcol);
+
+ _lastFoundString=msgstrEdit->selectedText();
+ break;
+ case Comment:
+ {
+ m_mainwindow->makeWidgetDockVisible (m_commentview);
+ _lastFoundString= m_commentview->selectText (pos.offset, pos.offset+len);
+ break;
+ }
+ case UndefPart:
+ break;
+ }
+ }
+
+ if(forReplace) {
+ kdDebug(KBABEL) << "This is forReplace" << endl;
+ _replaceLen=len;
+
+ bool finished=false;
+ // check if we had reached the beginning before and now are before our starting position
+ if(_replaceWasAtEnd) {
+ if( pos.item > _findStartPos.item ) {
+ finished=true;
+ }
+ else if(pos.item == _findStartPos.item) {
+ if(pos.part==Msgstr && !opts.inComment && pos.offset >= _findStartPos.offset+_replaceExtraOffset)
+ finished=true;
+ else if(pos.part==Comment && pos.offset >= _findStartPos.offset+_replaceExtraOffset)
+ finished=true;
+ }
+ }
+
+ if(finished) {
+ KMessageBox::information(this,i18n("%n replacement made","%n replacements made",_replacesTotal));
+ return false;
+ }
+
+ }
+
+ return true;
+}
+
+bool KBabelView::findPrev_internal(DocPosition& pos, bool forReplace, bool gui)
+{
+ FindOptions opts;
+ if(forReplace)
+ opts = _replaceDialog->replaceOpts();
+ else
+ opts = _findDialog->findOpts();
+
+ int len=0;
+
+ deselectAll();
+ bool success=false;
+ if(!_findBreakAtEnd && !(success=_catalog->findPrev(&opts,pos,len))) {
+ int r;
+
+ if(forReplace) {
+ _replaceWasAtEnd=true;
+ _findBreakAtEnd=true;
+ if(gui) {
+ r = KMessageBox::questionYesNo(this,
+ i18n("<qt>%n replacement made.<br>Beginning of document reached.<br>Continue from the end?</qt>",
+ "<qt>%n replacements made.<br>Beginning of document reached.<br>Continue from the end?</qt>",
+ _replacesTotal),QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel());
+ }
+ else {
+ r = KMessageBox::Yes;
+ }
+
+ }
+ else {
+ r = KMessageBox::questionYesNo(this,i18n("Beginning of document reached.\n"
+ "Continue from the end?"), QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel());
+ }
+ if(r == KMessageBox::Yes) {
+ pos.item = _catalog->numberOfEntries()-1;
+
+ if(opts.inComment) {
+ pos.part = Comment;
+ pos.offset = _catalog->comment(pos.item).length();
+ }
+ else if(opts.inMsgstr || forReplace) {
+ pos.part = Msgstr;
+ if( _catalog->msgstr(pos.item).empty() ) pos.offset=0;
+ else pos.offset = _catalog->msgstr(pos.item).last().length();
+ pos.form = _catalog->msgstr(pos.item).count()-1;
+ }
+ else {
+ pos.part = Msgid;
+ //FIXME: we should search in msgid plural forms
+ pos.offset = _catalog->msgid(pos.item).first().length();
+ }
+ }
+ else
+ return false;
+ }
+
+ // start at the end
+ if(!success && !_catalog->findPrev(&opts,pos,len)) {
+ if(forReplace) {
+ KMessageBox::information(this,i18n("%n replacement made","%n replacements made",_replacesTotal));
+ }
+ else {
+ KMessageBox::information(this,i18n("Search string not found."));
+ }
+ return false;
+ }
+ else if(gui) {
+ if(_currentIndex != pos.item
+ || (pos.part==Msgstr && msgstrEdit->currentForm() != pos.form) )
+ gotoEntry(pos);
+
+ int line,col,endline,endcol;
+ switch(pos.part) {
+ case Msgid:
+ msgidLabel->selectAll(false);
+ msgidLabel->setFocus();
+ msgidLabel->offset2Pos(pos.offset+len,line,col);
+ msgidLabel->offset2Pos(pos.offset,endline,endcol);
+
+ msgidLabel->setSelection(line,col,endline,endcol);
+ msgidLabel->setCursorPosition(endline,endcol);
+
+ _lastFoundString=msgidLabel->selectedText();
+ break;
+ case Msgstr:
+ msgstrEdit->selectAll(false);
+ msgstrEdit->setFocus();
+ msgstrEdit->offset2Pos(pos.offset+len,line,col);
+ msgstrEdit->offset2Pos(pos.offset,endline,endcol);
+
+ msgstrEdit->setSelection(line,col,endline,endcol);
+ msgstrEdit->setCursorPosition(endline,endcol);
+
+ _lastFoundString=msgstrEdit->selectedText();
+ break;
+ case Comment:
+ m_mainwindow->makeWidgetDockVisible (m_commentview);
+ _lastFoundString=m_commentview->
+ selectText(pos.offset, pos.offset+len);
+ break;
+ case UndefPart:
+ break;
+ }
+ }
+
+ if(forReplace) {
+ _replaceLen=len;
+
+ bool finished=false;
+ // check if we had reached the beginning before and now are before our starting position
+ if(_replaceWasAtEnd) {
+ if( pos.item < _findStartPos.item ) {
+ finished=true;
+ }
+ else if(pos.item == _findStartPos.item) {
+ if(pos.part==Comment && !opts.inMsgstr && pos.offset < _findStartPos.offset+_replaceExtraOffset)
+ finished=true;
+ else if(pos.part==Msgstr && pos.offset < _findStartPos.offset+_replaceExtraOffset)
+ finished=true;
+ }
+ }
+
+ if(finished) {
+ KMessageBox::information(this,i18n("%n replacement made","%n replacements made",_replacesTotal));
+ return false;
+ }
+
+ }
+
+
+ return true;
+}
+
+
+void KBabelView::find()
+{
+ Part hadFocus;
+ if(msgidLabel->hasFocus())
+ hadFocus=Msgid;
+ else if(m_commentview->hasFocus())
+ hadFocus=Comment;
+ else
+ hadFocus=Msgstr;
+
+ if( !_findDialog ) {
+ _findDialog = new FindDialog(false,this);
+ }
+
+ QString marked;
+ if(msgstrEdit->hasFocus()) {
+ marked=msgstrEdit->selectedText();
+ msgstrEdit->selectAll(false);
+ }
+ else if(m_commentview->hasFocus()) {
+ marked=m_commentview->selectedText();
+ m_commentview->textDeselectAll();
+ }
+ else if(msgidLabel->hasFocus()) {
+ marked=msgidLabel->selectedText();
+ msgidLabel->selectAll(false);
+ }
+
+
+ if(marked==_lastFoundString)
+ marked="";
+
+ if( _findDialog->exec(marked) == QDialog::Accepted ) {
+ DocPosition pos;
+ FindOptions opts=_findDialog->findOpts();
+ opts.askFile = false; // do not search in more files
+ _findDialog->setFindOpts(opts);
+
+ if(opts.fromCursor) {
+ _findBreakAtEnd=false;
+ pos.item=_currentIndex;
+
+ if(hadFocus == Comment && opts.inComment) {
+ pos.part = Comment;
+ pos.offset = m_commentview->currentIndex();
+ }
+ else
+ if( hadFocus == Msgid && opts.inMsgid) {
+ pos.part = Msgid;
+ pos.offset = msgidLabel->currentIndex();
+ }
+ else {
+ pos.part = Msgstr;
+ pos.offset = msgstrEdit->currentIndex();
+ }
+ }
+ else {
+ _findBreakAtEnd=true;
+
+ if(opts.backwards) {
+ pos.item=_catalog->numberOfEntries();
+ if(opts.inComment)
+ pos.part=Comment;
+ else if(opts.inMsgstr)
+ pos.part=Msgstr;
+ else
+ pos.part=Msgid;
+
+ pos.offset=1000; // set to a high number
+ }
+ else {
+ pos.item=0;
+ if(opts.inMsgid)
+ pos.part=Msgid;
+ else if(opts.inMsgstr)
+ pos.part=Msgstr;
+ else
+ pos.part=Comment;
+
+ pos.offset=0;
+ }
+ }
+
+ if( opts.backwards ) {
+ _findStartPos=pos;
+ findPrev_internal(pos);
+ }
+ else {
+ _findStartPos=pos;
+ findNext_internal(pos);
+ }
+ }
+}
+
+void KBabelView::replace()
+{
+ _replacesTotal=0;
+ _replaceLen=0;
+ _replaceWasAtEnd=false;
+ _replaceExtraOffset=0;
+
+ Part hadFocus;
+ if(msgidLabel->hasFocus())
+ hadFocus=Msgid;
+ else if(m_commentview->hasFocus())
+ hadFocus=Comment;
+ else
+ hadFocus=Msgstr;
+
+ if( !_replaceDialog ) {
+ _replaceDialog = new FindDialog(true,this);
+ }
+ QString marked;
+ if(msgstrEdit->hasFocus()) {
+ marked=msgstrEdit->selectedText();
+ msgstrEdit->selectAll(false);
+ }
+ else if(m_commentview->hasFocus()) {
+ marked=m_commentview->selectedText();
+ m_commentview->textDeselectAll();
+ }
+ else if(msgidLabel->hasFocus()) {
+ marked=msgidLabel->selectedText();
+ msgidLabel->selectAll(false);
+ }
+
+ if(marked==_lastFoundString)
+ marked="";
+
+ if( _replaceDialog->exec(marked) == QDialog::Accepted ) {
+ KBabel::ReplaceOptions opts=_replaceDialog->replaceOpts();
+ if(opts.fromCursor) {
+ _findBreakAtEnd=false;
+ _replacePos.item=_currentIndex;
+
+ if(hadFocus==Comment && opts.inComment) {
+ _replacePos.part = Comment;
+ _replacePos.offset = m_commentview->currentIndex();
+ }
+ else
+ {
+ _replacePos.part = Msgstr;
+ _replacePos.offset = msgstrEdit->currentIndex();
+ }
+ }
+ else {
+ _findBreakAtEnd=true;
+ if(opts.backwards) {
+ _replacePos.item=_catalog->numberOfEntries();
+ if(opts.inComment)
+ _replacePos.part=Comment;
+ else
+ _replacePos.part=Msgstr;
+
+ _replacePos.offset=1000; // set to a high number
+ }
+ else {
+ _replacePos.item=0;
+ if(opts.inMsgstr)
+ _replacePos.part=Msgstr;
+ else
+ _replacePos.part=Comment;
+
+ _replacePos.offset=0;
+ }
+ }
+
+ // do not ask for next file from catalog manager
+ opts.askFile = false;
+ _replaceDialog->setReplaceOpts(opts);
+
+ bool success;
+
+ if( opts.backwards ) {
+ _findStartPos=_replacePos;
+ success = findPrev_internal(_replacePos,true,opts.ask);
+ }
+ else {
+ _findStartPos=_replacePos;
+ success = findNext_internal(_replacePos,true,opts.ask);
+ }
+
+
+
+ if(success) {
+ if(!_replaceAskDialog) {
+ _replaceAskDialog = new ReplaceDialog(this);
+ connect(_replaceAskDialog,SIGNAL(replace()),this,SLOT(replaceNext()));
+ connect(_replaceAskDialog,SIGNAL(next()),this,SLOT(findNextReplace()));
+ connect(_replaceAskDialog,SIGNAL(replaceAll()),this,SLOT(replaceAll()));
+ }
+
+ if(opts.ask) {
+ _replaceAskDialog->exec();
+ }
+ else
+ replaceAll();
+ }
+
+ }
+}
+
+
+void KBabelView::replaceNext()
+{
+ _replacesTotal++;
+
+ KBabel::ReplaceOptions opts=_replaceDialog->replaceOpts();
+
+ // calculate the diff to original offset due to replacing a string
+ // in the starting item
+ if(_findStartPos.item == _replacePos.item ) {
+ if((opts.backwards && !_replaceWasAtEnd)
+ || (!opts.backwards && _replaceWasAtEnd)) {
+ _replaceExtraOffset += (opts.replaceStr.length()-_replaceLen);
+ }
+ }
+
+ Part part;
+ uint form = 0;
+ QString str;
+
+ if(_replacePos.part==Msgstr) {
+ part=Msgstr;
+ str = _catalog->msgstr(_replacePos.item).first()
+ .mid(_replacePos.offset,_replaceLen);
+ form=_replacePos.form;
+ }
+ else if(_replacePos.part==Comment) {
+ part = Comment;
+ str = _catalog->comment(_replacePos.item)
+ .mid(_replacePos.offset,_replaceLen);
+ }
+ else {
+ kdWarning() << "msgid can not be changed in KBabelView::replaceNext()"
+ << endl;
+ return;
+}
+
+ _catalog->applyBeginCommand( _replacePos.item,part,this);
+
+ DelTextCmd* delCmd = new DelTextCmd(_replacePos.offset,str,form);
+ delCmd->setPart(part);
+ delCmd->setIndex(_replacePos.item);
+ _catalog->applyEditCommand(delCmd,0);
+
+ InsTextCmd* insCmd = new InsTextCmd(_replacePos.offset,opts.replaceStr,form);
+ insCmd->setPart(part);
+ insCmd->setIndex(_replacePos.item);
+ _catalog->applyEditCommand(insCmd,0);
+
+ _catalog->applyEndCommand( _replacePos.item,part,this);
+
+ // now find next string
+ bool success;
+
+ if( opts.backwards ) {
+ success = findPrev_internal(_replacePos,true);
+ }
+ else {
+ _replacePos.offset+=opts.replaceStr.length();
+ success = findNext_internal(_replacePos,true);
+ }
+
+ if(!success) {
+ if(_replaceAskDialog && _replaceAskDialog->isVisible())
+ _replaceAskDialog->hide();
+ }
+
+}
+
+
+void KBabelView::replaceAll()
+{
+ if(_replaceAskDialog && _replaceAskDialog->isVisible())
+ _replaceAskDialog->hide();
+
+ KBabel::ReplaceOptions opts=_replaceDialog->replaceOpts();
+ bool success=true;
+
+ _catalog->applyBeginCommand(_replacePos.item,Msgstr,this);
+
+ while(success)
+ {
+ kapp->processEvents(100);
+
+ _replacesTotal++;
+
+ // calculate the diff to original offset due to replacing a string
+ // in the starting item
+ if(_findStartPos.item == _replacePos.item ) {
+ if((opts.backwards && !_replaceWasAtEnd) || (!opts.backwards && _replaceWasAtEnd)) {
+ _replaceExtraOffset += (opts.replaceStr.length()-_replaceLen);
+ }
+ }
+
+ Part part;
+ uint form=0;
+ QString str;
+
+ if(_replacePos.part==Msgstr) {
+ part=Msgstr;
+ form=_replacePos.form;
+ str = _catalog->msgstr(_replacePos.item).first().mid(_replacePos.offset,_replaceLen);
+ }
+ else if(_replacePos.part==Comment) {
+ part = Comment;
+ str = _catalog->comment(_replacePos.item).mid(_replacePos.offset,_replaceLen);
+ }
+ else {
+ kdWarning() << "msgid can not be changed in KBabelView::replaceNext()" << endl;
+ return;
+ }
+
+ DelTextCmd* delCmd = new DelTextCmd(_replacePos.offset,str,form);
+ delCmd->setPart(part);
+ delCmd->setIndex(_replacePos.item);
+ _catalog->applyEditCommand(delCmd,0);
+
+ InsTextCmd* insCmd = new InsTextCmd(_replacePos.offset,opts.replaceStr,form);
+ insCmd->setPart(part);
+ insCmd->setIndex(_replacePos.item);
+ _catalog->applyEditCommand(insCmd,0);
+
+
+ // now find next string
+ if( opts.backwards ) {
+ success = findPrev_internal(_replacePos,true,false);
+ }
+ else {
+ _replacePos.offset+=opts.replaceStr.length();
+ success = findNext_internal(_replacePos,true,false);
+ }
+ }
+
+ _catalog->applyEndCommand(_replacePos.item,Msgstr,this);
+}
+
+void KBabelView::findNextReplace()
+{
+ bool success;
+ KBabel::ReplaceOptions opts=_replaceDialog->replaceOpts();
+
+ if( opts.backwards ) {
+ success = findPrev_internal(_replacePos,true);
+ }
+ else {
+ _replacePos.offset++;
+ success = findNext_internal(_replacePos,true);
+ }
+
+ if(!success) {
+ if(_replaceAskDialog && _replaceAskDialog->isVisible())
+ _replaceAskDialog->hide();
+ }
+
+}
+
+void KBabelView::findInFile(QCString fileSource, FindOptions options)
+{
+ DocPosition pos;
+ pos.item=0;
+ pos.part=Msgid;
+ pos.offset=0;
+ _findStartPos=pos;
+ _findBreakAtEnd=true; // do not start from the beginning at the end
+ _showTryLaterBox=true;
+
+ // delete dontDisplayAgain from configuration
+ KConfig* config = KGlobal::config();
+ KConfigGroupSaver saver(config,"Notification Messages");
+ config->writeEntry("waitForNextFile",true);
+
+ // set that there can be more files
+ options.askFile = true;
+
+ _fileSource = fileSource;
+
+ if( !_findDialog ) _findDialog = new FindDialog(false,this);
+ _findDialog->setFindOpts(options);
+ findNext_internal(pos);
+}
+
+void KBabelView::replaceInFile(QCString fileSource, KBabel::ReplaceOptions options)
+{
+ _replacePos.item=0;
+ _replacePos.part=Msgid;
+ _replacePos.offset=0;
+
+ _replacesTotal=0;
+ _replaceLen=0;
+ _replaceWasAtEnd=false;
+ _replaceExtraOffset=0;
+
+ _findBreakAtEnd=true;
+ _showTryLaterBox=true;
+
+ // delete dontDisplayAgain from configuration
+ KConfig* config = KGlobal::config();
+ KConfigGroupSaver saver(config,"Notification Messages");
+ config->writeEntry("waitForNextFile",true);
+
+ // set that there can be more files
+ options.askFile = true;
+
+ _fileSource = fileSource;
+
+ if( !_replaceDialog ) _replaceDialog = new FindDialog(true,this);
+ _replaceDialog->setReplaceOpts(options);
+
+ bool success;
+
+ success = findNext_internal(_replacePos,true);
+
+ if(!success) kdDebug(KBABEL) << "Not found in file where catalog manager told us. This should not happen" << endl;
+ else {
+ if(!_replaceAskDialog) {
+ _replaceAskDialog = new ReplaceDialog(this);
+ connect(_replaceAskDialog,SIGNAL(replace()),this,SLOT(replaceNext()));
+ connect(_replaceAskDialog,SIGNAL(next()),this,SLOT(findNextReplace()));
+ connect(_replaceAskDialog,SIGNAL(replaceAll()),this,SLOT(replaceAll()));
+ }
+
+ if(options.ask) {
+ _replaceAskDialog->exec();
+ }
+ else replaceAll();
+ }
+}
+
+
+void KBabelView::deselectAll()
+{
+ msgstrEdit->selectAll(false);
+// FIXME: commentEdit->selectAll(false);
+ msgidLabel->selectAll(false);
+}
+
+void KBabelView::selectAll()
+{
+ if(msgstrEdit->hasFocus())
+ {
+ msgstrEdit->selectAll();
+ }
+// FIXME: else if(commentEdit->hasFocus())
+// FIXME: {
+// FIXME: commentEdit->selectAll();
+// FIXME: }
+ else if(msgidLabel->hasFocus())
+ {
+ msgidLabel->selectAll();
+ }
+}
+
+void KBabelView::clear()
+{
+ if(msgstrEdit->hasFocus())
+ {
+ msgstrEdit->clear();
+ }
+// FIXME: else if(commentEdit->hasFocus())
+// FIXME: {
+// FIXME: commentEdit->clear();
+// FIXME: }
+}
+
+void KBabelView::msgid2msgstr()
+{
+ // FIXME: should care about plural forms
+ QString text = _catalog->msgid(_currentIndex).first();
+
+ // this is KDE specific:
+ if(text.find("_: NAME OF TRANSLATORS\\n")==0)
+ {
+ text=_catalog->identitySettings().authorLocalizedName;
+ }
+ else if(text.find("_: EMAIL OF TRANSLATORS\\n")==0)
+ {
+ text=_catalog->identitySettings().authorEmail;
+ }
+ else if(_catalog->isGeneratedFromDocbook() && text.find("ROLES_OF_TRANSLATORS")==0)
+ {
+ text="<othercredit role=\\\"translator\\\">\n"
+ "<firstname></firstname><surname></surname>\n"
+ "<affiliation><address><email>"+_catalog->identitySettings().authorEmail+"</email></address>\n"
+ "</affiliation><contrib></contrib></othercredit>";
+ }
+ else if(_catalog->isGeneratedFromDocbook() && text.find("CREDIT_FOR_TRANSLATORS")==0)
+ {
+ text="<para>"+_catalog->identitySettings().authorLocalizedName+"\n"+
+ "<email>"+_catalog->identitySettings().authorEmail+"</email></para>";
+ }
+ else if(text.contains(_catalog->miscSettings().singularPlural))
+ {
+ text.replace(_catalog->miscSettings().singularPlural,"");
+ }
+ // end of KDE specific part
+
+
+ QRegExp reg=_catalog->miscSettings().contextInfo;
+ if(text.contains(reg))
+ {
+ text.replace(reg,"");
+ }
+
+ modifyMsgstrText(0,text,true);
+
+ msgstrEdit->setCursorPosition(0,0);
+}
+
+void KBabelView::search2msgstr()
+{
+ modifyMsgstrText(0,dictBox->translation(),true);
+
+ msgstrEdit->setCursorPosition(0,0);
+}
+
+
+void KBabelView::gotoFirst()
+{
+ DocPosition pos;
+ pos.item=0;
+ pos.form=0;
+ gotoEntry(pos);
+}
+
+void KBabelView::gotoLast()
+{
+ DocPosition pos;
+ pos.item=_catalog->numberOfEntries()-1;
+ pos.form=0;
+ gotoEntry(pos);
+}
+
+void KBabelView::gotoNext()
+{
+ DocPosition pos;
+ pos.item=_currentIndex;
+ pos.form=msgstrEdit->currentForm();
+
+ if( (int)pos.form+1 < _catalog->defaultNumberOfPluralForms()
+ && _catalog->pluralForm(_currentIndex)==Gettext )
+ {
+ pos.form++;
+ }
+ else
+ {
+ // check, if we are already showing the last entry
+ if(_currentIndex>=_catalog->numberOfEntries()-1)
+ {
+ return;
+ }
+ else
+ {
+ pos.item++;
+ pos.form=0;
+ }
+ }
+
+ gotoEntry(pos);
+}
+
+void KBabelView::gotoPrev()
+{
+ DocPosition pos;
+ pos.item=_currentIndex;
+ pos.form=msgstrEdit->currentForm();
+ // check, if we are already showing the first entry
+ if(_currentIndex==0 && pos.form==0)
+ {
+ return;
+ }
+ else
+ {
+ if( pos.form==0 )
+ {
+ pos.item--;
+ if( _catalog->pluralForm(pos.item)==Gettext )
+ pos.form=_catalog->defaultNumberOfPluralForms()-1;
+ } else pos.form--;
+
+ gotoEntry(pos);
+ }
+
+}
+
+void KBabelView::gotoEntry()
+{
+ if( !_gotoDialog )
+ {
+ _gotoDialog = new GotoDialog(_catalog->numberOfEntries(),this);
+ }
+
+ _gotoDialog->exec();
+ if( _gotoDialog->result() )
+ {
+ int number=_gotoDialog->number()-1;
+ int max=_catalog->numberOfEntries()-1;
+
+ if(number>max)
+ number=max;
+ else
+ if(number<0)
+ number=0;
+
+ DocPosition pos;
+ pos.item=number;
+ pos.form=0;
+ gotoEntry(pos);
+ }
+
+}
+
+void KBabelView::gotoNextFuzzy()
+{
+ DocPosition pos;
+ if( _catalog->nextFuzzy(_currentIndex,pos) >= 0 )
+ {
+ gotoEntry(pos);
+ }
+}
+
+void KBabelView::gotoPrevFuzzy()
+{
+ DocPosition pos;
+ if( _catalog->prevFuzzy(_currentIndex,pos) >= 0 )
+ {
+ gotoEntry(pos);
+ }
+}
+
+void KBabelView::gotoNextError()
+{
+ DocPosition pos;
+ if(_catalog->nextError(_currentIndex,pos) >= 0 )
+ {
+ _dontBeep=true;
+ gotoEntry(pos);
+ _dontBeep=false;
+ }
+}
+
+void KBabelView::gotoPrevError()
+{
+ DocPosition pos;
+ if(_catalog->prevError(_currentIndex,pos) >= 0)
+ {
+ _dontBeep=true;
+ gotoEntry(pos);
+ _dontBeep=false;
+ }
+}
+
+void KBabelView::gotoNextFuzzyOrUntrans()
+{
+ DocPosition fuzzyPos,untransPos;
+
+ int fuzzyIndex=_catalog->nextFuzzy(_currentIndex,fuzzyPos);
+ int untransIndex=_catalog->nextUntranslated(_currentIndex,untransPos);
+
+ if(fuzzyIndex<0 && untransIndex<0 ) return;
+
+ if(fuzzyIndex<0)
+ {
+ gotoEntry(untransPos);
+ return;
+ }
+ if(untransIndex<0)
+ {
+ gotoEntry(fuzzyPos);
+ return;
+ }
+
+ if( fuzzyIndex<untransIndex
+ || (fuzzyIndex==untransIndex && fuzzyPos.form<untransPos.form))
+ {
+ gotoEntry(fuzzyPos);
+ }
+ else
+ {
+ gotoEntry(untransPos);
+ }
+}
+
+void KBabelView::gotoPrevFuzzyOrUntrans()
+{
+ DocPosition fuzzyPos,untransPos;
+
+ int fuzzyIndex=_catalog->prevFuzzy(_currentIndex,fuzzyPos);
+ int untransIndex=_catalog->prevUntranslated(_currentIndex,untransPos);
+
+ if(fuzzyIndex<0 && untransIndex<0 ) return;
+
+ if(fuzzyIndex<0)
+ {
+ gotoEntry(untransPos);
+ return;
+ }
+ if(untransIndex<0)
+ {
+ gotoEntry(fuzzyPos);
+ return;
+ }
+
+ if( fuzzyIndex>untransIndex
+ || (fuzzyIndex==untransIndex && fuzzyPos.form>untransPos.form))
+ {
+ gotoEntry(fuzzyPos);
+ }
+ else
+ {
+ gotoEntry(untransPos);
+ }
+}
+
+void KBabelView::gotoNextUntranslated()
+{
+ DocPosition pos;
+ if(_catalog->nextUntranslated(_currentIndex,pos)>=0)
+ {
+ gotoEntry(pos);
+ }
+}
+
+void KBabelView::gotoPrevUntranslated()
+{
+ DocPosition pos;
+ if(_catalog->prevUntranslated(_currentIndex,pos)>=0)
+ {
+ gotoEntry(pos);
+ }
+}
+
+
+void KBabelView::gotoEntry(const DocPosition& pos, bool updateHistory)
+{
+ // clear up statusbar
+ emit signalChangeStatusbar("");
+
+ if(updateHistory)
+ {
+ if(_forwardHistory.count()>0)
+ {
+ emit signalForwardHistory(false);
+ }
+ _forwardHistory.clear();
+ _backHistory.append(_currentIndex);
+
+ if(_backHistory.count()==1)
+ {
+ emit signalBackHistory(true);
+ }
+ else if(_backHistory.count()>MAX_HISTORY)
+ {
+ _backHistory.remove(_backHistory.begin());
+ }
+ }
+
+ informDictionary();
+
+ _currentPos=pos;
+ _currentIndex=pos.item;
+ updateEditor(pos.form,true);
+ emitEntryState();
+ updateTags();
+ updateArgs();
+}
+
+void KBabelView::msgstrPluralFormChanged ( uint index )
+{
+ _currentPos.form = index;
+ emit signalDisplayed (_currentPos);
+}
+
+void KBabelView::backHistory()
+{
+ if(_backHistory.isEmpty())
+ {
+ kdDebug(KBABEL) << "KBabelView::backHistory called without any history." << endl;
+ return;
+ }
+
+ _forwardHistory.append(_currentIndex);
+ uint index=_backHistory.last();
+ _backHistory.remove(_backHistory.fromLast());
+
+ DocPosition pos;
+ pos.item=index;
+ pos.form=0;
+ gotoEntry(pos,false);
+
+ if(_backHistory.count()==0)
+ {
+ emit signalBackHistory(false);
+ }
+ if(_forwardHistory.count()==1)
+ {
+ emit signalForwardHistory(true);
+ }
+}
+
+void KBabelView::forwardHistory()
+{
+ if(_forwardHistory.isEmpty())
+ {
+ kdDebug(KBABEL) << "KBabelView::forwardHistory called without any history." << endl;
+ return;
+ }
+
+ _backHistory.append(_currentIndex);
+ uint index=_forwardHistory.last();
+ _forwardHistory.remove(_forwardHistory.fromLast());
+
+ DocPosition pos;
+ pos.item=index;
+ pos.form=0;
+ gotoEntry(pos,false);
+
+ if(_forwardHistory.count()==0)
+ {
+ emit signalForwardHistory(false);
+ }
+ if(_backHistory.count()==1)
+ {
+ emit signalBackHistory(true);
+ }
+}
+
+void KBabelView::removeFuzzyStatus()
+{
+ bool newState = !_catalog->isFuzzy(_currentIndex);
+ _catalog->setFuzzy(_currentIndex,newState);
+
+ // ensure we will update the translation memory as needed
+ msgstrEdit->setModified (true);
+ emit signalFuzzyDisplayed(newState);
+}
+
+
+void KBabelView::editHeader()
+{
+ HeaderEditor* editor=_catalog->headerEditor();
+
+ int editHeight=editor->height();
+ int editWidth=editor->width();
+ int w=width();
+ int h=height();
+
+ int x=w/2-editWidth/2;
+ int y=h/2-editHeight/2;
+
+ editor->move(mapToGlobal(QPoint(x,y)));
+
+ editor->show();
+ editor->raise();
+
+}
+
+
+void KBabelView::stopSearch()
+{
+ dictBox->stopSearch();
+}
+
+void KBabelView::startSearch()
+{
+ startSearch(false);
+}
+
+void KBabelView::startSearch(bool delay)
+{
+ QString msg = _catalog->msgid(_currentIndex,true).first();
+ QRegExp reg=_catalog->miscSettings().contextInfo;
+ if(msg.contains(reg))
+ {
+ msg.replace(reg,"");
+ }
+
+ dictBox->setActiveModule(KBabelSettings::defaultModule());
+ if(delay)
+ {
+ dictBox->startDelayedSearch(msg);
+ }
+ else
+ {
+ dictBox->startSearch(msg);
+ }
+}
+
+void KBabelView::startSearch(const QString module)
+{
+ // FIXME: should care about plural forms
+ QString msg = _catalog->msgid(_currentIndex,true).first();
+ QRegExp reg=_catalog->miscSettings().contextInfo;
+ if(msg.contains(reg))
+ {
+ msg.replace(reg,"");
+ }
+
+ dictBox->setActiveModule(module);
+ dictBox->startSearch(msg);
+
+}
+
+void KBabelView::startSelectionSearch()
+{
+ startSelectionSearch(KBabelSettings::defaultModule());
+}
+
+void KBabelView::startSelectionSearch(const QString module)
+{
+ dictBox->setActiveModule(module);
+
+ if(msgidLabel->hasSelectedText())
+ {
+ // TODO: should we care about end of lines?
+ dictBox->startSearch(msgidLabel->selectedText());
+ }
+ else if(msgstrEdit->hasSelectedText())
+ {
+ dictBox->startTranslationSearch(msgstrEdit->selectedText());
+ }
+ else
+ {
+ // should care about plural forms
+ QString msg = _catalog->msgid(_currentIndex,true).first();
+ QRegExp reg=_catalog->miscSettings().contextInfo;
+ if(msg.contains(reg))
+ {
+ msg.replace(reg,"");
+ }
+
+ dictBox->startSearch(msg);
+ }
+}
+
+
+void KBabelView::emitEntryState()
+{
+ // flag, so I don't have to always change the color of the text
+ static bool isError=false;
+
+ emit signalDisplayed(_currentPos);
+
+ emit signalFirstDisplayed(_currentIndex==0, msgstrEdit->currentForm()==0);
+ emit signalLastDisplayed((unsigned)(_currentIndex+1)==_catalog->numberOfEntries(), (signed)(msgstrEdit->currentForm())==_catalog->numberOfPluralForms(_currentIndex)-1);
+
+ bool fuzzy=_catalog->isFuzzy(_currentIndex);
+ bool untrans=_catalog->isUntranslated(_currentIndex);
+ emit signalFuzzyDisplayed(fuzzy);
+ emit signalUntranslatedDisplayed(untrans);
+ emit signalFuzzyAfterwards(_catalog->hasFuzzyAfterwards(_currentIndex));
+ emit signalUntranslatedAfterwards(_catalog->hasUntranslatedAfterwards(_currentIndex));
+ emit signalFuzzyInFront(_catalog->hasFuzzyInFront(_currentIndex));
+ emit signalUntranslatedInFront(_catalog->hasUntranslatedInFront(_currentIndex));
+
+ emit signalErrorAfterwards(_catalog->hasErrorAfterwards(_currentIndex));
+ emit signalErrorInFront(_catalog->hasErrorInFront(_currentIndex));
+
+ DocPosition pos;
+ if( _catalog->hasError(_currentIndex,pos) != isError )
+ {
+ isError = !isError;
+
+ emit signalFaultyDisplayed(isError);
+
+ if(isError)
+ {
+ QPalette palette=msgstrEdit->palette();
+ palette.setColor( QColorGroup::Text, red );
+
+ if( _catalog->itemStatus(_currentIndex).contains("syntax error"))
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::ErrorColor );
+ }
+ else
+ if( !_catalog->itemStatus(_currentIndex).isEmpty() && KBabelSettings::autoCheckColorError())
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::ErrorColor );
+ }
+ }
+ else
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::NormalColor );
+ }
+ }
+
+}
+
+void KBabelView::checkFuzzies()
+{
+ emit signalFuzzyAfterwards(_catalog->hasFuzzyAfterwards(_currentIndex));
+ emit signalFuzzyInFront(_catalog->hasFuzzyInFront(_currentIndex));
+}
+
+void KBabelView::checkUntranslated()
+{
+ emit signalUntranslatedAfterwards(_catalog->hasUntranslatedAfterwards(_currentIndex));
+ emit signalUntranslatedInFront(_catalog->hasUntranslatedInFront(_currentIndex));
+}
+
+void KBabelView::autoRemoveFuzzyStatus()
+{
+ // only at first text change remove fuzzy status
+ disconnect(msgstrEdit,SIGNAL(textChanged()),this,SLOT(autoRemoveFuzzyStatus()));
+
+ //removeFuzzyStatus();
+}
+
+void KBabelView::toggleFuzzyLed(bool on)
+{
+ if(!_fuzzyLed)
+ return;
+
+ if(on)
+ {
+ if(_fuzzyLed->state()==KLed::Off)
+ {
+ _fuzzyLed->on();
+ }
+ }
+ else
+ {
+ if(_fuzzyLed->state()==KLed::On)
+ _fuzzyLed->off();
+ }
+}
+
+void KBabelView::toggleUntransLed(bool on)
+{
+ if(!_untransLed)
+ return;
+
+ if(on)
+ {
+ if(_untransLed->state()==KLed::Off)
+ _untransLed->on();
+ }
+ else
+ {
+ if(_untransLed->state()==KLed::On)
+ _untransLed->off();
+ }
+}
+
+void KBabelView::toggleErrorLed(bool on)
+{
+ if(!_errorLed)
+ return;
+
+ if(on)
+ {
+ if(_errorLed->state()==KLed::Off)
+ {
+ _errorLed->on();
+ }
+ }
+ else
+ {
+ if(_errorLed->state()==KLed::On)
+ _errorLed->off();
+ }
+}
+
+
+
+
+void KBabelView::showError(const QString& message)
+{
+ KMessageBox::error(this,message);
+}
+
+void KBabelView::dragEnterEvent(QDragEnterEvent *event)
+{
+ // accept uri drops only
+ event->accept(KURLDrag::canDecode(event));
+}
+
+void KBabelView::dropEvent(QDropEvent *event)
+{
+ KURL::List uri;
+
+ // see if we can decode a URI.. if not, just ignore it
+ if (KURLDrag::decode(event, uri))
+ {
+ processUriDrop(uri , mapToGlobal(event->pos()));
+ }
+}
+
+
+bool KBabelView::eventFilter( QObject* object, QEvent* event)
+{
+ if(event->type() == QEvent::DragEnter)
+ {
+ QDragEnterEvent* e = (QDragEnterEvent*) event;
+ if(KURLDrag::canDecode(e))
+ {
+ e->accept(true);
+ return true;
+ }
+ }
+ else if(event->type() == QEvent::Drop)
+ {
+ KURL::List uri;
+ // see if we can decode a URI.. if not, just ignore it
+ if (KURLDrag::decode((QDropEvent*)event, uri))
+ {
+ processUriDrop(uri ,( (QWidget*)object)->mapToGlobal( ( (QDropEvent*)event )->pos()));
+ return true;
+ }
+ }
+ else if(event->type() == QEvent::KeyPress)
+ {
+ // This is a little workaround to use CTRL+ALT+Home, CTRL+ALT+End, Undo keys
+ // to go to the first and the last entry. Because otherwise
+ // CTRL+Home and CTRL+End and Undo are caught by QTextEdit
+ QKeyEvent *ke = (QKeyEvent*)event;
+
+ if(ke->key() == Key_Home && ke->state() == (AltButton | ControlButton))
+ {
+ gotoFirst();
+ return true;
+ }
+ else if(ke->key() == Key_End
+ && ke->state() == (AltButton | ControlButton))
+ {
+ gotoLast();
+ return true;
+ }
+ else if( KShortcut(KKey(ke)) == KStdAccel::undo() )
+ {
+ undo();
+ return true;
+ }
+ else if( KShortcut(KKey(ke)) == KStdAccel::redo() )
+ {
+ redo();
+ return true;
+ }
+ else if( ke->key() == Key_Insert )
+ {
+ m_mainwindow->toggleEditMode();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void KBabelView::processUriDrop(KURL::List& uriList, const QPoint& pos)
+{
+ // if we have two entries, the chance is high, that it
+ // is a drag from the catalog manager
+ if(uriList.count() == 2)
+ {
+ int result = _dropMenu->exec(pos);
+ switch(result)
+ {
+ case ID_DROP_OPEN:
+ {
+ KURL first(uriList.first());
+ KURL second(uriList.last());
+
+ if( KIO::NetAccess::exists(first, true, this) )
+ {
+ open(first);
+ }
+ else
+ {
+ openTemplate(second,first);
+ }
+ break;
+ }
+ case ID_DROP_OPEN_TEMPLATE:
+ {
+ open(uriList.last());
+ break;
+ }
+ }
+ }
+ else
+ {
+ // okay, we have one URI.. process it
+ KURL url( uriList.first() );
+
+ // load in the file
+ open(url);
+ }
+}
+
+void KBabelView::forwardMsgstrEditCmd(EditCommand* cmd)
+{
+/*
+ if(cmd->terminator()!=0)
+ {
+ kdDebug(KBABEL) << QString::number(cmd->terminator()) << endl;
+ }
+ else
+ {
+ DelTextCmd* delcmd = (DelTextCmd*) cmd;
+ kdDebug(KBABEL) << QString::number(delcmd->offset)+":"+delcmd->str+"|" << endl;
+ }
+*/
+ bool fuzzyRemoved=false;
+ if(KBabelSettings::autoUnsetFuzzy() && _catalog->isFuzzy(_currentIndex) )
+ {
+ fuzzyRemoved=true;
+
+ _catalog->applyBeginCommand(_currentIndex,Msgstr,this);
+
+ removeFuzzyStatus();
+ }
+
+ cmd->setPart(Msgstr);
+ cmd->setIndex(_currentIndex);
+
+ bool wasUntranslated=_catalog->isUntranslated(_currentIndex);
+
+ _catalog->applyEditCommand(cmd,this);
+
+ if( fuzzyRemoved )
+ {
+ _catalog->applyEndCommand(_currentIndex,Msgstr,this);
+ }
+
+
+ bool isUntranslated=_catalog->isUntranslated(_currentIndex);
+
+ if(wasUntranslated && !isUntranslated)
+ emit signalUntranslatedDisplayed(false);
+ else if(!wasUntranslated && isUntranslated)
+ emit signalUntranslatedDisplayed(true);
+
+}
+
+void KBabelView::autoCheck()
+{
+ autoCheck(true);
+}
+
+
+void KBabelView::autoCheck(bool onlyWhenChanged)
+{
+ if( !_autocheckTools.isEmpty() )
+ {
+ QStringList oldStatus = _catalog->itemStatus(_currentIndex);
+
+ QStringList status = _catalog->itemStatus( _currentIndex,true, _autocheckTools );
+
+ // if there is more than one view, the status changes only in
+ // one view, so we have to update always.
+ if(_catalog->isLastView() && onlyWhenChanged && oldStatus == status)
+ return;
+
+ if( !status.isEmpty() )
+ {
+ QString msg = "";
+
+ // ### TODO: whynot use i18n("context",text) directly?
+ KLocale* locale=KGlobal::locale();
+
+ for( QStringList::iterator it=status.begin() ; it != status.end() ; ++it )
+ {
+ if( msg.isEmpty() ) msg = locale->translate("what check found errors",(*it).utf8());
+ else msg += ", "+locale->translate("what check found errors",(*it).utf8());
+ }
+
+ //i18n: translators: Status bar text that automatic checks have found some errors
+ emit signalChangeStatusbar(i18n("1 error: %1", "%n errors: %1", status.size ()).arg(msg));
+ emit signalFaultyDisplayed(true);
+
+ if(KBabelSettings::autoCheckColorError())
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::ErrorColor );
+ }
+
+ if(KBabelSettings::beepOnError() && !_dontBeep)
+ {
+ if(onlyWhenChanged)
+ {
+ if(oldStatus != status && oldStatus.isEmpty() )
+ {
+ KNotifyClient::beep();
+ }
+ }
+ else if(isActiveWindow())
+ {
+ KNotifyClient::beep();
+ }
+ }
+ }
+ else if( _catalog->itemStatus(_currentIndex).isEmpty() )
+ {
+ _catalog->removeFromErrorList(_currentIndex);
+
+ emit signalFaultyDisplayed(false);
+
+ if(KBabelSettings::autoCheckColorError())
+ {
+ msgstrEdit->setCurrentColor( MsgMultiLineEdit::NormalColor );
+ }
+ }
+ }
+}
+
+void KBabelView::spellcheckAll()
+{
+ spell.what2Check=All;
+ spellcheck();
+}
+
+void KBabelView::spellcheckAllMulti()
+{
+ spell.what2Check=AllMulti;
+ spellcheck();
+}
+
+
+void KBabelView::spellcheckFromCursor()
+{
+ spell.what2Check=End;
+ spellcheck();
+}
+
+
+void KBabelView::spellcheckCurrent()
+{
+ spell.what2Check=Current;
+ spellcheck();
+}
+
+void KBabelView::spellcheckFromCurrent()
+{
+ spell.what2Check=BeginCurrent;
+ spellcheck();
+}
+
+
+void KBabelView::spellcheckMarked()
+{
+ if(!msgstrEdit->hasSelectedText())
+ {
+ return;
+ }
+
+ spell.what2Check=Marked;
+ spellcheck();
+}
+
+
+void KBabelView::spellcheckCommon()
+{
+ SpellDlg *spellDlg = new SpellDlg(msgstrEdit->hasSelectedText(),this
+ ,"SpellDlg");
+
+ if(spellDlg->exec())
+ {
+ if(spellDlg->all())
+ spell.what2Check=All;
+ else if(spellDlg->current())
+ spell.what2Check=Current;
+ else if(spellDlg->begin())
+ spell.what2Check=Begin;
+ else if(spellDlg->end())
+ spell.what2Check=End;
+ else if(spellDlg->marked())
+ spell.what2Check=Marked;
+ else if(spellDlg->beginCurrent())
+ spell.what2Check=BeginCurrent;
+ else
+ {
+ kdError() << "unhandled option in spell dialog" << endl;
+ return;
+ }
+
+ spellcheck();
+ }
+
+ delete spellDlg;
+}
+
+void KBabelView::addSpellcheckWords( uint pos, QString text, uint index, uint form )
+{
+ // special format chars
+ QString spclChars="abfnrtv'\"?\\";
+ QChar accelMarker=_catalog->miscSettings().accelMarker;
+
+ uint textLength=text.length();
+ do
+ {
+ QString word="";
+ bool wordBegin=false;
+ while(!wordBegin && pos < textLength)
+ {
+ QChar c=text[pos];
+ if(c.isLetter() || c==accelMarker)
+ {
+ wordBegin=true;
+ }
+ else if( c == '\\')
+ {
+ if(pos+1 < textLength && spclChars.contains(text[pos+1]) )
+ {
+ pos+=2;
+ }
+ else
+ {
+ // consider it to be unnecessary escaped character
+ pos++;
+ }
+ }
+ else
+ {
+ pos++;
+ }
+ }
+ int begin=pos;
+
+ bool wordEnd=false;
+ while(!wordEnd && pos < textLength)
+ {
+ if(text[pos].isLetter() || text[pos]=='-' || (text[pos]=='\'' && !spell.config->dictionary().startsWith("malti")))
+ {
+ word+=text[pos];
+ pos++;
+ }
+ else if(text[pos]==accelMarker)
+ {
+ pos++;
+ }
+ else if(text[pos]=='\n')
+ {
+ // newline without \n counts as nothing
+ pos++;
+ }
+ else
+ {
+ wordEnd=true;
+ }
+ }
+
+ int end=pos;
+
+ // remove '-' and accelMarker at the end of a word
+ while(text[end]=='-' || (text[pos]=='\'' && !spell.config->dictionary().startsWith("malti"))
+ || text[end]==accelMarker)
+ {
+ end--;
+ word.truncate(word.length()-1);
+ }
+
+ if(!word.isEmpty())
+ {
+ spell.wordList.append(word);
+ Position *pos = new Position;
+ pos->index=index;
+ pos->form=form;
+ pos->pos=begin;
+ pos->end=end;
+ spell.posDict.append(pos);
+ }
+ }
+ while(pos < textLength);
+}
+
+void KBabelView::spellcheck()
+{
+ if(isReadOnly() || spell.active)
+ return;
+
+ spell.wordList.clear();
+ spell.posDict.clear();
+ spell.ignoreList.clear();
+ spell.newIgnoreList.clear();
+
+ spell.misspelled=0;
+ spell.replaced=0;
+ spell.lastIndex=0;
+ spell.posCorrection=0;
+ spell.lastPos=0;
+ spell.inWordCorrection=0;
+
+ if( !_spellcheckSettings.valid )
+ {
+ _spellcheckSettings = _project->spellcheckSettings();
+ }
+
+ spell.config = new KSpellConfig(this,"tempSpellConfig");
+ spell.config->setNoRootAffix(_spellcheckSettings.noRootAffix);
+ spell.config->setRunTogether(_spellcheckSettings.runTogether);
+ spell.config->setClient(_spellcheckSettings.spellClient);
+ spell.config->setEncoding(_spellcheckSettings.spellEncoding);
+ spell.config->setDictionary(_spellcheckSettings.spellDict);
+
+ if(spell.what2Check==Marked)
+ {
+ spell.lastIndex=_currentIndex;
+
+ _tagExtractor->setString(msgstrEdit->selectedText());
+ QString marked=_tagExtractor->plainString(true);
+
+ addSpellcheckWords(msgstrEdit->beginOfMarkedText(),marked
+ ,_currentIndex,msgstrEdit->currentForm());
+ }
+ else
+ {
+ uint first=0;
+ uint last=_catalog->numberOfEntries()-1;
+ QString text;
+
+ bool emitProgress=false;
+
+ if(spell.what2Check==All || spell.what2Check==Begin
+ || spell.what2Check==End || spell.what2Check==AllMulti
+ || spell.what2Check==BeginCurrent)
+ {
+ emitProgress=true;
+ }
+
+ if(spell.what2Check==Begin)
+ {
+ first=0;
+ last=_currentIndex-1;
+ }
+ else if(spell.what2Check==End)
+ {
+ first=_currentIndex+1;
+ last=_catalog->numberOfEntries()-1;
+
+ int pos=msgstrEdit->currentIndex();
+ int form=msgstrEdit->currentForm();
+
+ QStringList msgs = _catalog->msgstr(_currentIndex);
+ _tagExtractor->setString((*msgs.at(form)));
+ text=_tagExtractor->plainString(true);
+ addSpellcheckWords( pos, text, _currentIndex, form++ );
+
+ for( QStringList::Iterator i=msgs.at(form++) ; i!=msgs.end(); i++)
+ {
+ _tagExtractor->setString(*i);
+ text=_tagExtractor->plainString(true);
+ addSpellcheckWords( pos, text, _currentIndex, form++ );
+ }
+ }
+ else if(spell.what2Check==BeginCurrent)
+ {
+ first=_currentIndex;
+ last=_catalog->numberOfEntries()-1;
+ }
+ else if(spell.what2Check!=All && spell.what2Check!=AllMulti)
+ {
+ first=last=_currentIndex;
+ }
+
+ if(emitProgress)
+ {
+ emit signalResetProgressBar(i18n("Preparing spell check"),100);
+ kapp->processEvents(100);
+ }
+
+ uint total=last-first+1;
+ uint lastPercent=0;
+ for(uint i=first; i <= last; i++)
+ {
+ if(emitProgress && 100*i/ QMAX(total,1) > lastPercent)
+ {
+ lastPercent++;
+ emit signalProgress(lastPercent);
+
+ kapp->processEvents(100);
+ }
+
+ QStringList msgs=_catalog->msgstr(i);
+ uint formCounter=0;
+ for(QStringList::Iterator j=msgs.begin() ; j!=msgs.end() ; ++j)
+ {
+ _tagExtractor->setString(*j);
+ text=_tagExtractor->plainString(true);
+ addSpellcheckWords(0,text,i,formCounter++);
+ }
+ }
+
+ if(spell.what2Check==Begin)
+ {
+ int pos=msgstrEdit->currentIndex();
+ int form=msgstrEdit->currentForm();
+
+ QStringList msgs = _catalog->msgstr(_currentIndex);
+ _tagExtractor->setString((*msgs.at(form)).left(pos));
+ text=_tagExtractor->plainString(true);
+ addSpellcheckWords( 0, text, _currentIndex, form++ );
+
+ for( QStringList::Iterator i=msgs.at(form++) ; i!=msgs.end(); i++)
+ {
+ _tagExtractor->setString(*i);
+ text=_tagExtractor->plainString(true);
+ addSpellcheckWords( 0, text, _currentIndex, form++ );
+ }
+ }
+
+ if(emitProgress)
+ {
+ emit signalClearProgressBar();
+ }
+ }
+
+ if(!spell.wordList.isEmpty())
+ {
+ spell.active=true;
+ _dontBeep=true;
+
+ spell.kspell= new KSpell (this, i18n("Spellcheck"),
+ this, SLOT(spellStart(KSpell *)), spell.config, true, true);
+ if( spell.kspell->status() == KSpell::Error )
+ {
+ KMessageBox::error( this, i18n("KBabel cannot start spell checker. "
+ "Please verify your KDE installation.") );
+ return;
+ }
+
+ connect(spell.kspell, SIGNAL(death()),this, SLOT(spellCleanDone()));
+
+ connect(spell.kspell, SIGNAL(misspelling(const QString &, const QStringList &
+ , unsigned int)), this
+ , SLOT(spellMisspelled(const QString &, const QStringList &, unsigned int)));
+
+ connect(spell.kspell, SIGNAL(corrected(const QString &, const QString &, unsigned int))
+ , this, SLOT(spellCorrected(const QString &, const QString &, unsigned int)));
+
+ connect(spell.kspell,SIGNAL(ignoreall(const QString &))
+ , this, SLOT(spellAddIgnore(const QString &)));
+
+ connect(spell.kspell, SIGNAL(done(bool))
+ , this, SLOT(spellResult(bool)));
+
+ spell.kspell->setAutoDelete(true); // let KSpell handle delete
+ }
+ else
+ {
+ KMessageBox::information(this,i18n(
+ "No relevant text has been found for spell checking."));
+ }
+}
+
+void KBabelView::spellStart(KSpell *)
+{
+ // set ignored words
+ if(_spellcheckSettings.rememberIgnored)
+ {
+ QString urlString = _spellcheckSettings.ignoreURL;
+ if(urlString.contains("@PACKAGE@"))
+ {
+ urlString.replace("@PACKAGE@",_catalog->packageName());
+ }
+ // ### TODO: correctly set the URL; support for MostLocalURL
+ KURL url(urlString);
+ if(url.isLocalFile())
+ {
+ QFile file(url.path());
+ if(file.open(IO_ReadOnly))
+ {
+ QTextStream stream(&file);
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ QString contents = stream.read();
+ file.close();
+
+ spell.ignoreList = QStringList::split('\n',contents);
+ }
+ else if(file.exists())
+ {
+ KMessageBox::sorry(this,
+ i18n("Error opening the file that contains words "
+ "to ignore during spell checking:\n"
+ "%1").arg(file.name()));
+ }
+ }
+ else
+ {
+ KMessageBox::sorry(this,
+ i18n("Only local files are allowed for saving "
+ "ignored words to during spell checking:\n"
+ "%1").arg(urlString));
+ }
+
+ if(spell.ignoreList.count() > 0)
+ {
+ emit signalResetProgressBar(i18n("Preparing spell check"),100);
+ kapp->processEvents(100);
+
+ uint total = spell.ignoreList.count();
+ uint oldPercent=0;
+ uint counter=0;
+ QStringList::Iterator it;
+ for(it=spell.ignoreList.begin(); it != spell.ignoreList.end(); ++it)
+ {
+ counter++;
+ if(counter/total > oldPercent)
+ {
+ oldPercent++;
+ emit signalProgress(oldPercent);
+ kapp->processEvents(100);
+ }
+
+ spell.kspell->ignore(*it);
+ }
+
+ emit signalClearProgressBar();
+ }
+ }
+
+ spell.kspell->checkList(&spell.wordList);
+}
+
+
+bool KBabelView::markMisspelled(const QString &orig, unsigned int pos)
+{
+ Position *p = spell.posDict.at(pos);
+ if(!p)
+ {
+ kdError() << "not a valid position: " << pos << endl;
+ return false;
+ }
+
+ if(p->index != _currentIndex || (p->index==_currentIndex && p->form!=msgstrEdit->currentForm()))
+ {
+ DocPosition pos;
+ pos.item=p->index;
+ pos.form=p->form;
+ gotoEntry(pos);
+ }
+
+
+ if(p->index != spell.lastIndex)
+ {
+ spell.lastIndex=p->index;
+ spell.posCorrection=0;
+ }
+ if(pos != spell.lastPos)
+ {
+ spell.lastPos=pos;
+ spell.inWordCorrection=0;
+ }
+
+ int x=0;
+ int y=0;
+
+ int begin=p->pos+spell.posCorrection-spell.inWordCorrection;
+ int end=p->end+spell.posCorrection-spell.inWordCorrection;
+
+ // check if this is the correct word
+ QString text = *_catalog->msgstr(p->index).at(p->form);
+ text=text.mid(begin,end-begin);
+ QChar accelMarker=_catalog->miscSettings().accelMarker;
+
+ if(text.contains(accelMarker))
+ {
+ text.replace(accelMarker,"");
+ }
+ if(text.contains('\n'))
+ {
+ text.replace("\n","");
+ }
+
+ bool textOk=true;
+ if(text != orig)
+ {
+ // if text and orig are not the same,
+ // maybe it was a word with hyphens
+ int n=text.contains('-');
+ n+=text.contains('\'');
+ if( n > 0 )
+ {
+ // re-get the original text since we replace some things above
+ QString text = *_catalog->msgstr(p->index).at(p->form);
+ text=text.mid(begin,end-begin);
+
+ bool textFound=false;
+ int i = 0;
+ int e=-1;
+ while(!textFound && i <= n)
+ {
+ int lastPos=e+1;
+ e = text.find('-',lastPos);
+ int tmp = text.find('\'',lastPos);
+ if(e < 0 && tmp > 0)
+ {
+ e=tmp;
+ }
+ else if(e > 0 && tmp > 0 && tmp < e)
+ {
+ e=tmp;
+ }
+
+ if(e<0) e=text.length();
+
+ QString w=text.mid(lastPos,e-lastPos);
+ if(w.contains(accelMarker))
+ {
+ w.replace(accelMarker,"");
+ }
+ if(text.contains('\n'))
+ {
+ text.replace("\n","");
+ }
+ if( w == orig)
+ {
+ textFound=true;
+ end=begin+e;
+ begin=begin+lastPos;
+ }
+
+ i++;
+ }
+
+ if(!textFound)
+ {
+ textOk=false;
+ }
+ }
+ else
+ {
+ textOk=false;
+ }
+ }
+
+ int beginx, beginy;
+
+ msgstrEdit->offset2Pos(end,y,x);
+ msgstrEdit->offset2Pos(begin,beginy,beginx);
+ msgstrEdit->setSelection(beginy,beginx,y,x);
+
+ if(!textOk)
+ {
+ text = *_catalog->msgstr(p->index).at(p->form);
+ text=text.mid(begin,end-begin);
+ kdDebug(KBABEL) << "Sync error: given: " << orig << " have: " << text << endl;
+ cancelSpellcheck();
+
+ KMessageBox::error(this,i18n(
+ "There seems to be an error with the synchronization "
+ "of the spell checking process and KBabel.\n"
+ "Please check that you have set the correct settings for "
+ "your language for spell checking.\n"
+ "If you have, and this problem is reproducible, please "
+ "send a detailed bug report (your spell checking options, "
+ "what file you have checked and what to do to reproduce "
+ "the problem) by using Help->Report Bug..."));
+ }
+
+ return textOk;
+}
+
+void KBabelView::spellMisspelled(const QString &orig, const QStringList &, unsigned int pos)
+{
+ kdDebug(KBABEL) << "misspelled: " << orig << " pos: " << pos << endl;
+
+ spell.misspelled++;
+
+ markMisspelled(orig,pos);
+}
+
+void KBabelView::spellCorrected(const QString &orig, const QString &word, unsigned int pos)
+{
+ if(orig != word)
+ {
+ QString newWord(word);
+ kdDebug(KBABEL) << "corrected: " << orig << " " << newWord
+ << " pos: " << pos << endl;
+
+ if(spell.replaced==0)
+ {
+ // handle the spell check as one action
+ int index;
+ Position *p = spell.posDict.at(pos);
+ if(p)
+ {
+ index=p->index;
+ }
+ else
+ {
+ index=_currentIndex;
+ }
+
+ _catalog->applyBeginCommand(index,Msgstr,this);
+ }
+
+ spell.replaced++;
+
+
+ if(markMisspelled(orig,pos))
+ {
+ QString marked=msgstrEdit->selectedText();
+ spell.origWords.append(marked);
+
+ if(marked.contains("\n") && !newWord.contains('\n'))
+ {
+ QString s1=newWord;
+ s1.replace(" ","\n");
+
+ // if only a newline has been replaced with a white space
+ if(s1==marked)
+ {
+ newWord.replace(" "," \n");
+ }
+
+ }
+ // check if the old word had an accelerator. If yes and the new
+ // word has no accelerator, try to add the accelerator for
+ // the same char else add in at the same position
+ QChar accelMarker=_catalog->miscSettings().accelMarker;
+ if(marked.contains(accelMarker) && !newWord.contains(accelMarker))
+ {
+ int b=marked.find(accelMarker);
+ QChar accel=marked[b+1];
+ int nb=newWord.find(accel,0,false);
+ if(nb>=0)
+ {
+ newWord.insert(nb,accelMarker);
+ }
+ // if the new word does not contain the old accel char
+ // set the accelerator to the same position as the old
+ else
+ {
+ if((uint)b >= newWord.length())
+ b = 0;
+ newWord.insert(b,accelMarker);
+ }
+ }
+
+ spell.newWords.append(newWord);
+
+ msgstrEdit->cut();
+ int row=0;
+ int col=0;
+ msgstrEdit->getCursorPosition(&row,&col);
+ msgstrEdit->insertAt(newWord,row,col,true);
+
+ int newCorrection = newWord.length() - marked.length();
+ spell.posCorrection += newCorrection;
+ spell.inWordCorrection += newCorrection;
+
+ // now store the new position
+ Position *p = spell.posDict.at(pos);
+ if(p)
+ {
+ p->end=p->end+newCorrection;
+ }
+ }
+ }
+}
+
+
+void KBabelView::spellResult(bool flag)
+{
+ kdDebug(KBABEL) << "spellResult: " << flag << endl;
+
+
+ if(spell.replaced > 0)
+ {
+ // close the spell check action
+ _catalog->applyEndCommand(spell.lastIndex,Msgstr,this);
+ }
+
+
+ if(flag)
+ {
+ emit signalChangeStatusbar(i18n("Spellcheck: %n word replaced","Spellcheck: %n words replaced",spell.replaced));
+
+ if(spell.misspelled==0)
+ {
+ KMessageBox::information(this,i18n(
+ "Spellcheck successfully finished.\n"
+ "No misspelled words have been found."));
+ }
+ else if(spell.replaced > 0 && spell.what2Check!=Current
+ && spell.what2Check!=Marked)
+ {
+ QStringList list;
+ QStringList::Iterator origIt;
+ QStringList::Iterator newIt;
+ origIt=spell.origWords.begin();
+ newIt=spell.newWords.begin();
+
+ for(;origIt != spell.origWords.end()
+ && newIt != spell.newWords.end(); origIt++,newIt++)
+ {
+ list.append(*origIt+" -> "+*newIt);
+ }
+
+ }
+
+ if( spell.what2Check!=AllMulti && spell.misspelled!=0 )
+ KMessageBox::information(this,i18n("Spellcheck: %n word replaced","Spellcheck: %n words replaced",spell.replaced));
+
+ if(_spellcheckSettings.rememberIgnored)
+ {
+ if(spell.newIgnoreList.count() > 0)
+ {
+ KURL url(_spellcheckSettings.ignoreURL);
+ if(url.isLocalFile())
+ {
+ QFile file(url.path());
+ if(file.open(IO_WriteOnly|IO_Append))
+ {
+ QStringList::Iterator it;
+ QTextStream stream(&file);
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+
+ for(it=spell.newIgnoreList.begin();
+ it!=spell.newIgnoreList.end();
+ ++it)
+ {
+ stream << *it << "\n";
+ }
+
+ file.close();
+ }
+ }
+ else
+ {
+ kdDebug(KBABEL) << "only local files are supported for storing"
+ << "ignored words" << endl;
+ }
+ }
+ }
+ }
+ else
+ {
+ emit signalChangeStatusbar(i18n("Spellcheck canceled"));
+ if(spell.replaced > 0)
+ undo();
+ }
+
+ int s=spell.kspell->dlgResult();
+ spell.kspell->cleanUp();
+
+ emit signalSpellcheckDone(s);
+ QTimer::singleShot(0,this,SLOT(cleanUpSpellStruct()));
+}
+
+
+void KBabelView::spellCleanDone()
+{
+ kdDebug(KBABEL) << "spellCleanDone" << endl;
+
+ // if the pointer is cleared, you have finished correcly
+ if( !spell.kspell ) return;
+
+ KSpell::spellStatus status = spell.kspell->status();
+
+ if(status == KSpell::Error || status == KSpell::Crashed)
+ {
+ cleanUpSpellStruct();
+ }
+
+ if(status == KSpell::Error)
+ {
+ KMessageBox::sorry(this, i18n("The spell checker program could not be started.\n"
+ "Please make sure you have the spell checker program properly "
+ "configured and in your PATH."));
+ }
+ else if(status == KSpell::Crashed)
+ {
+ KMessageBox::sorry(this, i18n("The spell checker program seems to have crashed."));
+ }
+}
+
+void KBabelView::cleanUpSpellStruct()
+{
+ kdDebug(KBABEL) << "Cleaning structure" << endl;
+ // spell.kspell is set to be autodeleted
+ spell.kspell = 0;
+ delete spell.config;
+ spell.config=0;
+ spell.wordList.clear();
+ spell.posDict.clear();
+ spell.origWords.clear();
+ spell.newWords.clear();
+ spell.ignoreList.clear();
+ spell.newIgnoreList.clear();
+ spell.active = false;
+ _dontBeep=false;
+}
+
+void KBabelView::cancelSpellcheck()
+{
+ spell.active=false;
+}
+
+void KBabelView::spellAddIgnore(const QString &word)
+{
+ if(!spell.ignoreList.contains(word))
+ {
+ spell.newIgnoreList.append(word);
+ }
+}
+
+void KBabelView::forwardSearchStart()
+{
+ emit signalResetProgressBar(i18n("Searching"),100);
+ emit signalSearchActive(true);
+}
+
+void KBabelView::forwardSearchStop()
+{
+ emit signalClearProgressBar();
+ emit signalSearchActive(false);
+}
+
+void KBabelView::forwardProgressStart(const QString& msg)
+{
+ emit signalResetProgressBar(msg,100);
+}
+
+void KBabelView::slotAutoSaveTimeout( )
+{
+ if ( isModified( ) )
+ {
+ autoSaveTimer->stop( );
+ saveFile( false );
+ autoSaveTimer->start( 1000 * 60 * _autoSaveDelay );
+ }
+}
+
+void KBabelView::useProject (Project::Ptr project)
+{
+ // FIXME: close the current project first
+ disconnect (_project, SIGNAL(signalSpellcheckSettingsChanged()),
+ this, SLOT(updateProjectSettings()));
+
+ _project = project;
+ _catalog->useProject(_project);
+
+ readProject(_project);
+
+ connect (project, SIGNAL(signalSpellcheckSettingsChanged()),
+ this, SLOT(updateProjectSettings()));
+}
+
+#include "kbabelview.moc"
diff --git a/kbabel/kbabel/kbabelview.h b/kbabel/kbabel/kbabelview.h
new file mode 100644
index 00000000..a52ed4dc
--- /dev/null
+++ b/kbabel/kbabel/kbabelview.h
@@ -0,0 +1,712 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBABELVIEW_H
+#define KBABELVIEW_H
+
+class HidingMsgEdit;
+class MsgMultiLineEdit;
+class GotoDialog;
+class QPopupMenu;
+class KLed;
+class FindDialog;
+class ReplaceDialog;
+
+namespace KBabel
+{
+ class EditCommand;
+ class RegExpExtractor;
+ class FindOptions;
+ class ReplaceOptions;
+}
+
+class QListBoxItem;
+class QTextView;
+class QTabWidget;
+class KListBox;
+class KSpell;
+class KSpellConfig;
+class KBabelDictBox;
+class KDataToolInfo;
+struct ReplaceOptions;
+struct ModuleInfo;
+
+#include <kdockwidget.h>
+#include <kurl.h>
+#include <kconfig.h>
+#include <qwidget.h>
+#include <qstrlist.h>
+#include <resources.h>
+
+#include <catalogview.h>
+#include "kbcatalog.h"
+#include "kbproject.h"
+#include "projectsettings.h"
+
+class KBabelMW;
+class CommentView;
+class ContextView;
+class KBCatalogListView;
+class CharacterSelectorView;
+class SourceView;
+class TagListView;
+
+/**
+ * This is the main view class for KBabel. Most of the non-menu,
+ * non-toolbar, and non-statusbar (e.g., non frame) GUI code should go
+ * here.
+ * @short Main view
+ * @author Matthias Kiefer <matthias.kiefer@gmx.de>
+ * @version 0.1
+ */
+class KBabelView : public QWidget, public KBabel::CatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ * @param buildLeds flag, if status leds should be created in editor
+ */
+ KBabelView(KBCatalog* catalog,KBabelMW *parent, KBabel::Project::Ptr project);
+
+ /**
+ * Destructor
+ */
+ virtual ~KBabelView();
+
+ /**
+ * @return the view, that has opened file url or 0 if this
+ * file is not opened
+ */
+ static KBabelView *viewForURL(const KURL& url, const QString project);
+
+ /**
+ * @return the view, that has no opened file url or 0 if there
+ * is no such view
+ */
+ static KBabelView *emptyView(const QString project);
+
+ KURL currentURL() const;
+ QString project() const { return _project->filename(); }
+ void useProject (KBabel::Project::Ptr project);
+
+ bool isLastView() const;
+ bool isModified() const;
+ /** the edit mode of the entry-editors*/
+ bool isOverwriteMode() const;
+ bool isReadOnly() const;
+ /** the edit mode of the entry-editors*/
+ void setOverwriteMode(bool ovr);
+ bool isSearching() const;
+
+ void saveView(KConfig *config);
+ void restoreView(KConfig *config);
+ void saveSession(KConfig*);
+ void restoreSession(KConfig*);
+
+ void readSettings(KConfig* config);
+ void saveSettings();
+
+ void readProject(KBabel::Project::Ptr project);
+ void saveProject(KConfig* config);
+
+ void openTemplate(const KURL& openURL, const KURL& saveURL);
+ bool saveFile(bool checkSyntax=true);
+ bool saveFileAs(KURL url = KURL(), bool checkSyntax=true);
+ bool saveFileSpecial();
+
+ /**
+ * Checks, if the file has been modified. If true, it askes the user if he wants
+ * to save, discard or cancel. If the users chose save, it saves the file.
+ * @return true, if it is allowed to open a new file. false, if the user wants
+ * to edit the file again.
+ */
+ bool checkModified();
+
+
+ /**
+ * Checks syntax of the current catalog. If the catalog is modified it
+ * saves it under a temporary filename ( using @ref Catalog::saveTempFile ).
+ *
+ * @param msgOnlyAtError flag, if a message should be shown, only if
+ * a error occured.
+ * @param question flag, if only a information about the result should
+ * be shown or a question, whether the user wants to continue or cancel
+ *
+ * @return true, if no error occured or if an error occured but the user
+ * wants to continue anyway.
+ */
+ bool checkSyntax(bool msgOnlyAtError, bool question);
+
+ /**
+ * this is called from the catalog when updating his views.
+ * reimplemented from @ref CatalogView
+ * @param cmd the edit command that has been applied
+ */
+ virtual void update(KBabel::EditCommand* cmd, bool undo=false);
+
+ KBCatalog* catalog() const{return _catalog;}
+
+ void processUriDrop(KURL::List& uriList, const QPoint & pos);
+
+ /**
+ * checks the status of the displayed entry: last, first, fuzzy,...
+ * and emits the appropriate signals
+ */
+ void emitEntryState();
+
+ void setRMBEditMenu(QPopupMenu*);
+ void setRMBSearchMenu(QPopupMenu*);
+ void setTagsMenu(QPopupMenu*);
+ void setArgsMenu(QPopupMenu*);
+
+ QPtrList<ModuleInfo> dictionaries();
+ KBabelDictBox* searchView() { return dictBox; }
+
+ bool autoDiffEnabled() const {return _diffEnabled;}
+
+public slots:
+
+ void gotoEntry(const KBabel::DocPosition& pos, bool updateHistory=true);
+
+ /** opens a filedialog and asks for an url */
+ void open();
+ void open(const KURL& url, const QString & package=QString::null, bool checkModified=true, bool newView=false);
+ void setFilePackage();
+ void revertToSaved();
+
+ void updateSettings();
+ void updateProjectSettings();
+
+ void undo();
+ void redo();
+ void textCut();
+ void textCopy();
+ void textPaste();
+ bool findNext();
+ bool findPrev();
+ void find();
+ void findInFile(QCString fileSource, KBabel::FindOptions options);
+ void replaceInFile(QCString fileSource, KBabel::ReplaceOptions options);
+ void replace();
+ void selectAll();
+ void deselectAll();
+ void clear();
+ void msgid2msgstr();
+ void search2msgstr();
+ void plural2msgstr();
+ void gotoFirst();
+ void gotoLast();
+ void gotoNext();
+ void gotoPrev();
+ void gotoEntry();
+ void gotoNextFuzzyOrUntrans();
+ void gotoPrevFuzzyOrUntrans();
+ void gotoNextFuzzy();
+ void gotoPrevFuzzy();
+ void gotoNextUntranslated();
+ void gotoPrevUntranslated();
+ void gotoNextError();
+ void gotoPrevError();
+
+ void forwardHistory();
+ void backHistory();
+
+ void spellcheckAll();
+ void spellcheckAllMulti();
+ void spellcheckFromCursor();
+ void spellcheckCurrent();
+ void spellcheckFromCurrent();
+ void spellcheckMarked();
+ void spellcheckCommon();
+
+ void roughTranslation();
+ void diff();
+ void toggleAutoDiff(bool on);
+ void diffShowOrig();
+ bool openDiffFile();
+ void insertNextTag();
+ void insertNextTagMsgid();
+ void insertNextArg();
+ void insertTagFromTool( const QString& tag );
+ void showTagsMenu();
+ void showArgsMenu();
+ void skipToNextTag();
+ void skipToPreviousTag();
+ void skipToTagFromTool(int index);
+ void wordCount();
+
+ void removeFuzzyStatus();
+ /** opens the header editor for the po-file */
+ void editHeader();
+
+ /** checks the syntax of the file by using msgftm */
+ bool checkSyntax();
+
+ /**
+ * perform all checks listed above
+ */
+ bool checkAll();
+
+ void stopSearch();
+ void startSearch();
+ void startSelectionSearch();
+ void startSearch(const QString id);
+ void startSelectionSearch(const QString id);
+
+ void configureDictionary(const QString id);
+ void editDictionary(const QString id);
+ void aboutDictionary(const QString id);
+
+ /**
+ * this was originally protected, but we need this to expose for
+ * KBabelMW forwarding
+ */
+ virtual void wheelEvent(QWheelEvent*);
+
+protected:
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual bool eventFilter(QObject*, QEvent* event);
+
+signals:
+ /** emited when a fuzzy catalogentry is shown */
+ void signalFuzzyDisplayed(bool);
+ /** emited when a untranslated catalogentry is shown */
+ void signalUntranslatedDisplayed(bool);
+ void signalFaultyDisplayed(bool);
+ /** emited when the first catalogentry is shown */
+ void signalFirstDisplayed(bool firstEntry, bool firstForm);
+ /** emited when the last catalog entry is shown */
+ void signalLastDisplayed(bool lastEntry, bool lastForm);
+
+ void signalNextTag( int index );
+
+ /**
+ * emited when a new entry is shown
+ * pos: position (index and plural form) of the currently shown entry
+ */
+ void signalDisplayed(const KBabel::DocPosition& pos);
+
+ /**
+ * emited when new entry is displayed and there is no
+ * fuzzy entry afterwards in the catalog
+ */
+ void signalFuzzyAfterwards(bool);
+ /**
+ * emited when new entry is displayed and there is no
+ * fuzzy entry in front of it in the catalog
+ */
+ void signalFuzzyInFront(bool);
+ /**
+ * emited when new entry is displayed and there is no
+ * untranslated entry afterwards in the catalog
+ */
+ void signalUntranslatedAfterwards(bool);
+ /**
+ * emited when new entry is displayed and there is no
+ * fuzzy entry in fornt of it in the catalog
+ */
+ void signalUntranslatedInFront(bool);
+
+ void signalErrorAfterwards(bool);
+ void signalErrorInFront(bool);
+
+ /**
+ * Use this signal to change the content of the statusbar
+ */
+ void signalChangeStatusbar(const QString& text);
+ /**
+ * Use this signal to change the content of the caption
+ */
+ void signalChangeCaption(const QString& text);
+
+ void signalNewFileOpened(KURL url);
+
+ void signalResetProgressBar(QString,int);
+ void signalProgress(int);
+ void signalClearProgressBar();
+
+ void signalSearchActive(bool);
+
+ void signalDiffEnabled(bool);
+
+ void signalForwardHistory(bool have);
+ void signalBackHistory(bool have);
+
+ void ledColorChanged(const QColor& color);
+
+ void signalDictionariesChanged();
+
+ void signalMsgstrChanged();
+
+ void signalNextTagAvailable(bool);
+ void signalTagsAvailable(bool);
+
+ void signalNextArgAvailable(bool);
+ void signalArgsAvailable(bool);
+
+ void signalCursorPosChanged(int line, int col);
+
+ void signalSpellcheckDone(int result);
+
+ void signalCopy();
+ void signalCut();
+ void signalPaste();
+ void signalSelectAll();
+
+private:
+ /**
+ * inserts the content of the current catalog entry into
+ * the fields in the view
+ * @param delay flag, if the auto search should be started delayed
+ * this is useful when a new file is opened
+ * @param formID number of the plural form to be displayed. Use 0 for
+ * no plural form
+ */
+ void updateEditor(int formID=0, bool delay=false);
+
+ void initDockWidgets();
+
+ void startSearch(bool delay);
+
+ /**
+ * makes some checks like checkings arguments and accels etc
+ * @param onlyWhenChanged flag, if message should only be shown
+ * when status changed
+ */
+ void autoCheck(bool onlyWhenChanged);
+
+ /**
+ * Create instances of tools currently setup for autochecks
+ */
+ void setupAutoCheckTools();
+
+ /**
+ * internal function to find next string given with @ref FindDialog
+ * starting at position pos
+ * @return true, if search was successful
+ */
+ bool findNext_internal(KBabel::DocPosition& pos, bool forReplace=false, bool mark=true);
+ /**
+ * internal function to find previous string given with @ref FindDialog
+ * starting at position pos
+ * @return true, if search was successful
+ */
+ bool findPrev_internal(KBabel::DocPosition& pos, bool forReplace=false, bool mark=true);
+
+ /**
+ * makes the real work
+ * @param autoDiff flag, if called from @ref autoDiff()
+ */
+ void diffInternal(bool autoDiff);
+
+ /**
+ * @param autoDiff flag, if called from @ref autoDiff()
+ */
+ bool openDiffFile(bool autoDiff);
+
+ /**
+ * Inserts a text into the msgstr (into the current form) using undoable commands.
+ * if @param clearFirst is set to true, it will clear the contents of msgstr before inserting
+ */
+ void modifyMsgstrText(const uint offset, const QString& text, bool clearFirst=false);
+
+protected slots:
+ bool validateUsingTool( const KDataToolInfo & info, const QString & command );
+ void modifyUsingTool( const KDataToolInfo & info, const QString & command );
+ void modifyCatalogUsingTool( const KDataToolInfo & info, const QString & command );
+
+private slots:
+ void msgstrPluralFormChanged (uint index);
+ void autoRemoveFuzzyStatus();
+
+ /** connected to the catalog. it is called when a new file is opened*/
+ void newFileOpened(bool readOnly);
+
+ void showError(const QString& message);
+
+ void toggleFuzzyLed(bool on);
+ void toggleUntransLed(bool on);
+ void toggleErrorLed(bool on);
+
+ void forwardMsgstrEditCmd(KBabel::EditCommand*);
+
+ /**
+ * called from a signal from ReplaceDialog to replace the
+ * current found string. After that it searches the next string
+ */
+ void replaceNext();
+ /**
+ * called from a signal from ReplaceDialog to replace
+ * all without asking anymore.
+ */
+ void replaceAll();
+ /**
+ * called from a signal from ReplaceDialog to go to next
+ * string to replace
+ */
+ void findNextReplace();
+
+ /**
+ * makes some checks like checkings arguments and accels etc
+ */
+ void autoCheck();
+
+ void autoDiff();
+
+ /**
+ * called, when text in msgstrEdit changes to inform
+ * the dictionary about the changes
+ */
+ void informDictionary();
+ void setNewLanguage();
+
+ void forwardProgressStart(const QString& msg);
+ void forwardSearchStart();
+ void forwardSearchStop();
+
+ /**
+ * checks if there is are fuzzy entries in front or behind
+ * the current entry and emits the appropriate signals
+ */
+ void checkFuzzies();
+ /**
+ * checks if there is are untranslated entries in front or behind
+ * the current entry and emits the appropriate signals
+ */
+ void checkUntranslated();
+
+ /** inserts the nth tag from the available tags into msgstr*/
+ void insertTag(int n);
+
+ /** visually display the tag to be inserted next */
+ void selectTag();
+
+ void updateTags();
+
+ /** inserts the nth argument from the available arguments into msgstr*/
+ void insertArg(int n);
+
+ void updateArgs();
+ void insertChar(QChar ch);
+
+ void showTryLaterMessageBox();
+
+ void dummy(KSpell*) {}
+
+private:
+ static QPtrList<KBabelView> *viewList;
+
+ HidingMsgEdit* msgstrEdit;
+ HidingMsgEdit* msgidLabel;
+ KBabelDictBox* dictBox;
+ GotoDialog* _gotoDialog;
+ FindDialog* _findDialog;
+ FindDialog* _replaceDialog;
+ ReplaceDialog* _replaceAskDialog;
+
+ QPopupMenu* _dropMenu;
+
+ KLed* _fuzzyLed;
+ KLed* _untransLed;
+ KLed* _errorLed;
+
+ KBCatalog* _catalog;
+ uint _currentIndex;
+ KBabel::DocPosition _currentPos;
+
+ KBabel::SpellcheckSettings _spellcheckSettings;
+
+ bool _autoSearchTempDisabled;
+
+ QValueList<uint> _backHistory;
+ QValueList<uint> _forwardHistory;
+
+ // flag to not beep, when switching to the next entry, because
+ // go -> next or prev entry was used.
+ bool _dontBeep;
+
+ /**
+ * position in document were find or replace function
+ * started to search
+ */
+ KBabel::DocPosition _findStartPos;
+ /**
+ * the string that was marked during the last search
+ */
+ QString _lastFoundString;
+
+ /*
+ * flag, if internal find functions should break at end or ask for
+ * beginning at the other end of the document
+ */
+ bool _findBreakAtEnd;
+
+ /*
+ * flag, if we search backwards and the direction was already
+ * changed (see findNext and findPrev)
+ */
+ bool _redirectedBackSearch;
+
+ bool _showTryLaterBox;
+
+ KBabel::DocPosition _replacePos;
+ int _replaceLen;
+ int _replacesTotal;
+ bool _replaceWasAtEnd;
+ /** contains the diff to the offset, where we started to search */
+ int _replaceExtraOffset;
+
+ /** appId for a source of the next files to be searched */
+ QCString _fileSource;
+
+ QStringList _tags;
+ QPopupMenu *_tagsMenu;
+
+ QStringList _args;
+ QPopupMenu *_argsMenu;
+
+ bool _diffEnabled;
+ bool _loadingDiffFile;
+ bool _diffing;
+
+ /*
+ * flag, set if editing KDE documentation PO-file
+ */
+ bool _editingDocumentation;
+ QPtrList<KDataTool> _autocheckTools;
+
+//spellcheck things
+private:
+ struct Position
+ {
+ uint index;
+ uint form;
+ uint pos;
+ uint end;
+ };
+
+ enum SpellWhat{All,AllMulti,Current,Marked,Begin,End,BeginCurrent};
+
+ struct
+ {
+ KSpell *kspell;
+ KSpellConfig* config;
+ QStringList wordList;
+ bool active;
+ int misspelled;
+ int replaced;
+ int posCorrection;
+ uint lastIndex;
+ QPtrList<Position> posDict;
+ SpellWhat what2Check;
+
+ // the last word, that was misspelled
+ uint lastPos;
+ // the position correction in the last word.
+ // needed if words with '-' are treated as seperate words
+ int inWordCorrection;
+
+ QStringList origWords;
+ QStringList newWords;
+
+ QStringList ignoreList;
+ QStringList newIgnoreList;
+ } spell;
+
+ struct {
+ KSpell *kspell;
+ KSpellConfig* config;
+ } spell2; // on-the-fly spellchecking
+
+ //DictSpellChecker * flyspell;
+
+
+ /**
+ * Marks a misspelled word in the editor.
+ * After that, the cursor is at the beginning of the
+ * marked text
+ * @param orig the original word as given from KSpell
+ * @param pos the position of the word in the StringList
+ * spell.wordList
+ *
+ * @returns false, if the there is a synchronization error,
+ * means the word has not been found in the editor.
+ */
+ bool markMisspelled(const QString &orig, unsigned int pos);
+
+private slots:
+ void spellcheck();
+ void cancelSpellcheck();
+ void spellStart(KSpell*);
+ void spellMisspelled(const QString &orig, const QStringList &sug, unsigned int pos);
+ void spellCorrected(const QString &orig, const QString &newWord, unsigned int pos);
+ void spellResult(bool);
+ void spellCleanDone();
+ void spellAddIgnore(const QString &);
+ // initialize spellchecking struct
+ void cleanUpSpellStruct();
+ void slotAutoSaveTimeout( );
+
+private:
+ void addSpellcheckWords(uint pos, QString text, uint index, uint form);
+
+private:
+ // configuration file
+ KSharedConfig::Ptr _config;
+ // project file
+ KBabel::Project::Ptr _project;
+
+ KBabel::RegExpExtractor* _tagExtractor;
+ KBabel::RegExpExtractor* _argExtractor;
+
+ QTimer * autoSaveTimer;
+ int _autoSaveDelay;
+
+ int _currentTag;
+
+ KBabelMW* m_mainwindow;
+ CommentView* m_commentview;
+ ContextView* m_contextview;
+ KBCatalogListView* m_cataloglistview;
+
+ CharacterSelectorView* m_charselectorview;
+ TagListView* m_taglistview;
+ SourceView* m_sourceview;
+
+ bool m_overwrite;
+};
+
+#endif // KBABELVIEW_H
diff --git a/kbabel/kbabel/kbabelview2.cpp b/kbabel/kbabel/kbabelview2.cpp
new file mode 100644
index 00000000..c07990d0
--- /dev/null
+++ b/kbabel/kbabel/kbabelview2.cpp
@@ -0,0 +1,1025 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include <kdatatool.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <knotifyclient.h>
+#include <kurl.h>
+#include <kio/netaccess.h>
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qvbox.h>
+
+#include "catalogsettings.h"
+#include "editcmd.h"
+#include "tagextractor.h"
+#include "kbabelview.h"
+#include "kbabeldictbox.h"
+#include "mymultilineedit.h"
+#include "hidingmsgedit.h"
+#include "roughtransdlg.h"
+#include "kbabelsettings.h"
+#include "kbprojectsettings.h"
+
+#include "resources.h"
+
+using namespace KBabel;
+
+QPtrList<ModuleInfo> KBabelView::dictionaries()
+{
+ QPtrList<ModuleInfo> list = dictBox->moduleInfos();
+
+ return list;
+}
+
+void KBabelView::configureDictionary(const QString id)
+{
+ dictBox->configure(id);
+}
+
+void KBabelView::editDictionary(const QString id)
+{
+ dictBox->edit(id);
+}
+
+
+void KBabelView::aboutDictionary(const QString id)
+{
+ dictBox->aboutModule(id);
+}
+
+void KBabelView::informDictionary()
+{
+ if( isSearching () )
+ stopSearch ();
+
+ if( msgstrEdit->isModified() )
+ dictBox->setTextChanged(_catalog->msgid(_currentIndex,true)
+ ,*(_catalog->msgstr(_currentIndex).at(msgstrEdit->currentForm()))
+ ,msgstrEdit->currentForm()
+ ,_catalog->comment(_currentIndex));
+}
+
+void KBabelView::setNewLanguage()
+{
+ IdentitySettings s = _catalog->identitySettings();
+
+ dictBox->setLanguage(s.languageCode, s.languageName);
+
+ // setup new plural form number
+ int form = msgstrEdit->currentForm();
+ if( form >= s.numberOfPluralForms )
+ form = s.numberOfPluralForms-1;
+
+ msgstrEdit->setNumberOfPlurals (s.numberOfPluralForms);
+ updateSettings();
+
+ if (! _catalog->currentURL().isEmpty())
+ {
+ updateEditor( form );
+ }
+}
+
+
+void KBabelView::wheelEvent(QWheelEvent *e)
+{
+ if( _catalog->numberOfEntries() == 0 ) return;
+
+ if( (e->state() & ControlButton) && (e->state() & AltButton))
+ {
+ if(e->delta() > 0)
+ {
+ gotoPrevFuzzyOrUntrans();
+ }
+ else
+ {
+ gotoNextFuzzyOrUntrans();
+ }
+ }
+ else if(e->state() & ControlButton)
+ {
+ if(e->delta() > 0)
+ {
+ gotoPrevFuzzy();
+ }
+ else
+ {
+ gotoNextFuzzy();
+ }
+ }
+ else if(e->state() & AltButton)
+ {
+ if(e->delta() > 0)
+ {
+ gotoPrevUntranslated();
+ }
+ else
+ {
+ gotoNextUntranslated();
+ }
+ }
+ else
+ {
+ if(e->delta() > 0)
+ {
+ gotoPrev();
+ }
+ else
+ {
+ gotoNext();
+ }
+ }
+
+ e->accept();
+}
+
+
+
+void KBabelView::roughTranslation()
+{
+ RoughTransDlg *dlg = new RoughTransDlg(dictBox, _catalog, this
+ , "roughtransDlg");
+
+ dlg->exec();
+
+ delete dlg;
+}
+
+
+void KBabelView::updateTags()
+{
+ bool hadTags = _tags.count() > 0;
+
+ _tags = _catalog->tagList(_currentIndex);
+
+ if(_tagsMenu)
+ {
+ _tagsMenu->clear();
+
+ QStringList tList;
+ QStringList::Iterator it;
+ int counter=0;
+ for(it=_tags.begin(); it!=_tags.end(); ++it)
+ {
+ QString s = *it;
+ if( s.startsWith("&") ) s = "&"+s;
+ if(!tList.contains(s))
+ {
+ _tagsMenu->insertItem(s,counter);
+ tList.append(s);
+ }
+ counter++;
+ }
+ }
+
+ bool haveTags = (_tags.count() > 0);
+
+ if(isReadOnly())
+ haveTags=false;
+
+ if(haveTags != hadTags)
+ {
+ emit signalNextTagAvailable(haveTags);
+ emit signalTagsAvailable(haveTags);
+ }
+
+ _currentTag = 0;
+
+ if(haveTags)
+ {
+ _tagExtractor->setString(_catalog->msgid(_currentIndex).first());
+ }
+ // if there is no tag, it will set invalid tag
+ selectTag();
+}
+
+void KBabelView::skipToNextTag()
+{
+ if( (uint)_currentTag >= _tags.count()-1 ) return;
+ ++_currentTag;
+ selectTag();
+}
+
+void KBabelView::skipToPreviousTag()
+{
+ if( _currentTag == 0 ) return;
+ --_currentTag;
+ selectTag();
+}
+
+void KBabelView::selectTag()
+{
+ if( _tagExtractor->countMatches() == 0 ) {
+ // no tags, select none
+ kdDebug() << "No tags" << endl;
+ msgidLabel->selectTag(0,0);
+ return;
+ }
+
+ // count number of eofs in tag
+ uint diff=0;
+ // FIXME: what about plural forms
+ QString msgid = _catalog->msgid(_currentIndex).first();
+
+ for( uint i = _tagExtractor->matchIndex(_currentTag); i < _tagExtractor->matchIndex(_currentTag)+_tags[_currentTag].length()+1; i++ )
+ {
+ if( msgid[i] == '\n' ) diff++;
+ }
+ msgidLabel->selectTag(_tagExtractor->matchIndex(_currentTag),_tags[_currentTag].length()+diff);
+ emit signalNextTag (_currentTag);
+}
+
+void KBabelView::setTagsMenu(QPopupMenu *menu)
+{
+ _tagsMenu=menu;
+
+ connect(_tagsMenu,SIGNAL(activated(int)),this,SLOT(insertTag(int)));
+}
+
+void KBabelView::modifyMsgstrText(const uint offset, const QString& text, bool clearFirst)
+{
+ _catalog->applyBeginCommand( _currentIndex, Msgstr ,this);
+
+ if( clearFirst ) msgstrEdit->clear();
+
+ InsTextCmd* insCmd = new InsTextCmd(offset,text,msgstrEdit->currentForm());
+ insCmd->setPart(Msgstr);
+ insCmd->setIndex(_currentIndex);
+
+ msgstrEdit->processCommand(insCmd,false);
+ forwardMsgstrEditCmd(insCmd);
+
+ _catalog->applyEndCommand(_currentIndex, Msgstr,this);
+
+ autoCheck( true ); // check it NOW - it should not be needed, but it is, I don't know why :-(
+}
+
+void KBabelView::insertTag(int n)
+{
+ QString tag = _tagsMenu->text(n);
+ if( tag.startsWith( "&&" ) ) tag = tag.remove(0,1); // replace && -> &. && is used for correct menu display
+
+ modifyMsgstrText( msgstrEdit->currentIndex(), tag );
+}
+
+void KBabelView::insertNextTag()
+{
+ if(_currentTag >= (int)_tags.count())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+
+ int offset = msgstrEdit->currentIndex();
+
+ _currentTag++;
+ selectTag();
+
+ modifyMsgstrText( offset, _tags[_currentTag-1] );
+}
+
+void KBabelView::insertNextTagMsgid()
+{
+ TagExtractor extractor;
+
+ int offset = msgstrEdit->beginOfLastMarkedText(); //msgstrEdit->currentIndex();
+
+ QString s = (*_catalog->msgstr(_currentIndex).at(msgstrEdit->currentForm())).left(offset);
+
+ QString t;
+
+ if( _catalog->pluralForm( _currentIndex ) == KDESpecific )
+ {
+ int pos = msgstrEdit->currentIndex();
+ int currentFormBegin=s.findRev("\\n",pos);
+ if( currentFormBegin == -1 ) currentFormBegin=0;
+ else currentFormBegin+=3; // skip the newline
+ int currentFormEnd=s.find("\\n",pos);
+ if( currentFormEnd == -1 ) currentFormEnd=s.length();
+
+ s=s.mid(currentFormBegin,currentFormEnd-currentFormBegin);
+ }
+
+ extractor.setString(s);
+ uint num= extractor.countMatches();
+ if(num >= _tags.count())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+
+ t=_tags[num];
+
+ modifyMsgstrText( offset, t );
+}
+
+void KBabelView::showTagsMenu()
+{
+ if(_tagsMenu && _tags.count() > 0)
+ {
+ int y=msgstrEdit->height()/2;
+ int x=msgstrEdit->width()/2;
+ _tagsMenu->exec(msgstrEdit->mapToGlobal( QPoint(x,y) ) );
+
+ return;
+ }
+}
+
+
+void KBabelView::updateArgs()
+{
+ bool hadArgs = _args.count() > 0;
+
+ _args = _catalog->argList(_currentIndex);
+
+ if(_argsMenu)
+ {
+ _argsMenu->clear();
+
+ QStringList tList;
+ QStringList::Iterator it;
+ int counter=0;
+ for(it=_args.begin(); it!=_args.end(); ++it)
+ {
+ QString s = *it;
+ if(!tList.contains(s))
+ {
+ _argsMenu->insertItem(s,counter);
+ tList.append(s);
+ }
+ counter++;
+ }
+ }
+
+ bool haveArgs = (_args.count() > 0);
+
+ if(isReadOnly())
+ haveArgs=false;
+
+ if(haveArgs != hadArgs)
+ {
+ emit signalNextArgAvailable(haveArgs);
+ emit signalArgsAvailable(haveArgs);
+ }
+}
+
+void KBabelView::setArgsMenu(QPopupMenu *menu)
+{
+ _argsMenu=menu;
+
+ connect(_argsMenu,SIGNAL(activated(int)),this,SLOT(insertArg(int)));
+}
+
+
+void KBabelView::insertArg(int n)
+{
+ QString arg = _argsMenu->text(n);
+
+ modifyMsgstrText( msgstrEdit->currentIndex(), arg );
+}
+
+void KBabelView::insertNextArg()
+{
+ int offset = msgstrEdit->currentIndex();
+
+ QString s = (*_catalog->msgstr(_currentIndex).at(msgstrEdit->currentForm())).left(offset);
+
+ if( _catalog->pluralForm( _currentIndex ) == KDESpecific )
+ {
+ int pos = msgstrEdit->currentIndex();
+ int currentFormBegin=s.findRev("\\n",pos);
+ if( currentFormBegin == -1 ) currentFormBegin=0;
+ else currentFormBegin+=3; // skip the newline
+ int currentFormEnd=s.find("\\n",pos);
+ if( currentFormEnd == -1 ) currentFormEnd=s.length();
+
+ s=s.mid(currentFormBegin,currentFormEnd-currentFormBegin);
+ }
+
+ _argExtractor->setString(s);
+ uint num=_argExtractor->countMatches();
+ if(num >= _args.count())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+
+ QString t=_args[num];
+
+ modifyMsgstrText( offset,t );
+}
+
+void KBabelView::showArgsMenu()
+{
+ if(_argsMenu && _args.count() > 0)
+ {
+ int y=msgstrEdit->height()/2;
+ int x=msgstrEdit->width()/2;
+ _argsMenu->exec(msgstrEdit->mapToGlobal( QPoint(x,y) ) );
+
+ return;
+ }
+}
+
+
+void KBabelView::diff()
+{
+ diffInternal(false);
+ msgstrEdit->setFocus();
+}
+
+void KBabelView::diffShowOrig()
+{
+ msgidLabel->setText(_catalog->msgid(_currentIndex));
+ msgidLabel->forceUpdate();
+ msgstrEdit->setFocus();
+}
+
+void KBabelView::toggleAutoDiff(bool on)
+{
+ if(on != _diffEnabled)
+ {
+ _diffEnabled = on;
+
+ if(on)
+ {
+ diff();
+ }
+ else
+ {
+ diffShowOrig();
+ }
+ }
+}
+
+void KBabelView::autoDiff()
+{
+ diffInternal(true);
+}
+
+void KBabelView::diffInternal(bool autoDf)
+{
+ if(_diffing || _loadingDiffFile)
+ {
+ return;
+ }
+
+ _diffing = true;
+ uint diffIndex = _currentIndex;
+
+ QString diffString;
+
+ Catalog::DiffResult r = _catalog->diff(_currentIndex, &diffString);
+
+ if(r == Catalog::DiffNeedList)
+ {
+ switch( _project->settings()->useDBForDiff() )
+ {
+ case 1:
+ {
+ _loadingDiffFile=true;
+ bool wasEnabled=_diffEnabled;
+ _diffEnabled=false;
+
+ QValueList<DiffEntry> diffList;
+ QString error;
+ QString package = _catalog->packageName()+".po";
+ kdDebug(KBABEL) << "getting list for " << package << endl;
+
+ if(dictBox->messagesForPackage(package,diffList,error))
+ {
+ kdDebug(KBABEL) << "got " << diffList.count()
+ << " messages" << endl;
+ _catalog->setDiffList(diffList);
+ }
+ else
+ {
+ KMessageBox::sorry(this
+ ,i18n("An error occurred while trying to get the list "
+ "of messages for this file from the database:\n"
+ "%1").arg(error));
+
+ _diffing=false;
+ _diffEnabled=false;
+ _loadingDiffFile=false;
+ emit signalDiffEnabled(false);
+
+ return;
+ }
+
+ _diffEnabled=wasEnabled;
+ _loadingDiffFile=false;
+ break;
+ }
+ case 0:
+ {
+ _diffing=false;
+ if(!openDiffFile(true))
+ {
+ _diffEnabled=false;
+ emit signalDiffEnabled(false);
+
+ _diffing=false;
+ return;
+ }
+
+ _diffing = true;
+ break;
+ }
+ case 2:
+ {
+ // get the list of all entries
+ QValueList<DiffEntry> diffList = _catalog->asDiffList();
+
+ QValueList<DiffEntry> resultList;
+
+ // swap msgstr and msgid
+ QValueList<DiffEntry>::iterator it;
+ DiffEntry entry;
+
+ for ( it = diffList.begin(); it != diffList.end(); ++it )
+ {
+ entry.msgstr = (*it).msgid;
+ // if there is no translation, do not show difference
+ if( !(*it).msgstr.isEmpty() )
+ {
+ entry.msgid = (*it).msgstr;
+ }
+ else
+ {
+ entry.msgid = (*it).msgid;
+ }
+ resultList.append(entry);
+ }
+
+ // set as a source for diff
+ _catalog->setDiffList(resultList);
+
+ _diffing=false;
+ _diffEnabled=true;
+ _loadingDiffFile=false;
+ emit signalDiffEnabled(true);
+ }
+ }
+
+ diffIndex = _currentIndex;
+ r = _catalog->diff(_currentIndex, &diffString);
+ }
+
+ // if the index changed in the meanwhile
+ while(diffIndex != _currentIndex)
+ {
+ diffIndex=_currentIndex;
+ r = _catalog->diff(_currentIndex,&diffString);
+ }
+
+ if(r == Catalog::DiffOk)
+ {
+ msgidLabel->setText(diffString);
+ msgidLabel->forceUpdate();
+
+ // FIXME: should care about plural forms
+ if(diffString == _catalog->msgid(_currentIndex).first() )
+ {
+ emit signalChangeStatusbar(i18n("No difference found"));
+ }
+ else
+ {
+ emit signalChangeStatusbar(i18n("Difference found"));
+ }
+ }
+ else
+ {
+ if(!autoDf)
+ {
+ KMessageBox::information(this
+ ,i18n("No corresponding message found."));
+ }
+ else
+ {
+ emit signalChangeStatusbar(
+ i18n("No corresponding message found"));
+ }
+ }
+
+ _diffing = false;
+}
+
+bool KBabelView::openDiffFile()
+{
+ return openDiffFile(false);
+}
+
+bool KBabelView::openDiffFile(bool autoDiff)
+{
+ if(_diffing || _loadingDiffFile)
+ return false;
+
+ KURL url;
+
+ if( autoDiff && ! _project->settings()->diffBaseDir().isEmpty() )
+ {
+ KURL fileURL = _catalog->currentURL();
+
+ KURL poBaseURL( _project->catManSettings().poBaseDir );
+
+ QString poBase = poBaseURL.path();
+ int len = poBase.length();
+ if(fileURL.path().left(len) == poBase)
+ {
+ QString fileRelPath = fileURL.path().mid(len);
+ if(fileRelPath[0] == '/')
+ fileRelPath=fileRelPath.mid(1);
+
+ if(_project->settings()->diffBaseDir().right(1) != "/")
+ _project->settings()->diffBaseDir() += '/';
+
+ QString diffFilePath = _project->settings()->diffBaseDir() + fileRelPath;
+
+
+ KURL diffFileURL(diffFilePath);
+
+ if(diffFileURL.isValid() && KIO::NetAccess::exists(diffFileURL,true,NULL))
+ {
+ url = diffFileURL;
+
+ kdDebug(KBABEL) << "using file " << diffFileURL.prettyURL()
+ << " as diff file" << endl;
+ }
+ }
+ }
+
+
+ if(url.isEmpty())
+ {
+ url = KFileDialog::getOpenURL(_project->settings()->diffBaseDir(),
+"application/x-gettext", this, i18n("Select File to Diff With"));
+ }
+
+ if(url.isEmpty())
+ return false;
+
+ _loadingDiffFile=true;
+ bool wasEnabled=_diffEnabled;
+ _diffEnabled=false;
+
+
+ Catalog cat;
+
+ connect(&cat,SIGNAL(signalProgress(int)),this,SIGNAL(signalProgress(int)));
+ emit signalResetProgressBar(i18n("loading file for diff"),100);
+
+ ConversionStatus stat = cat.openURL(url);
+
+ emit signalClearProgressBar();
+
+
+ if(stat != OK && stat != RECOVERED_PARSE_ERROR)
+ {
+ switch(stat)
+ {
+ case PARSE_ERROR:
+ {
+ KMessageBox::sorry(this
+ ,i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid PO file.").arg(url.prettyURL()));
+ break;
+ }
+ case NO_PERMISSIONS:
+ {
+ KMessageBox::sorry(this,i18n(
+ "You do not have permissions to read file:\n %1")
+ .arg(url.prettyURL()));
+ break;
+ }
+ case NO_FILE:
+ {
+ KMessageBox::sorry(this,i18n(
+ "You have not specified a valid file:\n %1")
+ .arg(url.prettyURL()));
+ break;
+ }
+ case NO_PLUGIN:
+ {
+ KMessageBox::error(this,i18n(
+ "KBabel cannot find a corresponding plugin for the MIME type of the file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ case UNSUPPORTED_TYPE:
+ {
+ KMessageBox::error(this,i18n(
+ "The import plugin cannot handle this type of the file:\n %1").arg(url.prettyURL()));
+ break;
+ }
+ default:
+ {
+ KMessageBox::sorry(this,i18n(
+ "Error while trying to open file:\n %1")
+ .arg(url.prettyURL()));
+ break;
+ }
+
+ }
+
+ _diffEnabled=wasEnabled;
+ _loadingDiffFile=false;
+
+ return false;
+ }
+
+ _catalog->setDiffList( cat.asDiffList() );
+
+ _diffEnabled=wasEnabled;
+ _loadingDiffFile=false;
+
+ return true;
+}
+
+void KBabelView::showTryLaterMessageBox()
+{
+ if( !_showTryLaterBox ) return;
+
+ KDialogBase *dialog= new KDialogBase(
+ i18n("Information"),
+ KDialogBase::Yes,
+ KDialogBase::Yes, KDialogBase::Yes,
+ this, "information", true, true,
+ KStdGuiItem::ok() );
+
+ QVBox *topcontents = new QVBox (dialog);
+ topcontents->setSpacing(KDialog::spacingHint()*2);
+ topcontents->setMargin(KDialog::marginHint()*2);
+
+ QWidget *contents = new QWidget(topcontents);
+ QHBoxLayout * lay = new QHBoxLayout(contents);
+ lay->setSpacing(KDialog::spacingHint()*2);
+
+ lay->addStretch(1);
+ QLabel *label1 = new QLabel( contents);
+ label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information));
+ lay->add( label1 );
+ QLabel *label2 = new QLabel( i18n("The search string has not been found yet.\n"
+ "However, the string might be found "
+ "in the files being searched at the moment.\n"
+ "Please try later."), contents);
+ label2->setAlignment( Qt::AlignAuto | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak );
+ label2->setMinimumSize(label2->sizeHint());
+ lay->add( label2 );
+ lay->addStretch(1);
+
+ QCheckBox *checkbox = new QCheckBox(i18n("Do not show in this find/replace session again"), topcontents);
+
+ dialog->setMainWidget(topcontents);
+ dialog->enableButtonSeparator(false);
+ dialog->incInitialSize( QSize(50,0) );
+
+ dialog->exec();
+
+ _showTryLaterBox = !checkbox->isChecked();
+ delete dialog;
+}
+
+void KBabelView::setFilePackage()
+{
+ bool result=false;
+ QString p = KInputDialog::getText(QString::null, i18n("Enter new package for the current file:"),_catalog->package(),&result,this);
+ if( result )
+ {
+ _catalog->setPackage(p);
+ emit signalChangeCaption(p);
+ }
+}
+
+void KBabelView::insertTagFromTool( const QString& tag )
+{
+ modifyMsgstrText(msgstrEdit->currentIndex(),tag);
+
+ msgstrEdit->setFocus();
+}
+
+void KBabelView::skipToTagFromTool( int index )
+{
+ _currentTag = index;
+ selectTag();
+}
+
+void KBabelView::plural2msgstr()
+{
+ int currentFormBegin, currentFormEnd, pos;
+ uint i;
+
+ QStringList msgs = _catalog->msgstr(_currentIndex);
+ QString text= *msgs.at(msgstrEdit->currentForm());
+ uint numForms = _catalog->numberOfPluralForms(_currentIndex);
+
+ if( text.isEmpty() || _catalog->pluralForm(_currentIndex) == NoPluralForm) return;
+
+
+ QString result;
+
+ switch( _catalog->pluralForm(_currentIndex) )
+ {
+ case Gettext:
+
+ _catalog->applyBeginCommand( _currentIndex, Msgstr ,this);
+
+ i=0;
+ for( QStringList::Iterator it=msgs.begin() ; it!=msgs.end() ; ++it )
+ {
+ if( i!= msgstrEdit->currentForm() )
+ {
+ // clear first
+ DelTextCmd* insCmd = new DelTextCmd(0,(*it),i);
+ insCmd->setPart(Msgstr);
+ insCmd->setIndex(_currentIndex);
+ msgstrEdit->processCommand(insCmd,false);
+ forwardMsgstrEditCmd(insCmd);
+
+ // insert text
+ insCmd = new InsTextCmd(0,text,i);
+ insCmd->setPart(Msgstr);
+ insCmd->setIndex(_currentIndex);
+ msgstrEdit->processCommand(insCmd,false);
+ forwardMsgstrEditCmd(insCmd);
+ }
+ i++;
+ }
+
+ // fill the non-initialized ones
+ while (i != numForms)
+ {
+ // insert text
+ DelTextCmd* insCmd = new InsTextCmd(0,text,i);
+ insCmd->setPart(Msgstr);
+ insCmd->setIndex(_currentIndex);
+ msgstrEdit->processCommand(insCmd,false);
+ forwardMsgstrEditCmd(insCmd);
+ i++;
+ }
+
+ _catalog->applyEndCommand( _currentIndex, Msgstr ,this);
+
+ break;
+
+ case KDESpecific:
+ {
+ pos = msgstrEdit->currentIndex();
+ currentFormBegin=text.findRev("\\n",pos);
+ if( currentFormBegin == -1 ) currentFormBegin=0;
+ else currentFormBegin+=3; // skip the newline
+ currentFormEnd=text.find("\\n",pos);
+ if( currentFormEnd == -1 ) currentFormEnd=text.length();
+
+ text=text.mid(currentFormBegin,currentFormEnd-currentFormBegin);
+
+ QString result=text;
+ for( i=1; i<numForms ; i++ )
+ result+="\\n\n"+text;
+
+ modifyMsgstrText( 0, result, true );
+ }
+ break;
+
+ case NoPluralForm: break;
+ }
+
+}
+
+bool KBabelView::validateUsingTool( const KDataToolInfo & info, const QString &command )
+{
+ if(currentURL().isEmpty())
+ return false;
+
+ KDataTool* tool = info.createTool();
+ if( !tool )
+ {
+ kdWarning() << "Cannot create tool" << endl;
+ return false;
+ }
+
+ bool result=_catalog->checkUsingTool(tool);
+ emitEntryState();
+
+ QString checkName = *(info.userCommands().at( info.commands().findIndex(command) ));
+
+ if(result)
+ {
+ KMessageBox::information(this
+ ,i18n("No mismatch has been found.")
+ ,checkName);
+ }
+ else
+ {
+ int index=0;
+ DocPosition pos;
+
+ if(!_catalog->hasError(0,pos))
+ index = _catalog->nextError(0,pos);
+ if(index>=0)
+ {
+ kdDebug(KBABEL) << "Going to " << pos.item << ", " << pos.form << endl;
+ gotoEntry(pos);
+ }
+
+ KMessageBox::error(this
+ ,i18n("Some mismatches have been found.\n"
+ "Please check the questionable entries by using "
+ "Go->Next error")
+ ,checkName);
+ }
+ delete tool;
+
+ return result;
+}
+
+void KBabelView::modifyUsingTool( const KDataToolInfo & info, const QString &command )
+{
+ KDataTool* tool = info.createTool();
+ if( !tool )
+ {
+ kdWarning() << "Cannot create tool" << endl;
+ return;
+ }
+
+ // do some stuff on all entries
+ _catalog->modifyUsingTool(tool, command);
+
+ delete tool;
+}
+
+void KBabelView::modifyCatalogUsingTool( const KDataToolInfo & info, const QString &command )
+{
+ KDataTool* tool = info.createTool();
+ if( !tool )
+ {
+ kdWarning() << "Cannot create tool" << endl;
+ return;
+ }
+
+ // do some stuff on the catalog
+ tool->run(command, _catalog, "Catalog", "application/x-kbabel-catalog");
+
+ delete tool;
+}
+
+void KBabelView::insertChar( QChar ch )
+{
+ if( isReadOnly() || _catalog->package().isEmpty() )
+ return;
+
+ modifyMsgstrText(msgstrEdit->currentIndex(),ch);
+ msgstrEdit->setFocus();
+}
+
+void KBabelView::wordCount()
+{
+ uint total, untranslated, fuzzy;
+
+ _catalog->wordCount( total, fuzzy, untranslated );
+
+ KMessageBox::information( this
+ , i18n("Total words: %1\n\n"
+"Words in untranslated messages: %2\n\n"
+"Words in fuzzy messages: %3").arg(total).arg(untranslated).arg(fuzzy)
+ , i18n("Word Count") );
+}
diff --git a/kbabel/kbabel/kbbookmarkhandler.cpp b/kbabel/kbabel/kbbookmarkhandler.cpp
new file mode 100644
index 00000000..fde1b051
--- /dev/null
+++ b/kbabel/kbabel/kbbookmarkhandler.cpp
@@ -0,0 +1,131 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Marco Wegner <mail@marcowegner.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+
+#include <qpopupmenu.h>
+#include <qregexp.h>
+#include <qstring.h>
+
+#include "kbbookmarkhandler.h"
+
+
+// implementation of KBabelBookmark
+KBabelBookmark::KBabelBookmark(int msgindex, QString msgtext)
+{
+ _msgindex = msgindex;
+ if (msgtext.length() > 32) {
+ msgtext.truncate(32);
+ msgtext.append("...");
+ }
+
+ // insert one '&' before every consecutive group of ampersands to keep the
+ // first of these from acting either as accelerator or mask in the menu
+ QRegExp rx("&+");
+ int pos = msgtext.find(rx);
+ while (pos >= 0) {
+ msgtext.insert(pos, '&');
+ pos = msgtext.find(rx, pos + rx.matchedLength() + 1);
+ }
+
+ _msgtext = msgtext;
+}
+
+int KBabelBookmark::msgindex() const
+{
+ return _msgindex;
+}
+
+QString KBabelBookmark::msgtext() const
+{
+ return _msgtext;
+}
+
+
+// implementation of KBabelBookmarkHandler
+KBabelBookmarkHandler::KBabelBookmarkHandler(QPopupMenu* menu)
+{
+ _menu = menu;
+ _list.setAutoDelete(true);
+}
+
+void KBabelBookmarkHandler::addBookmark(KBabelBookmark* b)
+{
+ // check if a bookmark to the current msgid exists already
+ QPtrListIterator<KBabelBookmark> it(_list);
+ KBabelBookmark* temp;
+
+ while((temp = it.current()) != 0) {
+ ++it;
+ if (temp->msgindex() == b->msgindex()) {
+ // gotcha
+ delete b;
+ return;
+ }
+ }
+
+ // if it's okay then add the bookmark
+ _list.append(b);
+ _menu->insertItem(QString("#%1 - %2").arg(b->msgindex()).arg(b->msgtext()),
+ this, SIGNAL(signalBookmarkSelected(int)), 0, b->msgindex());
+}
+
+void KBabelBookmarkHandler::addBookmark(int msgindex, QString msgtext)
+{
+ addBookmark(new KBabelBookmark(msgindex, msgtext));
+}
+
+void KBabelBookmarkHandler::setBookmarks(QPtrList<KBabelBookmark> list)
+{
+ QPtrListIterator<KBabelBookmark> it(list);
+ KBabelBookmark* temp;
+
+ while((temp = it.current()) != 0) {
+ ++it;
+ addBookmark(temp->msgindex(), temp->msgtext()); // make deep copy
+ }
+}
+
+QPtrList<KBabelBookmark> KBabelBookmarkHandler::bookmarks() const
+{
+ return _list;
+}
+
+void KBabelBookmarkHandler::slotClearBookmarks()
+{
+ while (!_list.isEmpty()) {
+ KBabelBookmark* b = _list.first();
+ _menu->removeItem(b->msgindex());
+ _list.remove(b);
+ }
+}
+
+#include "kbbookmarkhandler.moc"
diff --git a/kbabel/kbabel/kbbookmarkhandler.h b/kbabel/kbabel/kbbookmarkhandler.h
new file mode 100644
index 00000000..f47c2dbf
--- /dev/null
+++ b/kbabel/kbabel/kbbookmarkhandler.h
@@ -0,0 +1,155 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Marco Wegner <mail@marcowegner.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+
+#ifndef KBBOOKMARKHANDLER_H
+#define KBBOOKMARKHANDLER_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+class QPopupMenu;
+class QString;
+
+
+/**
+ * Simple class representing a bookmark in KBabel.
+ * Stored in the class are the msgindex (msgid #) and part of its text.
+ */
+class KBabelBookmark
+{
+ public:
+ /**
+ * Constructor.
+ * The msgtext will be truncated automatically when creating the bookmark.
+ *
+ * @param msgindex the index of the bookmarked msgid.
+ * @param msgtext the msgid.
+ */
+ KBabelBookmark(int msgindex, QString msgtext);
+
+ /**
+ * Return the index of the msgid.
+ *
+ * @return the index of the bookmarked msgid.
+ */
+ int msgindex() const;
+ /**
+ * Return the msgid.
+ *
+ * @return the msgid.
+ */
+ QString msgtext() const;
+
+ private:
+ /**
+ * The classes' own copy of the msgindex.
+ */
+ int _msgindex;
+ /**
+ * The classes' own copy of the msgid.
+ */
+ QString _msgtext;
+};
+
+
+/**
+ * Simple class for managing bookmarks in KBabel.
+ */
+class KBabelBookmarkHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor.
+ *
+ * @param menu the pointer to the menu where the bookmarks will be
+ * displayed.
+ */
+ KBabelBookmarkHandler(QPopupMenu* menu);
+
+ /**
+ * Add a bookmark.
+ * The bookmark is added to the internal list as well as to the menu.
+ *
+ * @param b the bookmark to be added.
+ */
+ void addBookmark(KBabelBookmark* b);
+ /**
+ * Add a bookmark.
+ * Overloaded member. The bookmark will first be created from msgindex
+ * and msgtext.
+ *
+ * @param msgindex the index of the bookmark's msgid.
+ * @param msgtext the msgindex of the bookmark to be added.
+ */
+ void addBookmark(int msgindex, QString msgtext);
+ /**
+ * Provide the handler with a list of bookmarks.
+ * Especially useful when creating a new view of the KBabel window.
+ *
+ * @param list the list to be copied.
+ */
+ void setBookmarks(QPtrList<KBabelBookmark> list);
+ /**
+ * Return the list of bookmarks for a new view of the KBabel window.
+ *
+ * @return the internal list of bookmarks
+ */
+ QPtrList<KBabelBookmark> bookmarks() const;
+
+ public slots:
+ /**
+ * Clear all bookmarks.
+ */
+ void slotClearBookmarks();
+
+ signals:
+ /**
+ * This signal is emitted if one of the bookmarks was activated.
+ * The signal contains the msgindex of the bookmark.
+ */
+ void signalBookmarkSelected(int);
+
+ private:
+ /**
+ * The pointer to the menu.
+ */
+ QPopupMenu* _menu;
+ /**
+ * The internal list for storing the bookmarks.
+ */
+ QPtrList<KBabelBookmark> _list;
+};
+
+#endif // KBBOOKMARKHANDLER_H
diff --git a/kbabel/kbabel/kbcatalog.cpp b/kbabel/kbabel/kbcatalog.cpp
new file mode 100644
index 00000000..52205484
--- /dev/null
+++ b/kbabel/kbabel/kbcatalog.cpp
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "kbcatalog.h"
+#include "headereditor.h"
+
+
+KBCatalog::KBCatalog(QString configFile, QObject* parent, const char* name)
+ : KBabel::Catalog(parent,name,configFile)
+{
+ _headerEditor=0;
+}
+
+
+KBCatalog::~KBCatalog()
+{
+ if(_headerEditor)
+ delete _headerEditor;
+}
+
+HeaderEditor* KBCatalog::headerEditor()
+{
+ if(!_headerEditor)
+ {
+ _headerEditor = new HeaderEditor(this,"_headerEditor");
+ }
+
+ return _headerEditor;
+}
+
+
+
+#include "kbcatalog.moc"
diff --git a/kbabel/kbabel/kbcatalog.h b/kbabel/kbabel/kbcatalog.h
new file mode 100644
index 00000000..ae6508cf
--- /dev/null
+++ b/kbabel/kbabel/kbcatalog.h
@@ -0,0 +1,61 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBCATALOG_H
+#define KBCATALOG_H
+
+#include "catalog.h"
+
+class HeaderEditor;
+
+
+/**
+* This class adds some functionality to the catalog,
+* that is needed by the gui.
+* * @author Matthias Kiefer <matthias.kiefer@gmx.de>
+*/
+class KBCatalog : public KBabel::Catalog
+{
+ Q_OBJECT
+
+public:
+ KBCatalog(QString configFile = QString::null ,QObject* parent=0, const char* name=0);
+ virtual ~KBCatalog();
+
+ HeaderEditor* headerEditor();
+
+private:
+ HeaderEditor* _headerEditor;
+
+};
+
+#endif //CATALOG_H
diff --git a/kbabel/kbabel/kbcataloglistview.cpp b/kbabel/kbabel/kbcataloglistview.cpp
new file mode 100644
index 00000000..51f9b008
--- /dev/null
+++ b/kbabel/kbabel/kbcataloglistview.cpp
@@ -0,0 +1,136 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Asgeir Frimannsson
+ <asgeirf@redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+**************************************************************************** */
+
+#include "kbcataloglistview.h"
+#include "kbcataloglistviewitem.h"
+#include "kbcatalog.h"
+#include "kbabel.h"
+#include "editcmd.h"
+
+#include <klocale.h>
+#include <klistview.h>
+#include <qcolor.h>
+#include <qlayout.h>
+#include <kglobalsettings.h>
+
+using namespace KBabel;
+
+KBCatalogListView::KBCatalogListView(KBCatalog* catalog, QWidget *parent, KBabel::Project::Ptr project)
+ : QWidget(parent)
+{
+ m_catalog= catalog;
+ QVBoxLayout* layout=new QVBoxLayout(this);
+
+ m_listview = new KListView(this, "catalogListView");
+ m_listview->addColumn(i18n("Id"));
+ m_listview->addColumn(i18n("Original String"));
+ m_listview->addColumn(i18n("Translated String"));
+ m_listview->setAlternateBackground(KGlobalSettings::alternateBackgroundColor());
+ m_listview->setFullWidth(true);
+ m_listview->setAllColumnsShowFocus(true);
+ m_listview->resize(this->size());
+
+ layout->addWidget(m_listview);
+ layout->setStretchFactor(m_listview,1);
+
+ connect(m_listview,SIGNAL(selectionChanged(QListViewItem *)), this,SLOT(selectionChanged(QListViewItem *)));
+}
+
+KBCatalogListView::~KBCatalogListView()
+{
+}
+
+
+void KBCatalogListView::selectionChanged ( QListViewItem * item)
+{
+ DocPosition pos;
+ int number = m_items->find(reinterpret_cast<KBCatalogListViewItem*>(item));
+ if(number<0) number = 0;
+
+ pos.item=number;
+ pos.form=0;
+
+ emit signalSelectionChanged(pos);
+}
+
+void KBCatalogListView::setSelectedItem(int index)
+{
+ QListViewItem * item = m_items->at(index);
+
+ // block signals - don't reemit the selected item signal
+ blockSignals(true);
+ m_listview->setSelected(item, true);
+ blockSignals(false);
+
+ m_listview->ensureItemVisible(item);
+}
+
+void KBCatalogListView::update(EditCommand* cmd, bool undo)
+{
+ /*
+ if((int)_currentIndex==cmd->index())
+ {
+ emitEntryState();
+
+ if(cmd->part()==Msgstr)
+ {
+ msgstrEdit->processCommand(cmd,undo);
+ emit signalMsgstrChanged();
+ }
+ }
+ */
+}
+
+void KBCatalogListView::msgstrChanged(const QString& str)
+{
+ KBCatalogListViewItem * item = reinterpret_cast<KBCatalogListViewItem *>(m_listview->selectedItem());
+ item->setMsgStr(str);
+}
+
+void KBCatalogListView::slotNewFileOpened()
+{
+ m_listview->clear();
+ KBCatalogListViewItem * tempItem;
+ if(m_catalog)
+ {
+ m_items = new QPtrVector<KBCatalogListViewItem>(m_catalog->numberOfEntries());
+
+ for(uint i=0;i<m_catalog->numberOfEntries();i++)
+ {
+ QString msgid = ( *m_catalog->msgid(i).at(0) );
+ QString msgstr = ( *m_catalog->msgstr(i).at(0) );
+ tempItem = new KBCatalogListViewItem(m_listview,0,i+1,
+ msgid,
+ msgstr);
+ m_items->insert(i, tempItem);
+ }
+ }
+
+ int width = m_listview->columnWidth(1) + m_listview->columnWidth(2);
+ m_listview->setColumnWidth(1,width/2);
+ m_listview->setColumnWidth(2,width/2);
+
+
+}
+
+
+#include "kbcataloglistview.moc"
diff --git a/kbabel/kbabel/kbcataloglistview.h b/kbabel/kbabel/kbcataloglistview.h
new file mode 100644
index 00000000..d9737871
--- /dev/null
+++ b/kbabel/kbabel/kbcataloglistview.h
@@ -0,0 +1,82 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Asgeir Frimannsson
+ <asgeirf@redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+**************************************************************************** */
+
+#ifndef KBCATALOGLISTVIEW_H
+#define KBCATALOGLISTVIEW_H
+
+#include <qwidget.h>
+#include <catalogview.h>
+#include <kconfig.h>
+#include <qwidget.h>
+//#include <qstrlist.h>
+#include <resources.h>
+#include "catalog.h"
+#include "kbcatalog.h"
+#include "kbproject.h"
+#include "projectsettings.h"
+#include "kbcataloglistviewitem.h"
+
+namespace KBabel{
+ class EditCommand;
+}
+
+class KBabelMW;
+class KBCatalog;
+class KListView;
+
+
+/**
+@author
+*/
+class KBCatalogListView : public QWidget, public KBabel::CatalogView
+{
+ Q_OBJECT
+public:
+ KBCatalogListView(KBCatalog* catalog, QWidget *parent, KBabel::Project::Ptr project);
+
+ ~KBCatalogListView();
+
+ /**
+ * this is called from the catalog when updating his views.
+ * reimplemented from @ref CatalogView
+ * @param cmd the edit command that has been applied
+ */
+ virtual void update(KBabel::EditCommand* cmd, bool undo=false);
+
+ void setSelectedItem(int index);
+signals:
+ void signalSelectionChanged(const KBabel::DocPosition& pos);
+
+public slots:
+ virtual void slotNewFileOpened();
+ void msgstrChanged(const QString&);
+
+private:
+ KListView * m_listview;
+ KBCatalog* m_catalog;
+ QPtrVector<KBCatalogListViewItem>* m_items;
+
+private slots:
+ void selectionChanged ( QListViewItem * item);
+};
+
+#endif
diff --git a/kbabel/kbabel/kbcataloglistviewitem.cpp b/kbabel/kbabel/kbcataloglistviewitem.cpp
new file mode 100644
index 00000000..5a4012a2
--- /dev/null
+++ b/kbabel/kbabel/kbcataloglistviewitem.cpp
@@ -0,0 +1,213 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Asgeir Frimannsson
+ <asgeirf@redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+**************************************************************************** */
+
+#include "kbcataloglistviewitem.h"
+#include <assert.h>
+
+KBCatalogListViewItem::KBCatalogListViewItem(KListView* lv, KListViewItem* parent, uint id, QString msgid, QString msgstr)
+ : Super(lv, parent, "","",""), m_id(id), m_msgid(msgid), m_msgstr(msgstr)
+{
+ setText(0,QString::number(id));
+}
+
+
+KBCatalogListViewItem::~KBCatalogListViewItem()
+{
+}
+
+void KBCatalogListViewItem::setMsgId(const QString& st)
+{
+ m_msgid = st;
+ setup();
+ repaint();
+}
+
+void KBCatalogListViewItem::setMsgStr(const QString& st)
+{
+ m_msgstr = st;
+ setup();
+ repaint();
+}
+
+uint KBCatalogListViewItem::getId()
+{
+ return m_id;
+}
+
+void KBCatalogListViewItem::setId(const uint id)
+{
+ m_id = id;
+ setup();
+ repaint();
+}
+
+QString KBCatalogListViewItem::key ( int column, bool ascending ) const{
+
+ if(column==0)
+ return QString().sprintf("%.8u", m_id);
+ else if(column==1)
+ return m_msgid;
+ else if(column==2)
+ return m_msgstr;
+ else
+ return Super::key(column, ascending);
+}
+
+
+void KBCatalogListViewItem::setup()
+{
+ assert(listView());
+
+ widthChanged();
+
+ m_doc_msgid.reset(0);
+ m_doc_msgstr.reset(0);
+
+ makeDocAvailable();
+
+ QListView* lv = listView();
+
+ m_doc_msgid->setWidth(std::max(1, int(lv->columnWidth(1))));
+ m_doc_msgstr->setWidth(std::max(1, int(lv->columnWidth(2))));
+
+ if(m_doc_msgid->height() > m_doc_msgstr->height())
+ setHeight(m_doc_msgid->height());
+ else
+ setHeight(m_doc_msgstr->height());
+
+}
+
+
+void KBCatalogListViewItem::paintMsgIdCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align)
+{
+ // check width
+
+ int widthPrepared = m_doc_msgid->width();
+
+ if (width != widthPrepared)
+ m_doc_msgid->setWidth(p, std::max(1, int(width)));
+
+ // check height
+
+ if (height() < m_doc_msgid->height() )
+ {
+ // invalid height, don't draw
+
+ setHeight(m_doc_msgid->height());
+ return;
+ }
+
+ // draw appropriate background
+
+ Super::paintCell(p, cg, column, width, align);
+
+ // draw it
+
+ m_doc_msgid->draw(p, 0, 0, QRect(0,0, width, height()), cg);
+
+}
+
+void KBCatalogListViewItem::paintMsgStrCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align)
+{
+ // check width
+
+ int widthPrepared = m_doc_msgstr->width();
+
+ if (width != widthPrepared)
+ m_doc_msgstr->setWidth(p, std::max(1, int(width)));
+
+ // check height
+
+ if (height() < m_doc_msgstr->height() )
+ {
+ // invalid height, don't draw
+
+ setHeight(m_doc_msgstr->height());
+ return;
+ }
+ else if(height() > m_doc_msgstr->height() && height() > m_doc_msgid->height())
+ {
+ if(m_doc_msgstr->height() > m_doc_msgid->height())
+ setHeight(m_doc_msgstr->height());
+ else
+ setHeight(m_doc_msgid->height());
+
+ return;
+ }
+
+ // draw appropriate background
+
+ Super::paintCell(p, cg, column, width, align);
+
+ // draw it
+
+ m_doc_msgstr->draw(p, 0, 0, QRect(0,0, width, height()), cg);
+
+}
+
+void KBCatalogListViewItem::paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align)
+{
+ assert(m_doc_msgid.get() && m_doc_msgstr.get() && p);
+
+ // paint background (empty text)
+
+
+ switch(column)
+ {
+ case 0: // id
+ Super::paintCell(p, cg, column, width, align);
+ return;
+ case 1: // msgid
+ paintMsgIdCell(p,cg,column,width,align);
+ return;
+ case 2: // msgstr
+ paintMsgStrCell(p,cg,column,width,align);
+ return;
+ }
+}
+
+void KBCatalogListViewItem::makeDocAvailable()
+{
+ if (m_doc_msgid.get() && m_doc_msgstr.get())
+ return;
+
+ assert(listView());
+
+ m_doc_msgid.reset(new QSimpleRichText(
+ formatMsg(m_msgid), listView()->font()));
+ m_doc_msgstr.reset(new QSimpleRichText(
+ formatMsg(m_msgstr), listView()->font()));
+}
+
+QString KBCatalogListViewItem::formatMsg(const QString str)
+{
+ // TODO: Use KBHighlighting for this
+ QString tmp_msgid = str;
+ tmp_msgid = tmp_msgid.replace( "\\n", "<br>" );
+ tmp_msgid = tmp_msgid.replace( "<", "&lt;" );
+ tmp_msgid = tmp_msgid.replace( ">", "&gt;" );
+
+ return tmp_msgid;
+}
diff --git a/kbabel/kbabel/kbcataloglistviewitem.h b/kbabel/kbabel/kbcataloglistviewitem.h
new file mode 100644
index 00000000..8fa6704a
--- /dev/null
+++ b/kbabel/kbabel/kbcataloglistviewitem.h
@@ -0,0 +1,72 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Asgeir Frimannsson
+ <asgeirf@redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+**************************************************************************** */
+
+#ifndef KBCATALOGLISTVIEWITEM_H
+#define KBCATALOGLISTVIEWITEM_H
+#include <memory>
+#include <klistview.h>
+#include <qsimplerichtext.h>
+#include "mymultilineedit.h"
+
+/**
+@author
+*/
+class KBCatalogListViewItem : public KListViewItem
+{
+ typedef KListViewItem Super;
+public:
+ KBCatalogListViewItem(KListView* lv, KListViewItem* parent, uint id, QString msgid, QString msgstr);
+
+ ~KBCatalogListViewItem();
+
+ void setMsgId(const QString& st);
+ void setMsgStr(const QString& st);
+ void setId(const uint id);
+ uint getId();
+
+protected:
+
+ virtual void setup();
+ virtual QString key ( int column, bool ascending ) const;
+
+ virtual void paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+
+
+private:
+ void makeDocAvailable();
+ void paintMsgIdCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+ void paintMsgStrCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+
+ QString formatMsg(const QString str);
+
+ uint m_id;
+ QString m_msgid;
+ QString m_msgstr;
+
+ std::auto_ptr<QSimpleRichText> m_doc_msgid;
+ std::auto_ptr<QSimpleRichText> m_doc_msgstr;
+};
+
+#endif
diff --git a/kbabel/kbabel/kbcatalogview.cpp b/kbabel/kbabel/kbcatalogview.cpp
new file mode 100644
index 00000000..ba8e9c03
--- /dev/null
+++ b/kbabel/kbabel/kbcatalogview.cpp
@@ -0,0 +1,137 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "kbcatalogview.h"
+#include "resources.h"
+
+using namespace KBabel;
+
+KBCatalogView::KBCatalogView(KBCatalog* catalog, QWidget* parent, Project::Ptr project)
+ : QWidget (parent), KBabel::CatalogView () , _project (project)
+{
+ if (catalog == 0)
+ kdFatal(KBABEL) << "catalog==0" << endl;
+
+ _catalog=catalog;
+ _catalog->registerView(this);
+
+ _config = KSharedConfig::openConfig ("kbabelrc");
+
+ _currentIndex=1; // here we use 1 to accept update at opening a file
+
+ connect ( _project, SIGNAL (signalSettingsChanged()), this, SLOT (readProjectSettings()) );
+ connect ( _catalog, SIGNAL (signalFileOpened(bool)), this, SLOT (readFileSettings() ) );
+
+ readProjectSettings();
+ readFileSettings();
+ readConfigurationSettings();
+}
+
+KBCatalogView::~KBCatalogView()
+{
+ _catalog->removeView(this);
+
+ // check if this view was the last view and delete the catalog if necessary
+ if(!_catalog->hasView())
+ {
+ delete _catalog;
+ }
+}
+
+void KBCatalogView::update(EditCommand*, bool )
+{
+}
+
+void KBCatalogView::textCut()
+{
+}
+
+void KBCatalogView::textCopy()
+{
+}
+
+void KBCatalogView::textPaste()
+{
+}
+
+void KBCatalogView::textSelectAll()
+{
+}
+
+void KBCatalogView::gotoEntry(const DocPosition& pos)
+{
+ if ( _currentIndex == pos.item )
+ return;
+
+ _currentIndex=pos.item;
+
+ updateView ();
+}
+
+void KBCatalogView::readProjectSettings()
+{
+}
+
+void KBCatalogView::readFileSettings()
+{
+ setReadOnly (_catalog->isReadOnly());
+}
+
+void KBCatalogView::readConfigurationSettings()
+{
+}
+
+void KBCatalogView::readSessionSettings(KConfig *)
+{
+}
+
+void KBCatalogView::writeConfigurationSettings(KConfig *)
+{
+}
+
+void KBCatalogView::writeSessionSettings(KConfig *)
+{
+}
+
+void KBCatalogView::setReadOnly (bool on)
+{
+ setEnabled (on);
+}
+
+void KBCatalogView::setProject(KBabel::Project::Ptr project)
+{
+ _project = project;
+ readProjectSettings();
+}
+
+#include "kbcatalogview.moc"
diff --git a/kbabel/kbabel/kbcatalogview.h b/kbabel/kbabel/kbcatalogview.h
new file mode 100644
index 00000000..5f23381a
--- /dev/null
+++ b/kbabel/kbabel/kbcatalogview.h
@@ -0,0 +1,102 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBCATALOGVIEW_H
+#define KBCATALOGVIEW_H
+
+#include <qwidget.h>
+
+#include <catalogview.h>
+#include "kbcatalog.h"
+#include "kbproject.h"
+#include "projectsettings.h"
+
+class KBCatalogView : public QWidget, public KBabel::CatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ KBCatalogView(KBCatalog* catalog, QWidget* parent, KBabel::Project::Ptr project);
+
+ /**
+ * Destructor
+ */
+ virtual ~KBCatalogView();
+
+ /**
+ * this is called from the catalog when updating his views.
+ * reimplemented from @ref CatalogView
+ * @param cmd the edit command that has been applied
+ */
+ virtual void update(KBabel::EditCommand* cmd, bool undo=false);
+
+ KBCatalog* catalog() const{return _catalog;}
+
+public slots:
+ virtual void textCut();
+ virtual void textCopy();
+ virtual void textPaste();
+ virtual void textSelectAll();
+ virtual void gotoEntry(const KBabel::DocPosition& pos);
+ virtual void setProject(KBabel::Project::Ptr project);
+ virtual void readProjectSettings();
+ virtual void readFileSettings();
+ virtual void readConfigurationSettings();
+ virtual void readSessionSettings(KConfig *config);
+
+ virtual void writeConfigurationSettings(KConfig *config);
+ virtual void writeSessionSettings(KConfig *config);
+
+ virtual void setReadOnly (bool on);
+
+ /**
+ * this is called when the view needs an updating.
+ * It's the only really needed method to reimplement
+ */
+ virtual void updateView() = 0;
+
+signals:
+ void signalCursorPosChanged(int line, int col);
+
+protected:
+ KBCatalog* _catalog;
+ uint _currentIndex;
+
+ // configuration file
+ KSharedConfig::Ptr _config;
+ // project file
+ KBabel::Project::Ptr _project;
+};
+
+#endif // KBCATALOGVIEW_H
diff --git a/kbabel/kbabel/kbcharselect.cpp b/kbabel/kbabel/kbcharselect.cpp
new file mode 100644
index 00000000..63316255
--- /dev/null
+++ b/kbabel/kbabel/kbcharselect.cpp
@@ -0,0 +1,94 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#include "kbcharselect.h"
+
+#include <kconfig.h>
+#include <kcharselect.h>
+#include <kdialog.h>
+#include <klocale.h>
+
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qscrollview.h>
+
+KBCharSelect::KBCharSelect(QWidget* parent,const char* name)
+ : QVBox(parent,name)
+{
+ setSpacing( KDialog::spacingHint() );
+
+ QHBox* bar = new QHBox(this);
+ bar->setSpacing( KDialog::spacingHint() );
+
+ QLabel *lTable = new QLabel( i18n( "Table:" ), bar );
+ _tableNum = new QSpinBox( 0, 255, 1, bar );
+ lTable->setBuddy( _tableNum );
+ bar->setStretchFactor( _tableNum, 1 );
+
+ QScrollView* scroll = new QScrollView( this );
+ _table = new KCharSelectTable(scroll,"charselector","helvetica",' ',0);
+ _table->setNumCols(16);
+ _table->setNumRows(16);
+
+ scroll->addChild(_table);
+
+ connect( _table, SIGNAL( doubleClicked() ), this, SLOT( emitChar() ) );
+ connect( _tableNum, SIGNAL( valueChanged(int) ), this, SLOT( setTab(int) ));
+}
+
+void KBCharSelect::emitChar()
+{
+ emit characterDoubleClicked( _table->chr() );
+}
+
+void KBCharSelect::setTab(int value)
+{
+ _table->setTableNum( value );
+}
+
+void KBCharSelect::saveSettings(KConfig* config)
+{
+ KConfigGroupSaver saver(config, "KBCharSelector" );
+
+ config->writeEntry( "TableNum", _tableNum->value() );
+ config->writeEntry( "SelectedChar", QString(_table->chr()) );
+}
+
+void KBCharSelect::restoreSettings(KConfig* config)
+{
+ KConfigGroupSaver saver(config, "KBCharSelector" );
+
+ _tableNum->setValue( config->readNumEntry("TableNum", 0 ));
+ _table->setChar( config->readEntry("SelectedChar"," ").at(0));
+}
+
+#include "kbcharselect.moc"
diff --git a/kbabel/kbabel/kbcharselect.h b/kbabel/kbabel/kbcharselect.h
new file mode 100644
index 00000000..4de3460f
--- /dev/null
+++ b/kbabel/kbabel/kbcharselect.h
@@ -0,0 +1,65 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef KBCHARSELECT_H
+#define KBCHARSELECT_H
+
+#include <qvbox.h>
+
+class KConfig;
+class KCharSelectTable;
+class QSpinBox;
+
+class KBCharSelect : public QVBox
+{
+ Q_OBJECT
+public:
+ KBCharSelect(QWidget* parent, const char* name=0);
+
+ void saveSettings(KConfig* config);
+ void restoreSettings(KConfig* config);
+
+signals:
+ void characterDoubleClicked( QChar ch );
+
+public slots:
+ void emitChar();
+
+private slots:
+ void setTab( int value);
+
+private:
+ KCharSelectTable* _table;
+ QSpinBox* _tableNum;
+};
+
+#endif // KBCHARSELECT_H
diff --git a/kbabel/kbabel/kbhighlighting.cpp b/kbabel/kbabel/kbhighlighting.cpp
new file mode 100644
index 00000000..ce58c483
--- /dev/null
+++ b/kbabel/kbabel/kbhighlighting.cpp
@@ -0,0 +1,316 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Marco Wegner <mail@marcowegner.de>
+ 2003 Trolltech AS
+ 2003 Lukas Tinkl <lukas@kde.org>
+ 2003-2005 Stanislav Visnovsky <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+
+#include <qcolor.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qtextedit.h>
+
+#include "kapplication.h"
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kbabelsettings.h>
+#include <kspell.h>
+
+#include "kbhighlighting.h"
+#include "resources.h"
+
+KBabelHighlighter::KBabelHighlighter( QTextEdit * edit, KSpell *spell ) : QObject()
+ , _edit( edit )
+ , syntaxHighlighting(true)
+ , mSpell(0), alwaysEndsWithSpace(true)
+{
+ regexps << "(<[_:A-Za-z][-_.:A-Za-z0-9]*([\\s]*[_:A-Za-z][-_.:A-Za-z0-9]*=\\\\\"[^<>]*\\\\\")*[\\s]*/?>)|(</[_:A-Za-z][-_.:A-Za-z0-9]*[\\s]*>)";
+ regexps << "(&[A-Za-z_:][A-Za-z0-9_.:-]*;)";
+ regexps << "(%[\\ddioxXucsfeEgGphln]+)|(%\\d+\\$[dioxXucsfeEgGphln])";
+ regexps << "(\\\\[abfnrtv'\"\?\\\\])|(\\\\\\d+)|(\\\\x[\\dabcdef]+)";
+
+ colors.resize( 8 );
+ colors[Normal] = KGlobalSettings::textColor();
+ colors[Tag] = KBabelSettings::tagColor ();
+ colors[Entity] = KBabelSettings::tagColor ();
+ colors[CFormat] = KBabelSettings::cformatColor ();
+ colors[Masked] = KBabelSettings::quotedColor ();
+ colors[Accel] = KBabelSettings::accelColor ();
+ colors[Error] = KBabelSettings::errorColor ();
+ colors[SpellcheckError] = KBabelSettings::spellcheckErrorColor ();
+
+ _hasErrors = false;
+
+ readSettings( );
+ regexps << accelMarker + "[\\w]";
+
+ connect( _edit, SIGNAL( textChanged( ) ), this, SLOT( highlight( ) ) );
+
+ setSpellChecker(spell);
+}
+
+// spell check the current text and highlight (as red text) those words
+// that fail the spell check
+void KBabelHighlighter::highlight( )
+{
+ // no updates while we're highlighting
+ _edit->blockSignals( true );
+ _edit->setUpdatesEnabled( false );
+
+ // store cursor position
+ int cpara, cindex;
+ _edit->getCursorPosition( &cpara, &cindex );
+
+ _edit->selectAll( );
+ _edit->setColor( _hasErrors ? colors[Error] : colors[Normal] );
+ _edit->removeSelection( );
+
+ // create a single line out of the text: remove "\n", so that we only
+ // have to deal with one single line of text.
+ QString text = _edit->text( );
+ text.replace( "\n", "" );
+
+ QRegExp rx;
+ int pos;
+
+ if (syntaxHighlighting)
+ {
+ for ( uint i = 0; i < regexps.count( ); ++i ) {
+ rx.setPattern( regexps[i] );
+ pos = text.find( rx );
+ while ( pos >= 0 ) {
+ doHighlighting( (HighlightType)(i+1), pos, rx.matchedLength( ) );
+ pos = text.find( rx, pos + rx.matchedLength( ) );
+ }
+ }
+ }
+
+ if( mSpell )
+ {
+ // spell-on-fly start
+ if (!text.endsWith(" "))
+ alwaysEndsWithSpace = false;
+ else
+ alwaysEndsWithSpace = true;
+
+ //MessageHighlighter::highlightParagraph( text, endStateOfLastPara );
+
+ int len = text.length();
+ if (alwaysEndsWithSpace)
+ len--;
+
+ currentPos = 0;
+ currentWord = "";
+ for (int i = 0; i < len; i++) {
+ if (text[i].isSpace() || text[i] == '-' || (text[i]=='\\' && text[i+1]=='n')) {
+ flushCurrentWord();
+ if (text[i]=='\\') i++;
+ currentPos = i + 1;
+ } else {
+ currentWord += text[i];
+ }
+ }
+
+ // this was if (!text[len - 1].isLetter())
+ // but then the last word is never checked
+ if (text[len - 1].isLetter()) {
+ kdDebug(KBABEL) << "flushing last Current word: " << currentWord << endl;
+ flushCurrentWord();
+ }
+ else {
+ kdDebug(KBABEL) << "not flushing last Current word: " << currentWord << endl;
+ }
+ } // spell-on-fly end
+
+ _edit->setColor( colors[Normal] );
+
+ //restore cursor position
+ _edit->setCursorPosition( cpara, cindex );
+
+ // allow updates again now that we're finished highlighting
+ _edit->setUpdatesEnabled( true );
+ _edit->blockSignals( false );
+ _edit->updateContents( );
+ _edit->ensureCursorVisible();
+}
+
+void KBabelHighlighter::doHighlighting( HighlightType type, int pos, int length )
+{
+ uint startPara = 0, endPara = 0, startIndex = pos, endIndex = pos+length;
+
+ // transform the one-dimensional indexes into two-dimensional ones
+ while ( startIndex > _edit->text( startPara ).length( ) )
+ startIndex -= _edit->text( startPara++ ).length( ) - 1;
+ while ( endIndex > _edit->text( endPara ).length( ) )
+ endIndex -= _edit->text( endPara++ ).length( ) - 1;
+
+ // and finally do the actual highlighting
+ _edit->setSelection( startPara, startIndex, endPara, endIndex );
+ _edit->setColor( colors[type] );
+ _edit->removeSelection( );
+}
+
+void KBabelHighlighter::setHighlightColor( HighlightType type, QColor color )
+{
+ colors[type] = color;
+}
+
+void KBabelHighlighter::setHasErrors( bool err )
+{
+ _hasErrors = err;
+}
+
+void KBabelHighlighter::readSettings( )
+{
+ // FIXME: does not care about different projects yet
+ KConfig * config = KGlobal::config( );
+ config->setGroup( "Misc" );
+ QString temp = config->readEntry( "AccelMarker", "&" );
+ accelMarker = temp[0];
+}
+
+static int dummy, dummy2;
+static int *Okay = &dummy;
+static int *NotOkay = &dummy2;
+
+void KBabelHighlighter::flushCurrentWord()
+{
+ while (currentWord[0].isPunct()) {
+ currentWord = currentWord.mid(1);
+ currentPos++;
+ }
+
+ QChar ch;
+ while ((ch = currentWord[(int) currentWord.length() - 1]).isPunct()
+ && ch != '(' && ch != '@')
+ currentWord.truncate( currentWord.length() - 1 );
+
+ // try to remove tags (they might not be fully compliant, but
+ // we don't want to check them anyway
+ QRegExp tags("(<[-_.:A-Za-z0-9]*([\\s]*[-_.:A-Za-z0-9]*=\\\\\"[^<>]*\\\\\")*[\\s]*/?>)|(</[-_.:A-Za-z0-9]*[\\s]*>)");
+ if( tags.search (currentWord) != -1 )
+ {
+ currentPos += tags.matchedLength();
+ }
+
+ currentWord.replace ( tags, "" );
+
+ if (!currentWord.isEmpty()) {
+ bool isPlainWord = true;
+ for (int i = 0; i < (int) currentWord.length(); i++) {
+ QChar ch = currentWord[i];
+ if (ch.upper() == ch) {
+ isPlainWord = false;
+ break;
+ }
+ }
+
+ if (/*isPlainWord && currentWord.length() > 2 &&*/ isMisspelled(currentWord))
+ doHighlighting(SpellcheckError,currentPos, currentWord.length());
+ }
+ currentWord = "";
+}
+
+QDict<int> KBabelHighlighter::dict(50021);
+
+bool KBabelHighlighter::isMisspelled(const QString& wordRaw)
+{
+ // We have to treat ampersands (like in "&go" or "g&o") in a special way.
+ // they must not break the word. And we cannot change the parameter, as
+ // then the highlight would be one character short. So we have to copy the
+ // word first.
+ QString word = wordRaw;
+ kdDebug(KBABEL) << "isampersand: checking (raw):" << word << endl;
+ word.replace("&", "" );
+ kdDebug(KBABEL) << "isMisspelled: checking: " << word << endl;
+
+ // Normally isMisspelled would look up a dictionary and return
+ // true or false, but kspell is asynchronous and slow so things
+ // get tricky...
+
+ // "dict" is used as a cache to store the results of KSpell
+ if (!dict.isEmpty() && dict[word] == NotOkay)
+ return true;
+ if (!dict.isEmpty() && dict[word] == Okay)
+ return false;
+
+ // there is no 'spelt correctly' signal so default to Okay
+ kdDebug(KBABEL) << "Adding word " << word << endl;
+ dict.replace(word, Okay);
+ mSpell->checkWord(word, false);
+ return false;
+}
+
+void KBabelHighlighter::slotMisspelling(const QString & originalword,
+ const QStringList & suggestions, unsigned int)
+{
+ kdDebug(KBABEL) << "Misspelled " << originalword << ", " << suggestions << endl;
+ dict.replace( originalword, NotOkay );
+
+ // this is slow but since kspell is async this will have to do for now
+ highlight();
+}
+
+void KBabelHighlighter::setSpellChecker( KSpell* spell )
+{
+ if( mSpell )
+ {
+ disconnect(mSpell, SIGNAL(misspelling(const QString &, const QStringList &, unsigned int)),
+ this, SLOT(slotMisspelling(const QString &, const QStringList &, unsigned int)));
+
+ // cleanup the cache
+ dict.clear();
+ }
+
+ mSpell = spell;
+
+ if( mSpell )
+ {
+ connect(mSpell, SIGNAL(misspelling(const QString &, const QStringList &, unsigned int)),
+ this, SLOT(slotMisspelling(const QString &, const QStringList &, unsigned int)));
+
+ // wait for KSpell to startup correctly
+ kapp->processEvents(500);
+ }
+
+ highlight();
+}
+
+void KBabelHighlighter::setSyntaxHighlighting( bool enable )
+{
+ syntaxHighlighting = enable;
+
+ // update highlighting
+ highlight();
+}
+#include "kbhighlighting.moc"
diff --git a/kbabel/kbabel/kbhighlighting.h b/kbabel/kbabel/kbhighlighting.h
new file mode 100644
index 00000000..91a6202d
--- /dev/null
+++ b/kbabel/kbabel/kbhighlighting.h
@@ -0,0 +1,104 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002 by Marco Wegner <mail@marcowegner.de>
+ (C) 2003 TrollTech AS
+ (C) 2003 Lukas Tinkl <lukas@kde.org>
+ (C) 2003-2005 Stanislav Visnovsky <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+
+#ifndef KBHIGHLIGHTING_H
+#define KBHIGHLIGHTING_H
+
+#include <qmemarray.h>
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qguardedptr.h>
+
+class KSpell;
+class QColor;
+class QString;
+class QTextEdit;
+
+class KBabelHighlighter : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum HighlightType {
+ Normal = 0,
+ Tag,
+ Entity,
+ CFormat,
+ Masked,
+ Accel,
+ Error,
+ SpellcheckError
+ };
+
+ KBabelHighlighter( QTextEdit * edit, KSpell *spell );
+
+ void setHighlightColor( HighlightType type, QColor color );
+ void setHasErrors( bool err );
+ void setSpellChecker( KSpell* spell);
+
+ bool isMisspelled(const QString& word);
+
+ public slots:
+ void highlight( );
+ void setSyntaxHighlighting( bool enable );
+
+ protected slots:
+ void slotMisspelling (const QString & originalword,
+ const QStringList & suggestions, unsigned int pos);
+
+ private:
+ void doHighlighting( HighlightType type, int pos, int length );
+ void readSettings( );
+ void flushCurrentWord();
+
+ private:
+ QTextEdit * _edit;
+ bool syntaxHighlighting;
+
+ QStringList regexps;
+ QMemArray<QColor> colors;
+
+ bool _hasErrors;
+ QString accelMarker;
+
+ static QDict<int> dict;
+ QGuardedPtr<KSpell> mSpell;
+ QString currentWord;
+ int currentPos;
+ bool alwaysEndsWithSpace;
+};
+
+#endif // KBHIGHLIGHTING_H
diff --git a/kbabel/kbabel/lo16-app-kbabel.png b/kbabel/kbabel/lo16-app-kbabel.png
new file mode 100644
index 00000000..98ee2659
--- /dev/null
+++ b/kbabel/kbabel/lo16-app-kbabel.png
Binary files differ
diff --git a/kbabel/kbabel/lo32-app-kbabel.png b/kbabel/kbabel/lo32-app-kbabel.png
new file mode 100644
index 00000000..8d52961b
--- /dev/null
+++ b/kbabel/kbabel/lo32-app-kbabel.png
Binary files differ
diff --git a/kbabel/kbabel/main.cpp b/kbabel/kbabel/main.cpp
new file mode 100644
index 00000000..40c28926
--- /dev/null
+++ b/kbabel/kbabel/main.cpp
@@ -0,0 +1,612 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 by Matthias Kiefer <matthias.kiefer@gmx.de>
+ 2002-2005 by Stanislav Visnovsky <visnovsky@kde.org>
+ Copyright (C) 2006 by Nicolas GOUTTE <goutte@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#include "kbabel.h"
+#include "kbabeliface.h"
+#include "kbprojectmanager.h"
+#include "catalog.h"
+#include "kbabelsplash.h"
+#include "findoptions.h"
+
+#include "version.h"
+
+#include <dcopclient.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kuniqueapplication.h>
+#include <kwin.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtimer.h>
+
+class KBabelInterface : public KBabelIface
+{
+public:
+ KBabelInterface();
+
+ virtual void openURL(QCString url, QCString package, WId window, int newWindow);
+ virtual void openURL(QCString url, QCString package, WId window, int newWindow, QCString projectFile);
+ virtual void openTemplate(QCString openFilename, QCString saveFilename, QCString package, int newWindow );
+ virtual void openTemplate(QCString openFilename, QCString saveFilename, QCString package, int newWindow, QCString projectFile );
+ virtual void gotoFileEntry(QCString url, QCString msgid);
+ virtual void gotoFileEntry(QCString url, QCString package, int msgid);
+ virtual void gotoFileEntry(QCString url, QCString package, int msgid, QCString projectFile);
+ virtual bool findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave);
+ virtual bool replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int ask, int askForNextFile, int askForSave);
+ virtual bool findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave, QCString project );
+ virtual bool replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int ask, int askForNextFile, int askForSave, QCString project );
+ virtual void spellcheck(QStringList fileList);
+private:
+ KBabelMW* findInstance( const KURL& url, const QString& project, const QString& package) const;
+};
+
+
+class KBabelApp : public KUniqueApplication
+{
+public:
+ KBabelApp();
+ virtual ~KBabelApp();
+
+ virtual int newInstance();
+
+private:
+ KBabelInterface *kbInterface;
+};
+
+KBabelApp::KBabelApp()
+ : KUniqueApplication()
+{
+ kbInterface = new KBabelInterface;
+}
+
+KBabelApp::~KBabelApp()
+{
+ delete kbInterface;
+}
+
+int KBabelApp::newInstance()
+{
+ bool first=true;
+ if(KBabelMW::memberList && !KBabelMW::memberList->isEmpty())
+ {
+ first=false;
+ }
+
+ // see if we are starting with session management
+#if KDE_IS_VERSION(3,3,0)
+ if (!restoringSession())
+#else
+ if (!isRestored() || !first)
+#endif
+ {
+ kdDebug () << "Suspending DCOP" << endl;
+ kapp->dcopClient()->suspend();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ QTimer timer;
+ QWidget *splash=0;
+ bool showSplash=args->isSet("splash");
+
+ if( showSplash && first )
+ {
+ setOverrideCursor(KCursor::waitCursor());
+ splash = new KBabelSplash();
+ splash->show();
+ timer.start(4000,true);
+ }
+
+ QString projectFile=args->getOption("project");
+ if( !projectFile.isEmpty() )
+ {
+ QFileInfo fi(projectFile);
+ projectFile = fi.absFilePath();
+ }
+ else
+ {
+ projectFile = KBabel::ProjectManager::defaultProjectName();
+ kdDebug(KBABEL) << "Using the default project Project: " << projectFile << endl;
+ }
+
+ kdDebug() << "Project: " << projectFile << endl;
+ QCString msgid=args->getOption("gotomsgid");
+ if(!msgid.isEmpty() && args->count() > 0)
+ {
+ kdDebug(KBABEL) << "gotomsgid" << endl;
+ QString m = QString::fromLocal8Bit(msgid);
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+ kbInterface->gotoFileEntry(args->url(0).url().local8Bit(),m.utf8());
+ }
+ else
+ {
+ // no session.. just start up normally
+ KBabelMW *widget=0;
+ if(args->count() > 0)
+ {
+ KURL u = args->url(0);
+ widget=KBabelMW::winForURL(u,projectFile);
+ }
+
+ if(!widget)
+ widget=KBabelMW::emptyWin(projectFile);
+
+ if(!widget)
+ widget=new KBabelMW(projectFile);
+
+ while(timer.isActive()) // let the user admire the splash screen ;-)
+ processEvents();
+
+ widget->show();
+ for (int i=0; i < args->count(); i++)
+ {
+ widget->open( args->url(i) , QString::null, i != 0 );
+ }
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+ }
+
+
+ args->clear();
+
+ if(splash)
+ {
+ delete KBabelSplash::instance;
+ }
+ if(showSplash)
+ {
+ KApplication::restoreOverrideCursor();
+ /*
+ KMessageBox::information(0,
+ "This is a development version of KBabel!\n"
+ "Please double check the files you edit "
+ "and save with this version for correctness.\n"
+ "Please report any bug you find to kiefer@kde.org.\n"
+ "Thanks.", "Warning");
+ */
+ }
+ }
+
+ return 0;
+}
+
+KBabelInterface::KBabelInterface()
+ : DCOPObject("KBabelIFace")
+{
+}
+
+void KBabelInterface::openURL(QCString url, QCString package, WId window, int newWindow)
+{
+ openURL(url,package,window,newWindow, KBabel::ProjectManager::defaultProjectName().local8Bit());
+}
+
+void KBabelInterface::openURL(QCString url, QCString package, WId window, int newWindow, QCString projectFile)
+{
+ const QString project( QString::fromLocal8Bit( projectFile ) );
+
+ kdDebug() << "openURL " << url << endl;
+
+ KURL u(QString::fromLocal8Bit(url));
+
+ kdDebug () << "Suspending DCOP" << endl;
+ kapp->dcopClient()->suspend();
+
+ KBabelMW *kb = KBabelMW::winForURL(u,project);
+ if(kb)
+ {
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ }
+ else
+ {
+ KMainWindow *mw = 0;
+ if(KMainWindow::memberList && !KMainWindow::memberList->isEmpty())
+ mw=KMainWindow::memberList->first();
+
+ // first, try to lookup correct winid
+ while( mw ) {
+ if( mw->inherits("KBabelMW") && mw->winId() == window)
+ {
+ kb = static_cast<KBabelMW*>(mw);
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ kb->open(u, QString::fromUtf8(package),newWindow);
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+
+ return ;
+ }
+ mw = KMainWindow::memberList->next();
+ }
+
+ // now, the empty window
+ kb = KBabelMW::emptyWin(projectFile);
+ if (kb)
+ {
+ // here, we don't care about "open in new window", because
+ // it's empty
+ KWin::setActiveWindow(kb->topLevelWidget()->winId());
+ kb->projectOpen(projectFile);
+ kb->open(u,QString::fromUtf8(package),false);
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+
+ return;
+ }
+
+ if(KMainWindow::memberList && !KMainWindow::memberList->isEmpty())
+ mw=KMainWindow::memberList->first();
+
+ while( mw ) {
+ if( mw->inherits("KBabelMW") && static_cast<KBabelMW*>(mw)->project()==project)
+ {
+ kb = static_cast<KBabelMW*>(mw);
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ kb->open(u, QString::fromUtf8(package),newWindow);
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+
+ return ;
+ }
+ mw = KMainWindow::memberList->next();
+ }
+
+ if( !mw )
+ {
+ kb = new KBabelMW(project);
+ kb->show();
+ } else kb = static_cast<KBabelMW*>(mw);
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ kb->open(u,QString::fromUtf8(package),newWindow);
+ }
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+}
+
+void KBabelInterface::openTemplate(QCString openFilename, QCString saveFilename, QCString package, int newWindow)
+{
+ openTemplate(openFilename, saveFilename, package, newWindow, KBabel::ProjectManager::defaultProjectName().local8Bit());
+}
+
+void KBabelInterface::openTemplate(QCString openFilename, QCString saveFilename, QCString package, int newWindow, QCString projectFile)
+{
+ const QString project( QString::fromLocal8Bit( projectFile ) );
+
+ const KURL u( QString::fromLocal8Bit( saveFilename ) );
+ const KURL t( QString::fromLocal8Bit( openFilename ) );
+
+ kdDebug () << "Suspending DCOP" << endl;
+ kapp->dcopClient()->suspend();
+
+ KBabelMW *kb = KBabelMW::winForURL(u, project);
+ if(kb)
+ {
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ }
+ else
+ {
+ KMainWindow *mw = 0;
+ if(KMainWindow::memberList && !KMainWindow::memberList->isEmpty())
+ mw=KMainWindow::memberList->first();
+
+ if(mw && mw->inherits("KBabelMW") && static_cast<KBabelMW*>(mw)->project()==project)
+ {
+ kb = static_cast<KBabelMW*>(mw);
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ kb->projectOpen(projectFile);
+ kb->openTemplate(t,u,QString::fromUtf8(package),newWindow);
+ }
+ else
+ {
+ kb = new KBabelMW(project);
+ kb->show();
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ kb->openTemplate(t,u,QString::fromUtf8(package));
+ }
+ }
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+}
+
+void KBabelInterface::gotoFileEntry(QCString url, QCString m)
+{
+ const KURL u( QString::fromLocal8Bit( url ) );
+ KBabelMW *kb = findInstance( u, KBabel::ProjectManager::defaultProjectName(), QString() );
+
+ if(!kb) return;
+
+ QString msgid = QString::fromUtf8(m);
+ int index = kb->m_view->catalog()->indexForMsgid(msgid);
+ if(index >= 0)
+ {
+ KBabel::DocPosition pos;
+ pos.item=index;
+ pos.form=0;
+ kb->m_view->gotoEntry(pos);
+ }
+}
+
+void KBabelInterface::gotoFileEntry(QCString url, QCString package, int m)
+{
+ gotoFileEntry(url, package, m, KBabel::ProjectManager::defaultProjectName().local8Bit() );
+}
+
+void KBabelInterface::gotoFileEntry(QCString url, QCString package, int m, QCString projectFile)
+{
+ const KURL u ( QString::fromLocal8Bit( url ) );
+ const QString p ( QString::fromUtf8( package ) ); // ### VERIFY encoding!
+ KBabelMW *kb = findInstance( u, projectFile, p );
+
+ if(!kb) return;
+
+ KBabel::DocPosition pos;
+ pos.item=m;
+ pos.form=0;
+ kb->m_view->gotoEntry(pos);
+}
+
+bool KBabelInterface::findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave)
+{
+ // no project given, open with default project
+ return findInFile ( fileSource, url, findStr, caseSensitive,
+ wholeWords, isRegExp, inMsgid, inMsgstr, inComment, ignoreAccelMarker, ignoreContextInfo,
+ askForNextFile, askForSave,
+ KBabel::ProjectManager::defaultProjectName().utf8() );
+}
+
+bool KBabelInterface::findInFile(QCString fileSource, QCString url,
+ QString findStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int askForNextFile, int askForSave, QCString project )
+{
+ kdDebug(KBABEL) << "findInFile (" <<fileSource<< "): " << url << " for " << findStr << endl;
+
+ const KURL u( QString::fromLocal8Bit( url ) );
+ KBabelMW *kb = findInstance( u, QString::fromLocal8Bit(project), QString() );
+
+ if(!kb) return false;
+
+ KBabel::FindOptions options;
+ options.findStr = findStr;
+ options.caseSensitive = (caseSensitive>0);
+ options.fromCursor = false;
+ options.backwards = false;
+ options.wholeWords = (wholeWords>0);
+ options.isRegExp = (isRegExp>0);
+ options.inMsgid = (inMsgid>0);
+ options.inMsgstr = (inMsgstr>0);
+ options.inComment = (inComment>0);
+ options.ignoreAccelMarker = (ignoreAccelMarker>0);
+ options.ignoreContextInfo = (ignoreContextInfo>0);
+ options.askForNextFile = (askForNextFile>0);
+ options.askForSave = (askForSave>0);
+ kb->m_view->findInFile(fileSource, options);
+
+ return true;
+}
+
+bool KBabelInterface::replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int ask, int askForNextFile, int askForSave)
+{
+ return replaceInFile( fileSource, url,
+ findStr, replaceStr, caseSensitive, wholeWords, isRegExp,
+ inMsgid, inMsgstr, inComment, ignoreAccelMarker, ignoreContextInfo,
+ ask, askForNextFile, askForSave,
+ KBabel::ProjectManager::defaultProjectName().utf8() );
+}
+
+bool KBabelInterface::replaceInFile(QCString fileSource, QCString url,
+ QString findStr, QString replaceStr, int caseSensitive, int wholeWords, int isRegExp,
+ int inMsgid, int inMsgstr, int inComment,
+ int ignoreAccelMarker, int ignoreContextInfo, int ask, int askForNextFile, int askForSave,
+ QCString project )
+{
+ kdDebug(KBABEL) << "replaceInFile (" <<fileSource<< "): " << url << " for " << findStr << endl;
+
+ const KURL u ( QString::fromLocal8Bit( url ) );
+ KBabelMW *kb = findInstance( u, QString::fromLocal8Bit(project), QString() );
+
+ if( !kb ) return false;
+
+ KBabel::ReplaceOptions options;
+ options.findStr = findStr;
+ options.replaceStr = replaceStr;
+ options.caseSensitive = (caseSensitive>0);
+ options.fromCursor = false;
+ options.backwards = false;
+ options.wholeWords = (wholeWords>0);
+ options.isRegExp = (isRegExp>0);
+ options.inMsgid = (inMsgid>0);
+ options.inMsgstr = (inMsgstr>0);
+ options.inComment = (inComment>0);
+ options.ignoreAccelMarker = (ignoreAccelMarker>0);
+ options.ignoreContextInfo = (ignoreContextInfo>0);
+ options.ask = (ask>0);
+ options.askForNextFile = (askForNextFile>0);
+ options.askForSave = (askForSave>0);
+ kb->m_view->replaceInFile(fileSource, options);
+
+ return true;
+}
+
+void KBabelInterface::spellcheck(QStringList fileList)
+{
+ // ### FIXME: the default project might use the wrong language!
+ KBabelMW *kb = findInstance( KURL(), KBabel::ProjectManager::defaultProjectName(), QString() );
+ kb->show();
+ kb->spellcheckMoreFiles( fileList );
+}
+
+KBabelMW* KBabelInterface::findInstance( const KURL& url, const QString& project, const QString& package) const
+{
+ kdDebug () << "Suspending DCOP" << endl;
+ kapp->dcopClient()->suspend();
+
+ KBabelMW *kb = 0;
+ if( !url.isEmpty() )
+ {
+ kb = KBabelMW::winForURL( url, project );
+
+ if(kb)
+ {
+ KWin::activateWindow(kb->topLevelWidget()->winId());
+ }
+ }
+
+ if( !kb )
+ {
+ kb = KBabelMW::emptyWin(project);
+ if( !kb )
+ {
+ kb = new KBabelMW(project);
+ }
+ else
+ {
+ kb->projectOpen(project);
+ }
+
+ kb->show();
+ if ( !url.isEmpty() )
+ kb->open( url, package, false );
+ }
+
+ kdDebug () << "Resuming DCOP" << endl;
+ kapp->dcopClient()->resume();
+
+ return kb;
+}
+
+static KCmdLineOptions options[] =
+{
+ {"gotomsgid <msgid>",I18N_NOOP("Go to entry with msgid <msgid>"),0},
+ {"nosplash",I18N_NOOP("Disable splashscreen at startup"),0},
+ {"project <configfile>",I18N_NOOP("File to load configuration from"),0},
+ {"+[file]",I18N_NOOP("Files to open"),0},
+ KCmdLineLastOption
+};
+
+
+int main(int argc, char **argv)
+{
+ KAboutData about("kbabel",I18N_NOOP("KBabel"),VERSION,
+ I18N_NOOP("An advanced PO file editor"),KAboutData::License_GPL,
+ I18N_NOOP("(c) 1999,2000,2001,2002,2003,2004,2005,2006 The KBabel developers"),0,"http://kbabel.kde.org");
+
+ about.addAuthor("Matthias Kiefer",I18N_NOOP("Original author"),"kiefer@kde.org");
+ about.addAuthor("Wolfram Diestel"
+ ,I18N_NOOP("Wrote diff algorithm, fixed KSpell and gave a lot "
+ "of useful hints."),"wolfram@steloj.de");
+ about.addAuthor("Andrea Rizzi",I18N_NOOP("Wrote the dictionary plugin "
+ "for searching in a database and some other code.")
+ ,"rizzi@kde.org");
+ about.addAuthor("Stanislav Visnovsky",I18N_NOOP("Current maintainer, porting to KDE3/Qt3.")
+ ,"visnovsky@kde.org");
+ about.addAuthor("Marco Wegner",I18N_NOOP("Bug fixes, KFilePlugin for PO files, CVS support, mailing files")
+ ,"dubbleu@web.de");
+ about.addAuthor("Asgeir Frimannsson",I18N_NOOP("Translation List View")
+ ,"asgeirf@redhat.com");
+ about.addAuthor("Nicolas Goutte", I18N_NOOP("Current maintainer"), "goutte@kde.org");
+
+ about.addCredit("Claudiu Costin",I18N_NOOP("Wrote documentation and sent "
+ "many bug reports and suggestions for improvements.")
+ ,"claudiuc@geocities.com");
+ about.addCredit("Thomas Diehl",I18N_NOOP("Gave many suggestions for the GUI "
+ "and the behavior of KBabel. He also contributed the beautiful splash screen.")
+ ,"thd@kde.org");
+ about.addCredit("Stephan Kulow",I18N_NOOP("Helped keep KBabel up to date "
+ "with the KDE API and gave a lot of other help."),"coolo@kde.org");
+ about.addCredit("Stefan Asserhall",I18N_NOOP("Implemented XML validation/highlighting "
+ "plus other small fixes.") ,"stefan.asserhall@telia.com");
+ about.addCredit("Dwayne Bailey",I18N_NOOP("Various validation plugins.")
+ ,"dwayne@translate.org.za");
+ about.addCredit("SuSE GmbH"
+ ,I18N_NOOP("Sponsored development of KBabel for a while.")
+ ,"suse@suse.de","http://www.suse.de");
+ about.addCredit("Trolltech", I18N_NOOP("KBabel contains code from Qt"), 0, "http://www.trolltech.com");
+
+ about.addCredit("Eva Brucherseifer", I18N_NOOP("String distance algorithm implementation"), "eva@kde.org");
+
+ about.addCredit("Albert Cervera Areny", I18N_NOOP("Error list for current entry, regexp data tool"), "albertca@hotpop.com");
+
+ about.addCredit("Nick Shaforostoff", I18N_NOOP("Word-by-word string difference algorithm implementation"), "shafff@ukr.net");
+
+ // Initialize command line args
+ KCmdLineArgs::init(argc, argv, &about);
+
+ // Tell which options are supported
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ // Add options from other components
+ KUniqueApplication::addCmdLineOptions();
+
+
+ if(!KUniqueApplication::start())
+ {
+ return 0;
+ }
+
+ KBabelApp app;
+
+ if( app.isRestored() )
+ {
+ RESTORE(KBabelMW)
+ }
+
+ return app.exec();
+}
diff --git a/kbabel/kbabel/mymultilineedit.cpp b/kbabel/kbabel/mymultilineedit.cpp
new file mode 100644
index 00000000..820d493e
--- /dev/null
+++ b/kbabel/kbabel/mymultilineedit.cpp
@@ -0,0 +1,1668 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2001-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ Alt+123 feature idea taken from KOffice by David Faure <david@mandrakesoft.com>.
+ Word wrap support by Jarno Elonen <elonen@iki.fi>, 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+
+#include "mymultilineedit.h"
+#include "editcmd.h"
+#include "resources.h"
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qvaluelist.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qclipboard.h>
+#include <qapplication.h>
+#include <qdragobject.h>
+//#include <private/qrichtext_p.h>
+#include <qpopupmenu.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kmessagebox.h>
+#include <kstdaccel.h>
+
+#include "kbhighlighting.h"
+
+using namespace KBabel;
+
+MyMultiLineEdit::MyMultiLineEdit(int ID, QWidget* parent,const char* name)
+ :KTextEdit(parent,name), emitUndo(true),
+ _firstChangedLine(0),
+ _lastChangedLine(0),
+ _lastParagraph(0),
+ _lastParagraphOffset(0),
+ _lastSelectionStart(-1),
+ _lastSelectionEnd(-1),
+ _dontUpdate(false), _myID (ID),
+ _menu(0), _overwrite(false)
+{
+ setUndoRedoEnabled(false); // we handle this ourselves
+ setWordWrap( WidgetWidth );
+ viewport()->setAcceptDrops( false ); // we need our parent to get drops
+
+ connect(this, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
+}
+
+void MyMultiLineEdit::onSelectionChanged()
+{
+ kdDebug(KBABEL) << "MyMultiLineEdit::onSelectionChanged" << endl;
+ int parFrom, parTo, indexFrom, indexTo;
+ if ( hasSelectedText() ) {
+ getSelection( &parFrom, &indexFrom, &parTo, &indexTo );
+ kdDebug(KBABEL) << "parFrom=" << parFrom << "indexFrom=" << indexFrom << "parTo=" << parTo << "indexTo=" << indexTo << endl;
+ _lastSelectionStart = beginOfMarkedText();
+ }
+ else
+ {
+ _lastSelectionStart = -1; // no selection
+ _lastSelectionEnd = -1;
+ }
+
+ //kdDebug(KBABEL) << "_lastSelectionStart=" << _lastSelectionStart << endl;
+}
+
+void MyMultiLineEdit::processCommand(EditCommand* cmd, bool undo)
+{
+ if(cmd->terminator()!=0)
+ return;
+
+ DelTextCmd* delcmd = (DelTextCmd*) cmd;
+ bool ins = true;
+ if (delcmd->type() == EditCommand::Delete )
+ ins = undo;
+ else if (delcmd->type() == EditCommand::Insert )
+ ins = !undo;
+ else
+ {
+ return;
+ }
+
+ // avoid duplicate update of catalog
+ bool oldEmitUndo = emitUndo;
+ emitUndo = false;
+
+ QPalette _visibleHighlight( palette() );
+ QPalette _invisibleHighlight( palette() );
+ QColorGroup newcg( colorGroup() );
+ newcg.setColor( QColorGroup::HighlightedText, newcg.text() );
+ newcg.setColor( QColorGroup::Highlight, newcg.base() );
+ if( hasFocus() ) _invisibleHighlight.setActive( newcg );
+ else _invisibleHighlight.setInactive( newcg );
+ setPalette( _invisibleHighlight );
+
+ if(delcmd->offset <= (int)_lastParagraphOffset)
+ {
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+ }
+
+ if ( ins )
+ {
+ int row, col;
+
+ offset2Pos( delcmd->offset, row, col );
+ setCursorPosition( row, col );
+
+ _firstChangedLine=row;
+ if(delcmd->str.find("\n")>0 )_lastChangedLine=row+delcmd->str.contains("\n");
+ else _lastChangedLine=row;
+
+ KTextEdit::insert( delcmd->str );
+
+ offset2Pos( delcmd->offset+delcmd->str.length(), row, col );
+ setCursorPosition( row, col);
+ }
+ else
+ { // del
+
+ int row, col, rowEnd, colEnd;
+
+ offset2Pos( delcmd->offset, row, col );
+ offset2Pos( delcmd->offset + delcmd->str.length(), rowEnd, colEnd );
+
+ setSelection( row, col, rowEnd, colEnd, 0 );
+ _firstChangedLine=_lastChangedLine=row;
+ KTextEdit::removeSelectedText();
+ }
+
+
+ setPalette( _visibleHighlight );
+
+ emitUndo = oldEmitUndo;
+
+ emitCursorPosition();
+}
+
+int MyMultiLineEdit::beginOfLastMarkedText()
+{
+ if ( _lastSelectionStart != -1 )
+ return _lastSelectionStart;
+ else
+ return currentIndex();
+}
+
+int MyMultiLineEdit::endOfLastMarkedText()
+{
+ if ( _lastSelectionEnd != -1 )
+ return _lastSelectionEnd;
+ else
+ return currentIndex();
+}
+
+int MyMultiLineEdit::beginOfMarkedText()
+{
+ int beginX=0;
+ int beginY=0;
+ int endX=0;
+ int endY=0;
+
+ int pos=-1;
+
+ getSelection(&beginY,&beginX,&endY,&endX);
+ if( hasSelectedText() )
+ {
+ pos = pos2Offset(beginY,beginX);
+ }
+
+ return pos;
+}
+
+void MyMultiLineEdit::emitCursorPosition()
+{
+ int line=0;
+ int col=0;
+ getCursorPosition(&line,&col);
+
+ emit cursorPositionChanged(line, col);
+}
+
+void MyMultiLineEdit::wheelEvent(QWheelEvent *e)
+{
+ e->ignore();
+}
+
+void MyMultiLineEdit::focusInEvent(QFocusEvent *e)
+{
+ KTextEdit::focusInEvent(e);
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::contentsContextMenuEvent( QContextMenuEvent * e)
+{
+ e->accept();
+ if( _menu ) _menu->exec( e->globalPos() );
+}
+
+QPopupMenu * MyMultiLineEdit::createPopupMenu()
+{
+ return _menu;
+}
+
+QPopupMenu * MyMultiLineEdit::createPopupMenu(const QPoint &)
+{
+ return 0;
+}
+
+void MyMultiLineEdit::setContextMenu( QPopupMenu * menu )
+{
+ _menu = menu;
+}
+
+void MyMultiLineEdit::doKeyboardAction( KeyboardAction action )
+{
+ int row,col;
+ getCursorPosition(&row, &col);
+
+ switch( action ) {
+ case ActionDelete:
+ _firstChangedLine=_lastChangedLine=row;
+ my_del(); break;
+
+ case ActionBackspace:
+ _firstChangedLine=_lastChangedLine=row;
+ my_backspace(); break;
+
+ case ActionReturn:
+ if( emitUndo)
+ emit signalUndoCmd( new InsTextCmd(currentIndex(), "\n", _myID) );
+ break;
+
+ case ActionKill:
+ _firstChangedLine=_lastChangedLine=row;
+ if(emitUndo)
+ {
+ int x,y;
+ getCursorPosition( &x, &y );
+ QString s = text(x);
+ if( y < (int)s.length()-1 ) // not the end of paragraph
+ {
+ QString delText = s.mid( y, s.length()-y-1);
+ emit signalUndoCmd( new DelTextCmd(currentIndex(), delText, _myID ) );
+ } else
+ if( x < paragraphs()-1 ) // not the end of text
+ emit signalUndoCmd( new DelTextCmd(currentIndex(), "\n", _myID ) );
+ }
+ break;
+ default: break;
+ }
+
+ KTextEdit::doKeyboardAction( action );
+
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::setText(const QString& s)
+{
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+ // workaround, since insert does not interpret markup
+ setTextFormat( Qt::PlainText );
+ _firstChangedLine=_lastChangedLine=0;
+ KTextEdit::setText(s);
+ setTextFormat( Qt::AutoText );
+ // now the number of lines is known, let's do highlight
+ _lastChangedLine=paragraphs();
+ emit textChanged();
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::insertAt( const QString & s, int line, int col, bool mark )
+{
+ // it will invoke insert, don't need to send InsTextCmd
+ KTextEdit::insertAt(s,line,col);
+
+ // code from QMultiLineEdit
+ if( mark )
+ setSelection( line, col, line, col + s.length(), 0 );
+ // end of copied code
+
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::insert( const QString & text, bool indent, bool checkNewLine, bool removeSelected )
+{
+ int row,col;
+
+ bool noSelectionRemoved = true;
+ setUpdatesEnabled(false);
+ if( removeSelected && hasSelectedText() )
+ {
+ int endRow,endCol;
+ getSelection(&row,&col,&endRow,&endCol);
+
+ if( row < (int)_lastParagraph )
+ {
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+ }
+
+ _firstChangedLine=_lastChangedLine=row;
+ removeSelectedText();
+ noSelectionRemoved = false;
+ }
+
+ getCursorPosition(&row,&col);
+ _firstChangedLine=row;
+ _lastChangedLine=row;
+
+ if( emitUndo)
+ {
+ emit signalUndoCmd( new BeginCommand(-1,UndefPart));
+ // reimplemented overwrite
+ if( _overwrite && noSelectionRemoved)
+ {
+ doKeyboardAction( ActionDelete );
+ }
+
+ emit signalUndoCmd( new InsTextCmd(currentIndex(), text, _myID) );
+ emit signalUndoCmd( new EndCommand(-1,UndefPart));
+ }
+
+ int n=text.find("\n");
+ if( n > 0 ) _lastChangedLine+=n;
+
+ // setup palettes
+
+ QPalette _visibleHighlight( palette() );
+ QPalette _invisibleHighlight( palette() );
+ QColorGroup newcg( colorGroup() );
+ newcg.setColor( QColorGroup::HighlightedText, newcg.text() );
+ newcg.setColor( QColorGroup::Highlight, newcg.base() );
+ if( hasFocus() ) _invisibleHighlight.setActive( newcg );
+ else _invisibleHighlight.setInactive( newcg );
+ setPalette( _invisibleHighlight );
+ KTextEdit::insert(text, indent, checkNewLine, removeSelected);
+ setPalette( _visibleHighlight );
+
+ setUpdatesEnabled(true);
+
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::removeLine ( int line )
+{
+ kdDebug(KBABEL) << "removeLine invoked" << endl;
+
+ KTextEdit::removeParagraph(line);
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::clear()
+{
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+
+ _dontUpdate=true;
+
+ QString s = text();
+ if( !s.isEmpty() && emitUndo ) {
+ emit signalUndoCmd( new BeginCommand(-1,UndefPart) );
+ emit signalUndoCmd( new DelTextCmd(0,s,_myID) );
+ emit signalUndoCmd( new EndCommand(-1,UndefPart) );
+ }
+
+ KTextEdit::clear();
+
+ _dontUpdate=false;
+
+ _firstChangedLine=_lastChangedLine=0;
+ emitCursorPosition();
+}
+
+
+void MyMultiLineEdit::my_backspace()
+{
+
+ int cursorY, cursorX;
+ getCursorPosition( &cursorY, &cursorX );
+
+ if( hasSelectedText())
+ {
+ Q_ASSERT( "backspace: This should never happen, why is not invoked removeSelectedText()?");
+ }
+ else if(! (cursorY==0 && cursorX==0) )
+ {
+ if(emitUndo)
+ {
+ int offset = currentIndex();
+
+ QString s= text(cursorY);
+ if(cursorX != 0)
+ {
+ QString delTxt(s[cursorX-1]);
+ emit signalUndoCmd(new DelTextCmd(offset-1,delTxt,_myID));
+ }
+ else if( cursorY > 0 || cursorX > 0 ) // not at the beginning
+ {
+ emit signalUndoCmd(new DelTextCmd(offset-1,"\n",_myID));
+ }
+ }
+ }
+}
+
+void MyMultiLineEdit::my_del()
+{
+
+ int cursorY, cursorX;
+ getCursorPosition( &cursorY, &cursorX );
+
+ if( hasSelectedText())
+ {
+ Q_ASSERT( "del: This should never happen, why is not invoked removeSelectedText()?");
+ }
+ else if(! (cursorY==paragraphs()-1 && cursorX==paragraphLength( cursorY )) )
+ {
+ if(emitUndo)
+ {
+ int offset = pos2Offset(cursorY, cursorX);
+
+ QString s=text(cursorY);
+ if(cursorX != (int)s.length()-1)
+ {
+ QString delTxt(s[cursorX]);
+ emit signalUndoCmd(new DelTextCmd(offset,delTxt,_myID));
+ }
+ else if( cursorY < (int)paragraphs()-1 || ( (cursorY == (int)paragraphs()-1) && (cursorX < (int)text( paragraphs()-1 ).length()-1 ) ) )// !atEnd() )
+ {
+ emit signalUndoCmd(new DelTextCmd(offset,"\n",_myID));
+ }
+ }
+ }
+}
+
+void MyMultiLineEdit::removeSelectedText(int selNum)
+{
+ if( selNum != 0 )
+ {
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+
+ KTextEdit::removeSelectedText(selNum);
+ }
+ else
+ {
+ int paraFrom, idxFrom, paraTo, idxTo;
+ KTextEdit::getSelection( &paraFrom, &idxFrom, &paraTo, &idxTo );
+
+ if( paraFrom < (int)_lastParagraph )
+ {
+ _lastParagraph=0;
+ _lastParagraphOffset=0;
+ }
+
+ int offset = pos2Offset( paraFrom, idxFrom );
+ emit signalUndoCmd(new DelTextCmd( offset, selectedText(), _myID ) );
+ KTextEdit::removeSelectedText(selNum);
+ }
+
+ emitCursorPosition();
+}
+
+void MyMultiLineEdit::paste()
+{
+ KTextEdit::paste();
+ emitCursorPosition();
+}
+
+int MyMultiLineEdit::currentIndex()
+{
+ int para; // paragraph of current position
+ int index; // index in the current paragraph
+
+ KTextEdit::getCursorPosition(&para,&index);
+
+ return pos2Offset( para, index );
+}
+
+
+void MyMultiLineEdit::offset2Pos(int offset, int &paragraph, int &index) const
+{
+ if (offset <= 0)
+ {
+ paragraph = 0;
+ index = 0;
+ return;
+ }
+ else
+ {
+ int charsLeft = offset;
+ int i;
+
+ for( i = 0; i < paragraphs(); ++i )
+ {
+ if (paragraphLength( i ) < charsLeft)
+ charsLeft -= paragraphLength( i );
+ else
+ {
+ paragraph = i;
+ index = charsLeft;
+ return;
+ }
+ --charsLeft;
+ }
+
+ paragraph = i-1;
+ index = charsLeft;
+ return;
+ }
+}
+
+int MyMultiLineEdit::pos2Offset(uint paragraph, uint index)
+{
+ paragraph = QMAX( QMIN( (int)paragraph, paragraphs() - 1), 0 ); // Sanity check
+ index = QMAX( QMIN( (int)index, paragraphLength( paragraph )), 0 ); // Sanity check
+
+ {
+ uint lastI;
+ lastI = paragraphLength( paragraph );
+ uint i = 0;
+ uint tmp = 0;
+
+ if( paragraph>=_lastParagraph )
+ {
+ tmp = _lastParagraphOffset;
+ i = _lastParagraph;
+ }
+
+ for( ;i < paragraph ; i++ )
+ {
+ tmp += paragraphLength( i ) + 1;
+ }
+
+ _lastParagraphOffset=tmp;
+ _lastParagraph=paragraph;
+
+ tmp += QMIN( lastI, index );
+
+ return tmp;
+ }
+}
+
+void MyMultiLineEdit::setReadOnly(bool on)
+{
+ // I want this backgroundmode, also when readonly==true
+ if(on)
+ {
+ setBackgroundMode(PaletteBase);
+ }
+
+ QTextEdit::setReadOnly(on);
+}
+
+void MyMultiLineEdit::setOverwriteMode( bool b )
+{
+ _overwrite = b;
+}
+
+/*******************************************************************************/
+MsgMultiLineEdit::MsgMultiLineEdit(int ID, KSpell* spell, QWidget* parent,const char* name)
+ :MyMultiLineEdit(ID, parent,name),
+ _quotes(false),
+ _cleverEditing(false),
+ _highlightBg(false),
+ _spacePoints(false),
+ _bgColor(colorGroup().base().dark(110)),
+ _textColor(KGlobalSettings::textColor()),
+ _errorColor(Qt::red),
+ _currentColor(KGlobalSettings::textColor()),
+ _whitespace(0),
+ _hlSyntax(true),
+ _quoteColor(Qt::darkGreen),
+ _unquoteColor(Qt::red),
+ _cformatColor(Qt::blue),
+ _accelColor(Qt::darkMagenta),
+ _showDiff(false),
+ _diffUnderlineAdd(true),
+ _diffStrikeOutDel(true),
+ _diffAddColor(Qt::darkGreen),
+ _diffDelColor(Qt::darkRed),
+ _currentUnicodeNumber(0),
+ highlighter(0),
+ _tagStartPara(0), _tagStartIndex(0), _tagEndPara(0), _tagEndIndex(0)
+{
+ diffPos.setAutoDelete(true);
+ diffPos.clear();
+
+ _whitespace = new QPixmap(2,2,-1,QPixmap::BestOptim);
+ _whitespace->fill(_textColor);
+ _errorWhitespace = new QPixmap(2,2,-1,QPixmap::BestOptim);
+ _errorWhitespace->fill(_errorColor);
+
+ _whitespaceNB = new QPixmap(3,3,-1,QPixmap::BestOptim);
+ _whitespaceNB->fill();
+ _errorWhitespaceNB = new QPixmap(3,3,-1,QPixmap::BestOptim);
+ _errorWhitespaceNB->fill();
+
+ QPainter p(_whitespaceNB);
+ p.setPen( _textColor );
+ p.drawEllipse(_whitespaceNB->rect());
+
+ QPainter q(_errorWhitespaceNB);
+ q.setPen( _errorColor );
+ q.drawEllipse(_errorWhitespaceNB->rect());
+
+ // this will setup bitBlt pixmaps
+ setFont( font() );
+ highlighter = new KBabelHighlighter( this, spell );
+ connect( this, SIGNAL( signalSyntaxHighlightingChanged( bool ) ), highlighter, SLOT( setSyntaxHighlighting( bool ) ) );
+
+ connect( this, SIGNAL( selectionChanged() ), this, SLOT( paintSpacePoints() ) );
+ connect( this, SIGNAL( cursorPositionChanged( int, int ) ), this, SLOT( paintSpacePoints(int, int) ) );
+ connect( this, SIGNAL( textChanged() ), this, SLOT( emittedTextChanged() ) );
+}
+
+MsgMultiLineEdit::~MsgMultiLineEdit ()
+{
+ if(highlighter)
+ delete highlighter;
+}
+
+void MsgMultiLineEdit::setText(const QString& s)
+{
+ QString str = s;
+
+ if(_showDiff)
+ {
+ diffPos.clear();
+ int lines = s.contains('\n');
+ diffPos.resize(lines+1);
+
+ QStringList lineList = QStringList::split('\n',s,true);
+
+ int lineCounter=-1;
+ bool haveAdd=false;
+ bool haveDel=false;
+ bool multiline=false;
+ QStringList::Iterator it;
+ for(it = lineList.begin(); it != lineList.end(); ++it)
+ {
+ lineCounter++;
+
+ int lastPos=0;
+ bool atEnd=false;
+
+ while(!atEnd)
+ {
+ int addPos=-1;
+ int delPos=-1;
+
+ if(haveAdd && multiline)
+ {
+ addPos=0;
+ }
+ else
+ {
+ addPos = (*it).find("<KBABELADD>",lastPos);
+ }
+
+ if(haveDel && multiline)
+ {
+ delPos=0;
+ }
+ else
+ {
+ delPos = (*it).find("<KBABELDEL>",lastPos);
+ }
+
+ if(delPos >= 0 && addPos >= 0)
+ {
+ if(delPos <= addPos)
+ {
+ haveDel=true;
+ haveAdd=false;
+ }
+ else
+ {
+ haveDel=false;
+ haveAdd=true;
+ }
+ }
+ else if(delPos >= 0)
+ {
+ haveDel=true;
+ haveAdd=false;
+ }
+ else if(addPos >= 0)
+ {
+ haveDel=false;
+ haveAdd=true;
+ }
+ else
+ {
+ atEnd=true;
+ haveAdd=false;
+ haveDel=false;
+ }
+
+ DiffInfo di;
+ di.begin=-1;
+
+ if(haveAdd)
+ {
+ if(!multiline)
+ {
+ (*it).remove(addPos,11);
+ }
+
+ int endPos = (*it).find("</KBABELADD>",addPos);
+ if(endPos < 0)
+ {
+ endPos = (*it).length();
+ atEnd=true;
+ multiline=true;
+ }
+ else
+ {
+ (*it).remove(endPos,12);
+ haveAdd=false;
+ multiline=false;
+ }
+
+ lastPos=endPos;
+
+ di.begin=addPos;
+ di.end=endPos-1;
+ di.add=true;
+ }
+ else if(haveDel)
+ {
+ if(!multiline)
+ {
+ (*it).remove(delPos,11);
+ }
+
+ int endPos = (*it).find("</KBABELDEL>",delPos);
+ if(endPos < 0)
+ {
+ endPos = (*it).length();
+ atEnd=true;
+ multiline=true;
+ }
+ else
+ {
+ (*it).remove(endPos,12);
+ haveDel=false;
+ multiline=false;
+ }
+
+ lastPos=endPos;
+
+ di.begin=delPos;
+ di.end=endPos-1;
+ di.add=false;
+ }
+
+ if(di.begin >= 0)
+ {
+ QValueList<DiffInfo> *list = diffPos[lineCounter];
+ if(!list)
+ {
+ list = new QValueList<DiffInfo>;
+ diffPos.insert(lineCounter,list);
+ }
+
+ list->append(di);
+ }
+
+ }
+ }
+
+ QRegExp reg("</?KBABELADD>");
+ str.replace(reg,"");
+ reg.setPattern("</?KBABELDEL>");
+ str.replace(reg,"");
+ }
+
+ MyMultiLineEdit::setText(str);
+ paintSpacePoints();
+}
+
+void MsgMultiLineEdit::setQuotes(bool on)
+{
+ _quotes=on;
+ update();
+}
+
+void MsgMultiLineEdit::setCleverEditing(bool on)
+{
+ _cleverEditing=on;
+}
+
+
+void MsgMultiLineEdit::setHighlightBg(bool on)
+{
+ _highlightBg=on;
+ update();
+}
+
+
+void MsgMultiLineEdit::setBgColor(const QColor& color)
+{
+ _bgColor=color;
+
+ if(_highlightBg)
+ update();
+}
+
+void MsgMultiLineEdit::setSpacePoints(bool on)
+{
+ _spacePoints=on;
+
+ update();
+}
+
+void MsgMultiLineEdit::setHighlightSyntax(bool on)
+{
+ _hlSyntax=on;
+
+ emit signalSyntaxHighlightingChanged (on);
+
+ update();
+}
+
+void MsgMultiLineEdit::setHighlightColors(const QColor& quoteColor, const QColor& unquoteColor
+ , const QColor& cformatColor, const QColor& accelColor, const QColor& tagColor)
+{
+ _quoteColor=quoteColor;
+ _unquoteColor=unquoteColor;
+ _cformatColor=cformatColor;
+ _accelColor=accelColor;
+ _tagColor=tagColor;
+
+ highlighter->setHighlightColor( KBabelHighlighter::Tag, tagColor );
+ highlighter->setHighlightColor( KBabelHighlighter::Entity, accelColor );
+ highlighter->setHighlightColor( KBabelHighlighter::CFormat, cformatColor );
+ highlighter->setHighlightColor( KBabelHighlighter::Masked, quoteColor );
+
+ update();
+}
+
+
+void MsgMultiLineEdit::setFont(const QFont& font)
+{
+ KTextEdit::setFont(font);
+
+ // we don't need to calculate a special offset for non-breaking space, since
+ // they are very similar in size
+ QFontMetrics fm(font);
+ _wsOffsetX = QMAX(fm.width(' ')/2-2,1);
+ _wsOffsetY = QMAX(fm.height()/2-1,0);
+
+ repaint();
+}
+
+void MsgMultiLineEdit::setDiffDisplayMode(bool addUnderline, bool delStrikeOut)
+{
+ _diffUnderlineAdd = addUnderline;
+ _diffStrikeOutDel = delStrikeOut;
+
+ if(_showDiff)
+ update();
+}
+
+void MsgMultiLineEdit::setDiffColors(const QColor& addColor
+ , const QColor& delColor)
+{
+ _diffAddColor = addColor;
+ _diffDelColor = delColor;
+
+ if(_showDiff)
+ update();
+}
+
+void MsgMultiLineEdit::setTextColor(const QColor &color )
+{
+ QPalette p( palette() );
+ QColorGroup newcg( colorGroup() );
+ newcg.setColor( QColorGroup::Text, color );
+ if( hasFocus() ) p.setActive( newcg );
+ else p.setInactive( newcg );
+ setPalette( p );
+ _textColor = color;
+ highlighter->setHighlightColor( KBabelHighlighter::Normal, color );
+}
+
+void MsgMultiLineEdit::setErrorColor(const QColor &color )
+{
+ _errorColor = color;
+ highlighter->setHighlightColor( KBabelHighlighter::Error, color );
+}
+
+void MsgMultiLineEdit::setCurrentColor(const TextColor color)
+{
+ if( color == NormalColor ) {
+ _currentColor = _textColor;
+ highlighter->setHasErrors( false );
+ } else {
+ _currentColor = _errorColor;
+ highlighter->setHasErrors( true );
+ }
+
+ /*
+ setUpdatesEnabled(false);
+ // need to block signals (especially textChanged() to avoid recursion with KBabelView::autoCheck
+ blockSignals(true);
+ selectAll();
+ setColor( _currentColor );
+ removeSelection();
+ setColor(_currentColor);
+ blockSignals(false);
+ setUpdatesEnabled(true);
+ */
+ forceUpdate();
+}
+
+void MsgMultiLineEdit::setSpellChecker(KSpell* spell)
+{
+ highlighter->setSpellChecker(spell);
+}
+
+void MsgMultiLineEdit::paintSpacePoints(int, int )
+{
+ paintSpacePoints();
+}
+
+void MsgMultiLineEdit::paintSpacePoints()
+{
+ QRect r;
+ QPainter painter(viewport() );
+ const QFontMetrics& fm = fontMetrics();
+
+ int paranum = paragraphAt(QPoint(contentsX(), contentsY()));
+
+ if( _spacePoints )
+ {
+ int curpara = paranum;
+ painter.setPen( _currentColor );
+ QPixmap* ws, *wsnb;
+
+ if( _currentColor== _errorColor )
+ {
+ ws = _errorWhitespace;
+ wsnb = _errorWhitespaceNB;
+ }
+ else
+ {
+ ws = _whitespace;
+ wsnb = _whitespaceNB;
+ }
+
+ while( curpara < paragraphs())
+ {
+ if ( paragraphRect( curpara ).top() > contentsY()+visibleHeight()) break;
+
+ const QString& s = text(curpara);
+ int i = s.find( " " );
+ while( (i >= 0) && (i < (int)s.length()-1) ) // -1 because text will end by EOLN
+ {
+ QPixmap* pm = ( s.at(i).unicode() == 0x00A0U ) ? wsnb : ws;
+ QRect r = mapToView( curpara, i );
+ r.moveBy( r.width()/2, (r.height() - fm.descent())/2 );
+ r.moveBy( -pm->rect().width()/2, -pm->rect().height()/2-1 );
+ bitBlt(viewport(), r.topLeft(), pm, pm->rect(), Qt::CopyROP);
+ i = s.find( " ", i+1 );
+ }
+ ++curpara;
+ }
+ }
+
+ if( _quotes )
+ {
+ QFontMetrics fm( font());
+ QRect qs = fm.boundingRect("\"");
+
+ for( int curpara = paranum; curpara < paragraphs() ; curpara++ )
+ {
+ r = paragraphRect(curpara);
+ if( r.y() > contentsY()+visibleHeight() ) break;
+
+ painter.drawText( QPoint( 0, mapToView( curpara, 0 ).top()) +
+ QPoint(0, qs.height() + 4), "\""); // 4 = hardcoded margin in QT
+ painter.drawText( mapToView( curpara, QMAX( 0,
+ ((int)text( curpara ).length())-1)).topRight() +
+ QPoint(0, qs.height() + 4), "\""); // 4 = hardcoded margin in QT
+ }
+ }
+
+ if( _showDiff && (!_diffUnderlineAdd || !_diffStrikeOutDel) )
+ {
+ if( paragraphs() == (int)diffPos.size() ) // sanity check
+ {
+ painter.setRasterOp( Qt::AndROP );
+ for( int curpara = paranum; curpara < paragraphs() ; curpara++ )
+ {
+ r = paragraphRect(curpara);
+ if( r.y() > contentsY()+visibleHeight() ) break;
+
+ QValueList<DiffInfo> *list = diffPos[curpara];
+ if(list)
+ {
+ QValueList<DiffInfo>::ConstIterator it;
+ for(it = list->begin(); it != list->end(); ++it)
+ {
+ QRect beg = mapToView( curpara, (*it).begin );
+ QRect end = mapToView( curpara, (*it).end );
+
+ QColor* c = 0;
+ if( (*it).add && !_diffUnderlineAdd)
+ c = &_diffAddColor;
+ else if(!(*it).add && !_diffStrikeOutDel)
+ c = &_diffDelColor;
+
+ if ( c != 0 )
+ {
+ // Single or multiple lines?
+ if ( beg.top() == end.top())
+ {
+ painter.fillRect( QRect( beg.topLeft(),
+ QPoint( end.right(), end.bottom())), *c );
+ }
+ else
+ {
+ painter.fillRect( QRect(
+ beg.topLeft(),
+ QPoint( r.right(), beg.bottom())), *c );
+ if( end.top()-beg.bottom() > 2 ) {
+ // there is a line, not only thin space
+ painter.fillRect( QRect(
+ QPoint( r.left(), beg.bottom()),
+ QPoint( r.right(), end.top())), *c );
+ }
+ painter.fillRect( QRect(
+ QPoint( r.left(), end.top()),
+ QPoint( end.right(), end.bottom())), *c );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if( _showDiff && (_diffUnderlineAdd || _diffStrikeOutDel) )
+ {
+ if( paragraphs() == (int)diffPos.size() ) // sanity check
+ {
+ for( int curpara = paranum; curpara < paragraphs() ; curpara++ )
+ {
+ r = paragraphRect(curpara);
+ if( r.y() > contentsY()+visibleHeight() ) break;
+
+ QValueList<DiffInfo> *list = diffPos[curpara];
+ if(list)
+ {
+ QPen addPen(_diffAddColor,2);
+ QPen delPen(_diffDelColor,2);
+ QValueList<DiffInfo>::ConstIterator it;
+ for(it = list->begin(); it != list->end(); ++it)
+ {
+ QRect beg = mapToView( curpara, (*it).begin );
+ QRect end = mapToView( curpara, (*it).end );
+
+ QPen* p = 0;
+ int dy = 0;
+ if( (*it).add && _diffUnderlineAdd)
+ p = &addPen;
+ else if(!(*it).add && _diffStrikeOutDel)
+ {
+ p = &delPen;
+ dy = fm.ascent()/2-1;
+ }
+
+ if ( p != 0 )
+ {
+ painter.setPen( *p );
+
+ // Single or multiple lines?
+ if ( beg.top() == end.top())
+ painter.drawLine(
+ beg.topLeft() + QPoint(0, fm.ascent()-dy),
+ end.topRight()+ QPoint(0, fm.ascent()-dy));
+ else
+ {
+ int y = beg.top() + fm.ascent();
+ painter.drawLine(
+ QPoint(beg.left(), y),
+ QPoint(r.right(), y));
+ y += fm.lineSpacing();
+ while (y < end.top() + fm.ascent())
+ {
+ painter.drawLine(
+ QPoint(r.left(), y),
+ QPoint(r.right(), y));
+ y += fm.lineSpacing();
+ }
+ painter.drawLine(
+ QPoint(r.left(), end.top() + fm.ascent()),
+ QPoint(end.right(), end.top() + fm.ascent()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void MsgMultiLineEdit::repaint()
+{
+ highlight();
+ MyMultiLineEdit::repaint();
+}
+
+void MsgMultiLineEdit::forceUpdate()
+{
+ _firstChangedLine=0;
+ _lastChangedLine=paragraphs()-1;
+ highlighter->highlight();
+ MyMultiLineEdit::repaint();
+}
+
+void MsgMultiLineEdit::ensureCursorVisible()
+{
+ if( isUpdatesEnabled() )
+ MyMultiLineEdit::ensureCursorVisible();
+}
+
+void MsgMultiLineEdit::highlight()
+{
+/* if( _dontUpdate ) return;
+
+ QColor bg;
+ if( _highlightBg ) bg = _bgColor;
+ else bg = colorGroup().base();
+
+ for( int i = 0 ; i < paragraphs() ; i++ )
+ setParagraphBackgroundColor( i, bg );
+
+
+ if(_hlSyntax)
+ {
+ blockSignals(true); // block signals to avoid recursion
+ setUpdatesEnabled(false);
+ int cursorParagraph, cursorIndex;
+
+ getCursorPosition( &cursorParagraph, &cursorIndex );
+
+ // setup new colors
+
+ uint i;
+
+ QRegExp markup("(\\\\)|(\")|(\\\\[abfnrtv'\"\?\\\\])|(\\\\\\d+)|(\\\\x[\\dabcdef]+)"
+ "|(%[\\ddioxXucsfeEgGphln]+)|(&[^\\s])|(&[\\w-]+;)");
+
+ for( i = QMAX(_firstChangedLine,0) ; i < QMIN(_lastChangedLine+1,(uint)paragraphs()) ; i++ ) {
+
+ QString line=text(i);
+
+ //remove old highlighting
+ setSelection(i,0,i,line.length());
+ setColor( _currentColor );
+ removeSelection();
+
+ QColor colorToUse;
+
+ int index=0;
+ index=markup.search( line, index );
+ while(index>=0)
+ {
+ switch( line[index].latin1() )
+ {
+ case '\\':
+ if( markup.matchedLength() == 1 ) colorToUse=_unquoteColor;
+ else colorToUse=_quoteColor;
+ break;
+ case '\"':
+ colorToUse=_unquoteColor;
+ break;
+ case '%':
+ colorToUse=_cformatColor;
+ break;
+ case '&':
+ colorToUse=_accelColor;
+ break;
+ }
+
+ setSelection( i, index, i, index+markup.matchedLength(), 0);
+ setColor( colorToUse );
+ removeSelection();
+ index=markup.search( line, index+markup.matchedLength() );
+ }
+ }
+
+ // Color XML and HTML tags
+
+ int tagindex=0;
+ int taglength=0;
+ int lineindex=0;
+ uint index=0;
+ int startPara, endPara, startIndex, endIndex;
+ QString t= text();
+
+ if(_lastParagraph <= _firstChangedLine)
+ {
+ index=_lastParagraph;
+ lineindex=_lastParagraphOffset;
+ }
+
+ for( ; index<_firstChangedLine ; index++)
+ lineindex+=paragraphLength(index)+1;
+
+ QRegExp re("<.*>");
+ re.setMinimal(true);
+
+ if( _firstChangedLine >0 )
+ {
+ QColor c;
+ QFont f;
+ VerticalAlignment v;
+ getFormat(_firstChangedLine-1, paragraphLength(_firstChangedLine-1)-1, &f, &c, &v);
+ QString l = text(_firstChangedLine-1);
+ if( c==_tagColor && !l.endsWith(">") ) // hope _tagColor will be different than other colors
+ {
+ QRegExp endtag("[^<]*>");
+ tagindex=endtag.search(t, lineindex);
+ taglength=endtag.matchedLength();
+ } else {
+ tagindex=re.search(t, lineindex);
+ taglength=re.matchedLength();
+ }
+ } else {
+ tagindex=re.search( t, lineindex );
+ taglength=re.matchedLength();
+ }
+
+ while( tagindex >= 0 && (int)index<paragraphs())
+ {
+ while( tagindex>=lineindex && index<_lastChangedLine+2)
+ lineindex+=paragraphLength(index++)+1;
+ if(index==_lastChangedLine+2) break;
+ lineindex-=paragraphLength(index-1);
+ lineindex--;
+ index--;
+
+ startPara=index;
+ startIndex=tagindex-lineindex;
+
+ tagindex+=taglength;
+
+ while( tagindex>=lineindex && (int)index<paragraphs())
+ lineindex+=paragraphLength(index++)+1;
+ lineindex-=paragraphLength(index-1);
+ lineindex--;
+ index--;
+
+ endPara=index;
+ endIndex=tagindex-lineindex;
+
+ setSelection( startPara, startIndex, endPara, endIndex, 0 );
+ setColor( _tagColor );
+ removeSelection();
+
+ if(index>_lastChangedLine) break;
+ tagindex=re.search( t, tagindex );
+ taglength=re.matchedLength();
+ }
+
+ setCursorPosition( cursorParagraph, cursorIndex );
+ setColor( _textColor );
+ setUpdatesEnabled(true);
+ blockSignals(false); // block signals to avoid recursion
+ updateContents();
+ }
+ ensureCursorVisible();
+ */
+}
+
+void MsgMultiLineEdit::drawContents( QPainter *painter, int clipx, int clipy, int clipw, int cliph )
+{
+ MyMultiLineEdit::drawContents( painter, clipx, clipy, clipw, cliph );
+ paintSpacePoints();
+}
+
+void MsgMultiLineEdit::paintEvent( QPaintEvent *event )
+{
+ MyMultiLineEdit::paintEvent( event );
+ paintSpacePoints();
+}
+
+QRect MsgMultiLineEdit::mapToView( int para, int index )
+{
+ if( para < 0 || para > paragraphs() ||
+ index < 0 || index > paragraphLength(para) )
+ return QRect(); //invalid rectangle
+
+ const QFontMetrics& fm = fontMetrics();
+ const QString& paratext = text(para);
+
+ // Find index of the first character on the same line as parameter
+ // 'index' using binary search. Very fast, even for long texts.
+ int linestart = 0;
+ int indexline = lineOfChar( para, index );
+ if ( indexline > 0 )
+ {
+ int min = 0, max = index;
+ int i = (min + max)/2;
+ int iline = lineOfChar( para, i );
+ while ( iline != indexline-1 ||
+ lineOfChar( para, i+1 ) != indexline )
+ {
+ Q_ASSERT( min != max && min != i && max != i );
+ if ( iline < indexline )
+ min = i;
+ else
+ max = i;
+ i = (min + max)/2;
+ iline = lineOfChar( para, i );
+ }
+ linestart = i+1;
+ }
+ Q_ASSERT( linestart >= 0 );
+
+ int linewidth;
+
+ // if the tag is not valid, easy
+ if( (_tagStartPara == _tagEndPara) && (_tagStartIndex == _tagEndIndex) ) {
+ linewidth = fm.width( paratext.mid( linestart, index-linestart ));
+ } else {
+ int tso = pos2Offset( _tagStartPara, _tagStartIndex );
+ int teo = pos2Offset( _tagEndPara, _tagEndIndex );
+ int off = pos2Offset( para, index );
+
+ if( off < tso ) {
+ // it is surely before the tag
+ linewidth = fm.width( paratext.mid( linestart, index-linestart ));
+ } else if( off >= teo ) {
+ // it is surely after the tag
+
+ // is it on the same line as the end of the tag?
+ if( _tagEndPara < para || lineOfChar( _tagEndPara, _tagEndIndex ) < indexline ) {
+ // no tag on the line, no bold
+ linewidth = fm.width( paratext.mid( linestart, index-linestart ));
+ } else {
+ QFont f( font() );
+ f.setBold( true );
+ QFontMetrics bfm( f );
+ // is tag single displayed line?
+ if( _tagStartPara == _tagEndPara
+ && lineOfChar( _tagStartPara, _tagStartIndex ) == lineOfChar( _tagEndPara, _tagEndIndex ) )
+ {
+ // yes, count the non-bold before the tag start
+ linewidth = fm.width( paratext.mid( linestart, _tagStartIndex-linestart ) )
+ + bfm.width( paratext.mid( _tagStartIndex, _tagEndIndex-_tagStartIndex ) );
+ }
+ else
+ {
+ // count the part of the tag itself
+ linewidth = bfm.width( paratext.mid( linestart, _tagEndIndex-linestart ) );
+ }
+
+ // add the rest from tag to the index
+ linewidth += fm.width( paratext.mid( _tagEndIndex, index-_tagEndIndex ) );
+ }
+ }
+ else {
+ // in tag
+ QFont f( font() );
+ f.setBold( true );
+ QFontMetrics bfm( f );
+ // is it the first line of the tag?
+ if( para == _tagStartPara && indexline == lineOfChar( _tagStartPara, _tagStartIndex ) ) {
+ // start of the line is normal
+ linewidth = fm.width( paratext.mid( linestart, _tagStartIndex-linestart ) )
+ + bfm.width( paratext.mid( _tagStartIndex, index-_tagStartIndex ) );
+ } else {
+ // whole is bold
+ linewidth = bfm.width( paratext.mid( linestart, index-linestart ) );
+ }
+ }
+ }
+
+ // FIXME as soon as it's possible to ask real margins from QTextEdit:
+ const int left_margin = 4;
+ // const int top_margin = 4;
+
+ QPainter painter( viewport());
+ const QRect& linerect = paragraphRect(para);
+ return QRect(
+ contentsToViewport( QPoint(
+ left_margin + linerect.left() + linewidth ,
+ /*top_margin + */linerect.top() + indexline * fm.lineSpacing() + fm.leading())),
+ QSize(
+ fm.charWidth( paratext, index ),
+ fm.lineSpacing()
+ ));
+}
+
+void MsgMultiLineEdit::keyPressEvent(QKeyEvent *e)
+{
+ if(!_cleverEditing || isReadOnly())
+ {
+ MyMultiLineEdit::keyPressEvent(e);
+ return;
+ }
+
+ KKey key( e );
+
+ if(e->key() == Key_Return || e->key() == Key_Enter)
+ {
+ emit signalUndoCmd(new BeginCommand(-1,UndefPart));
+
+ int row, col;
+ getCursorPosition(&row,&col);
+ QString str=text(row);
+
+ if(e->state() & ShiftButton)
+ {
+ if(col > 0 && !str.isEmpty())
+ {
+ if(str.at(col-1) == '\\' && !isMasked(&str,col-1))
+ {
+ insert("n",false);
+ }
+ else
+ {
+ insert("\\n",false);
+ }
+ }
+ else
+ {
+ insert("\\n",false);
+ }
+ }
+ else if(!(e->state() & ControlButton))
+ {
+ if(col > 0 && !str.isEmpty() && !str.at(col-1).isSpace())
+ {
+ if(str.at(col-1)=='\\' && !isMasked(&str,col-1))
+ {
+ insert("\\",false);
+ }
+
+ // if there is not a new line at the end
+ if(col < 2 || str.mid(col-2,2)!="\\n")
+ {
+ insert(" ",false);
+ }
+ }
+ else if(str.isEmpty())
+ {
+ insert("\\n",false);
+ }
+ }
+
+ if( !str.isEmpty())
+ {
+ // construct new event without modifiers
+ MyMultiLineEdit::keyPressEvent( new QKeyEvent(e->type(), e->key(), e->ascii(), 0,
+ e->text(), e->isAutoRepeat(), e->count() ) );
+ e->accept();
+ }
+
+ emit signalUndoCmd(new EndCommand(-1,UndefPart));
+ return;
+ }
+ else if(e->key() == Key_Tab)
+ {
+ insert("\\t",false);
+ emit textChanged();
+ e->accept();
+ return;
+ }
+ else if((e->key() == Key_Delete && !(e->state() & ControlButton))
+ || ((e->state() & ControlButton) && e->key() == Key_D) )
+ {
+ emit signalUndoCmd(new BeginCommand(-1,UndefPart));
+
+ if(!hasSelectedText())
+ {
+ int row, col;
+ getCursorPosition(&row,&col);
+ QString str=text(row);
+
+ if(!str.isEmpty() && col < (int)str.length() && str.at(col) == '\\'
+ && !isMasked(&str,col))
+ {
+ QString spclChars="abfnrtv'\"?\\";
+ if(col < (int)str.length()-1
+ && spclChars.contains(str.at(col+1)))
+ {
+ del();
+ }
+ }
+ }
+
+ del();
+
+ emit signalUndoCmd(new EndCommand(-1,UndefPart));
+ emit textChanged();
+ e->accept();
+ return;
+ }
+ else if(e->key() == Key_BackSpace
+ || ((e->state() & ControlButton) && e->key() == Key_H) )
+ {
+ emit signalUndoCmd(new BeginCommand(-1,UndefPart));
+
+ if(!hasSelectedText())
+ {
+ int row, col;
+ getCursorPosition(&row,&col);
+ QString str=text(row);
+
+ QString spclChars="abfnrtv'\"?\\";
+ if(!str.isEmpty() && col > 0 && spclChars.contains(str.at(col-1)))
+ {
+ if(col > 1 && str.at(col-2)=='\\' && !isMasked(&str,col-2))
+ {
+ MyMultiLineEdit::keyPressEvent(e);
+ }
+ }
+
+ }
+
+ MyMultiLineEdit::keyPressEvent(e);
+
+ emit signalUndoCmd(new EndCommand(-1,UndefPart));
+
+ e->accept();
+ return;
+ }
+ else if(e->text() == "\"")
+ {
+ emit signalUndoCmd(new BeginCommand(-1,UndefPart));
+
+ int row, col;
+ getCursorPosition(&row,&col);
+ QString str=text(row);
+
+ if(col == 0 || str.at(col-1) != '\\' || isMasked(&str,col-1) )
+ {
+ insert("\\\"",false);
+ }
+ else
+ {
+ insert("\"",false);
+ }
+
+ e->accept();
+
+ emit signalUndoCmd(new EndCommand(-1,UndefPart));
+ return;
+ }
+ else if(e->key() == Key_Space && ( e->state() & AltButton ) )
+ {
+ insert( QChar( 0x00a0U ) );
+ e->accept();
+ return;
+ }
+ // ALT+123 feature
+ else if(( e->state() & AltButton ) && e->text()[0].isDigit() )
+ {
+ QString text=e->text();
+ while ( text[0].isDigit() ) {
+ _currentUnicodeNumber = 10*_currentUnicodeNumber+(text[0].digitValue());
+ text.remove( 0, 1 );
+ }
+ }
+ else
+ {
+ MyMultiLineEdit::keyPressEvent(e);
+ }
+}
+
+void MsgMultiLineEdit::keyReleaseEvent(QKeyEvent* e)
+{
+ if ( e->key() == Key_Alt && _currentUnicodeNumber >= 32 )
+ {
+ QString text = QChar( _currentUnicodeNumber );
+ _currentUnicodeNumber=0;
+ insert( text );
+ }
+}
+
+void MsgMultiLineEdit::setDiffMode(bool on)
+{
+ _showDiff=on;
+
+ if(!on)
+ {
+ diffPos.clear();
+ }
+}
+
+bool MsgMultiLineEdit::isMasked(QString *str, uint col)
+{
+ if(col == 0 || !str)
+ return false;
+
+ uint counter=0;
+ int pos=col;
+
+ while(pos >= 0 && str->at(pos) == '\\')
+ {
+ counter++;
+ pos--;
+ }
+
+ return !(bool)(counter%2);
+}
+
+void MsgMultiLineEdit::emittedTextChanged()
+{
+ highlight();
+ paintSpacePoints();
+}
+
+void MsgMultiLineEdit::selectTag(int start, int length)
+{
+ setUpdatesEnabled(false);
+ setSelection( _tagStartPara, _tagStartIndex, _tagEndPara, _tagEndIndex);
+ setBold( false );
+
+ offset2Pos(start, _tagStartPara, _tagStartIndex);
+ offset2Pos(start+length, _tagEndPara, _tagEndIndex);
+
+ setSelection( _tagStartPara, _tagStartIndex, _tagEndPara, _tagEndIndex);
+ setBold( true );
+ setUpdatesEnabled(true);
+}
+
+#include "mymultilineedit.moc"
diff --git a/kbabel/kbabel/mymultilineedit.h b/kbabel/kbabel/mymultilineedit.h
new file mode 100644
index 00000000..30771610
--- /dev/null
+++ b/kbabel/kbabel/mymultilineedit.h
@@ -0,0 +1,307 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2001-2003 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef MYMULTILINEEDIT_H
+#define MYMULTILINEEDIT_H
+
+#include <ktextedit.h>
+#include <qptrvector.h>
+
+namespace KBabel
+{
+ class EditCommand;
+}
+
+class KBabelHighlighter;
+class KSpell;
+class QPixmap;
+
+class MyMultiLineEdit : public KTextEdit
+{
+ Q_OBJECT
+public:
+ MyMultiLineEdit(int ID,QWidget* parent,const char* name=0);
+
+ /**
+ applies cmd to the displayed text, but does not emit
+ signalUndoCommand
+ */
+ void processCommand(KBabel::EditCommand* cmd, bool undo=false);
+
+ /**
+ * @returns the position in text, where the marked text begins
+ * -1, if there is no marked text
+ */
+ int beginOfMarkedText();
+
+ /**
+ * @returns the position in text, where the last marked text began
+ * or the current cursor position if there was no marked text.
+ * This is used for getting the start position for a text replacement
+ */
+ int beginOfLastMarkedText();
+
+ /**
+ * @returns the position in text, where the last marked text ended
+ * or the current cursor position if there was no marked text.
+ * This is used for getting the end position for a text replacement
+ */
+ int endOfLastMarkedText();
+
+ virtual void insertAt ( const QString & s, int line, int col, bool mark = false );
+ virtual void removeLine ( int line );
+
+ int pos2Offset(uint paragraph, uint index);
+ void offset2Pos(int offset, int &row, int &col) const;
+ /**
+ * @returns the current position in text, where the cursor is
+ */
+
+ int currentIndex();
+ /**
+ * processes Del key
+ */
+ void my_del();
+ void my_backspace();
+
+ /**
+ * need to override deleting of popup menus :-(
+ */
+ void contentsContextMenuEvent( QContextMenuEvent *e );
+
+ /**
+ * need to reimplement overwrite mode :-(
+ */
+ bool isOverwriteMode() { return _overwrite; }
+
+public slots:
+
+ virtual void clear();
+ virtual void paste();
+ virtual void setReadOnly(bool on);
+ virtual void setContextMenu( QPopupMenu *menu );
+ virtual void setText(const QString& s);
+ virtual void doKeyboardAction( KeyboardAction action );
+ virtual void removeSelectedText(int selNum = 0);
+
+ virtual void onSelectionChanged();
+
+ /**
+ reimplemented overwrite mode, since QTextEdit handles this internally and does
+ not use any accessible virtual methods :-((.
+ */
+ virtual void setOverwriteMode(bool b);
+
+protected:
+
+ virtual void focusInEvent(QFocusEvent*);
+ virtual QPopupMenu *createPopupMenu();
+ virtual QPopupMenu *createPopupMenu(const QPoint &pos);
+
+ /* the parent handles this */
+ virtual void wheelEvent(QWheelEvent*);
+
+ bool emitUndo;
+
+ /* First and the last line of the last change. They are only approximate. Used for faster display
+ * highlighting etc.
+ */
+ uint _firstChangedLine;
+ uint _lastChangedLine;
+
+ /* This is a cache. _lastPragraphOffset always correctly corresponds to _lastParagraphOffset
+ */
+ uint _lastParagraph;
+ uint _lastParagraphOffset;
+
+ /* We save the last selection positions. This is needed when a tag is inserted to get the
+ left cursor position of the originally used selection */
+ int _lastSelectionStart;
+ int _lastSelectionEnd;
+
+ /* flag to skip any work on updating, since it will be more changes */
+ bool _dontUpdate;
+
+protected slots:
+ virtual void insert ( const QString & text, bool indent = FALSE, bool checkNewLine = TRUE, bool removeSelected = TRUE );
+ virtual void emitCursorPosition();
+
+signals:
+ void signalUndoCmd(KBabel::EditCommand*);
+ void signalSyntaxHighlightingChanged (bool enable);
+
+protected:
+ int _myID;
+
+private:
+ QPopupMenu *_menu;
+ bool _overwrite;
+};
+
+
+class MsgMultiLineEdit : public MyMultiLineEdit
+{
+ Q_OBJECT
+public:
+ enum TextColor { NormalColor, ErrorColor };
+
+ MsgMultiLineEdit(int ID, KSpell* spell=0, QWidget* parent=0,const char* name=0);
+ virtual ~MsgMultiLineEdit();
+
+ /** is displaying surrounding quotes enabled? */
+ bool quotes() const { return _quotes;}
+ /** enable or disable displaying of surrounding quotes */
+ void setQuotes(bool on);
+
+ /** is clever editing enabled? */
+ bool cleverEditing() const { return _cleverEditing; }
+ /** enable or disable clever editing */
+ void setCleverEditing(bool on);
+ /** is highlighting background enabled? */
+ bool highlightBg() const { return _highlightBg; }
+ /** enable or disable highlighting background*/
+ void setHighlightBg(bool on);
+ QColor bgColor() const { return _bgColor; }
+ void setBgColor(const QColor& color);
+
+ bool spacePoints() const { return _spacePoints; }
+ void setSpacePoints(bool on);
+
+ bool highlightSyntax() const { return _hlSyntax; }
+ void highlight();
+ void setHighlightSyntax(bool on);
+ void setHighlightColors(const QColor& quoteColor, const QColor& unquoteColor
+ , const QColor& cformatColor, const QColor& accelColor, const QColor& tagColor);
+
+ void setFont(const QFont& font);
+
+ void setDiffMode(bool on);
+ void setDiffDisplayMode(bool underlineAdded, bool strikeOutDeleted);
+ void setDiffColors(const QColor& addColor, const QColor& delColor);
+
+ void setTextColor(const QColor &color);
+ void setErrorColor(const QColor &color);
+
+ void setCurrentColor(const TextColor color);
+
+ void setSpellChecker(KSpell* spell);
+
+ void selectTag(int start, int length);
+
+public slots:
+ virtual void setText(const QString& s);
+ void paintSpacePoints();
+ void paintSpacePoints( int para, int pos ); // overloaded for signal QTextEdit::cursorPositionChanged
+
+ /**
+ * reimplemented to call highlight()
+ */
+ void repaint();
+ void forceUpdate();
+ void emittedTextChanged();
+
+ /**
+ * reimplemented to skip in case of disabled updates
+ */
+ void ensureCursorVisible();
+
+protected:
+ virtual void paintEvent (QPaintEvent * event );
+ virtual void drawContents( QPainter *painter, int clipx, int clipy, int clipw, int cliph );
+
+ virtual void keyPressEvent(QKeyEvent*);
+ virtual void keyReleaseEvent(QKeyEvent*);
+
+private:
+ /**
+ * Computes the pixel position in line which corresponds to
+ * character position xIndex
+ */
+ QRect mapToView( int para, int index );
+
+ /**
+ * tests if the character in string str at position col is masked with
+ * '\' by counting the number of '\' backwards
+ */
+ static bool isMasked(QString *str,uint col);
+
+private:
+ bool _quotes;
+ bool _cleverEditing;
+ bool _highlightBg;
+ bool _spacePoints;
+ QColor _bgColor;
+ QColor _textColor;
+ QColor _errorColor;
+ QColor _currentColor;
+
+ QPixmap* _whitespace;
+ QPixmap* _whitespaceNB;
+ QPixmap* _errorWhitespace;
+ QPixmap* _errorWhitespaceNB;
+
+ int _wsOffsetX;
+ int _wsOffsetY;
+
+ bool _hlSyntax;
+ QColor _quoteColor;
+ QColor _unquoteColor;
+ QColor _cformatColor;
+ QColor _accelColor;
+ QColor _tagColor;
+
+ struct DiffInfo
+ {
+ bool add;
+ int begin;
+ int end;
+ };
+
+ QPtrVector< QValueList<DiffInfo> > diffPos;
+ bool _showDiff;
+ bool _diffUnderlineAdd;
+ bool _diffStrikeOutDel;
+ QColor _diffAddColor;
+ QColor _diffDelColor;
+
+ // for Alt+123 feature
+ int _currentUnicodeNumber;
+
+ KBabelHighlighter * highlighter;
+
+ // next tag highlighting
+ int _tagStartPara, _tagStartIndex, _tagEndPara, _tagEndIndex;
+};
+
+#endif // MYMULTILINEEDIT_H
diff --git a/kbabel/kbabel/pics/Makefile.am b/kbabel/kbabel/pics/Makefile.am
new file mode 100644
index 00000000..b5108197
--- /dev/null
+++ b/kbabel/kbabel/pics/Makefile.am
@@ -0,0 +1,6 @@
+# Add all of your pixmaps here
+pics_DATA = broken.png missing.png needwork.png ok.png pref_identity.png \
+ splash.png noflag.png
+
+# This is where it will all be installed
+picsdir = $(kde_datadir)/kbabel/pics
diff --git a/kbabel/kbabel/pics/broken.png b/kbabel/kbabel/pics/broken.png
new file mode 100644
index 00000000..d0948e92
--- /dev/null
+++ b/kbabel/kbabel/pics/broken.png
Binary files differ
diff --git a/kbabel/kbabel/pics/missing.png b/kbabel/kbabel/pics/missing.png
new file mode 100644
index 00000000..e0311068
--- /dev/null
+++ b/kbabel/kbabel/pics/missing.png
Binary files differ
diff --git a/kbabel/kbabel/pics/needwork.png b/kbabel/kbabel/pics/needwork.png
new file mode 100644
index 00000000..e31413d8
--- /dev/null
+++ b/kbabel/kbabel/pics/needwork.png
Binary files differ
diff --git a/kbabel/kbabel/pics/noflag.png b/kbabel/kbabel/pics/noflag.png
new file mode 100644
index 00000000..5b6ad0c2
--- /dev/null
+++ b/kbabel/kbabel/pics/noflag.png
Binary files differ
diff --git a/kbabel/kbabel/pics/ok.png b/kbabel/kbabel/pics/ok.png
new file mode 100644
index 00000000..f2b731a0
--- /dev/null
+++ b/kbabel/kbabel/pics/ok.png
Binary files differ
diff --git a/kbabel/kbabel/pics/pref_identity.png b/kbabel/kbabel/pics/pref_identity.png
new file mode 100644
index 00000000..de7e1459
--- /dev/null
+++ b/kbabel/kbabel/pics/pref_identity.png
Binary files differ
diff --git a/kbabel/kbabel/pics/splash.png b/kbabel/kbabel/pics/splash.png
new file mode 100644
index 00000000..26f908c7
--- /dev/null
+++ b/kbabel/kbabel/pics/splash.png
Binary files differ
diff --git a/kbabel/kbabel/searchpreferences.ui b/kbabel/kbabel/searchpreferences.ui
new file mode 100644
index 00000000..5e002657
--- /dev/null
+++ b/kbabel/kbabel/searchpreferences.ui
@@ -0,0 +1,109 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>SearchPreferences</class>
+<author>Stanislav Visnovsky</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SearchPreferences</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_AutoSearch</cstring>
+ </property>
+ <property name="text">
+ <string>Au&amp;tomatically start search</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Automatically start search&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;If this is activated, the search is automatically started
+whenever you switch to another entry in the editor. You can
+choose where to search with the combo box &lt;b&gt;Default Dictionary&lt;/b&gt;.
+&lt;/p&gt;&lt;p&gt;You can also start searching manually by choosing an entry in
+the popup menu that appears either when clicking
+&lt;b&gt;Dictionaries-&gt;Find...&lt;/b&gt; or keeping the dictionary button
+in the toolbar pressed for a while.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>D&amp;efault dictionary:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>_kcfg_DefaultModule</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>_kcfg_DefaultModule</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Default Dictionary&lt;/b&gt;&lt;/p&gt;
+&lt;p&gt;Choose here where to search as default.
+This setting is used when searching is started automatically
+or when pressing the dictionary button in the toolbar.&lt;/p&gt;
+&lt;p&gt;You can configure the different dictionaries by selecting
+the desired dictionary from &lt;b&gt;Settings-&gt;Configure Dictionary&lt;/b&gt;.
+&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>91</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbabel/kbabel/sourceview.cpp b/kbabel/kbabel/sourceview.cpp
new file mode 100644
index 00000000..08c0f8a4
--- /dev/null
+++ b/kbabel/kbabel/sourceview.cpp
@@ -0,0 +1,75 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "sourceview.h"
+#include "context.h"
+
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+#include <kcursor.h>
+#include <klocale.h>
+
+#include "resources.h"
+#include "kbcatalog.h"
+
+using namespace KBabel;
+
+SourceView::SourceView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent,project)
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setResizeMode( QLayout::Minimum );
+
+ _contextView = new SourceContext (this, project);
+ layout->addWidget (_contextView);
+
+ connect(_catalog, SIGNAL(signalFileOpened(bool)), this, SLOT(setDisabled(bool)));
+}
+
+void SourceView::updateView()
+{
+ if (isVisible ())
+ {
+ // Note: we use Catalog::comment instead of Catalog::context as SourceContext::setContext has to repeat the major part of the code of Catalog::context, so SourceContext::setContext can do the whole job alone.
+ _contextView->setContext( _catalog->packageDir(), _catalog->packageName(), _catalog->comment(_currentIndex), _catalog->currentURL() );
+ }
+}
+
+void SourceView::setProject(KBabel::Project::Ptr project)
+{
+ KBCatalogView::setProject(project);
+ _contextView->setProject(project);
+}
+
+#include "sourceview.moc"
diff --git a/kbabel/kbabel/sourceview.h b/kbabel/kbabel/sourceview.h
new file mode 100644
index 00000000..8caeed35
--- /dev/null
+++ b/kbabel/kbabel/sourceview.h
@@ -0,0 +1,57 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004-2005 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef SOURCEVIEW_H
+#define SOURCEVIEW_H
+
+#include "kbcatalogview.h"
+
+class SourceContext;
+
+class SourceView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ SourceView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+public slots:
+ virtual void updateView();
+ virtual void setProject(KBabel::Project::Ptr project);
+
+private:
+ SourceContext* _contextView;
+};
+
+#endif // SOURCEVIEW_H
diff --git a/kbabel/kbabel/spelldlg.cpp b/kbabel/kbabel/spelldlg.cpp
new file mode 100644
index 00000000..49500e09
--- /dev/null
+++ b/kbabel/kbabel/spelldlg.cpp
@@ -0,0 +1,142 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#include "spelldlg.h"
+#include "spelldlgwidget.h"
+
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+
+#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+SpellDlg::SpellDlg(bool haveMarkedText,QWidget *parent,const char *name)
+ : KDialogBase(parent,name,true,i18n("Caption of dialog","Spelling")
+ , Ok|Cancel)
+{
+ setButtonOK(KGuiItem(i18n("&Spell Check"),"spellcheck"));
+
+ _mainWidget = new SpellDlgWidget(this);
+ setMainWidget(_mainWidget);
+
+ if(haveMarkedText)
+ {
+ _mainWidget->markedBtn->setChecked(true);
+ _mainWidget->defaultBtn->setChecked(false);
+ _mainWidget->defaultBtn->setEnabled(false);
+ }
+ else
+ {
+ _mainWidget->markedBtn->setEnabled(false);
+
+ KConfig *config = KGlobal::config();
+ KConfigGroupSaver cs(config,"SpellDlg");
+ QString what=config->readEntry("Default","All");
+
+ if(what=="All")
+ _mainWidget->allBtn->setChecked(true);
+ else if(what=="Current")
+ _mainWidget->currentBtn->setChecked(true);
+ else if(what=="Begin")
+ _mainWidget->beginBtn->setChecked(true);
+ else if(what=="End")
+ _mainWidget->endBtn->setChecked(true);
+ else
+ _mainWidget->allBtn->setChecked(true);
+
+ }
+
+}
+
+SpellDlg::~SpellDlg()
+{
+ if(_mainWidget->defaultBtn->isChecked())
+ {
+ KConfig *config=KGlobal::config();
+ KConfigGroupSaver cs(config,"SpellDlg");
+
+ QString what="All";
+ if(_mainWidget->endBtn->isChecked())
+ what="End";
+ else if(_mainWidget->beginBtn->isChecked())
+ what="Begin";
+ else if(_mainWidget->currentBtn->isChecked())
+ what="Current";
+
+ config->writeEntry("Default",what);
+ }
+}
+
+bool SpellDlg::all() const
+{
+ return _mainWidget->allBtn->isChecked();
+}
+
+bool SpellDlg::current() const
+{
+ return _mainWidget->currentBtn->isChecked();
+}
+
+bool SpellDlg::begin() const
+{
+ return _mainWidget->beginBtn->isChecked();
+}
+
+bool SpellDlg::end() const
+{
+ return _mainWidget->endBtn->isChecked();
+}
+
+bool SpellDlg::marked() const
+{
+ return _mainWidget->markedBtn->isChecked();
+}
+
+
+void SpellDlg::markedChecked(bool on)
+{
+ if(on)
+ {
+ _mainWidget->defaultBtn->setChecked(false);
+ }
+
+ _mainWidget->defaultBtn->setEnabled(!on);
+}
+
+bool SpellDlg::beginCurrent( ) const
+{
+ return _mainWidget->beginCurrentMsgBtn->isChecked( );
+}
+
+
+#include "spelldlg.moc"
diff --git a/kbabel/kbabel/spelldlg.h b/kbabel/kbabel/spelldlg.h
new file mode 100644
index 00000000..ea857777
--- /dev/null
+++ b/kbabel/kbabel/spelldlg.h
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef SPELLDLG_H
+#define SPELLDLG_H
+
+#include <kdialogbase.h>
+
+
+class SpellDlgWidget;
+
+class SpellDlg : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ SpellDlg(bool haveMarkedText, QWidget* parent, const char *name=0);
+ ~SpellDlg();
+
+ bool all() const;
+ bool current() const;
+ bool begin() const;
+ bool end() const;
+ bool marked() const;
+ bool beginCurrent() const;
+
+private slots:
+ void markedChecked(bool);
+
+private:
+ SpellDlgWidget *_mainWidget;
+};
+
+#endif // SPELLDLG_H
diff --git a/kbabel/kbabel/spelldlgwidget.ui b/kbabel/kbabel/spelldlgwidget.ui
new file mode 100644
index 00000000..fe5a5d0b
--- /dev/null
+++ b/kbabel/kbabel/spelldlgwidget.ui
@@ -0,0 +1,126 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>SpellDlgWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SpellDlgWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>388</width>
+ <height>262</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Choose What You Want to Spell Check</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check only the current message.</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>allBtn</cstring>
+ </property>
+ <property name="text">
+ <string>A&amp;ll messages</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check all translated messages of this file.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>currentBtn</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;urrent message only</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check only the current message.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>beginCurrentMsgBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Fro&amp;m beginning of current message to end of file</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>beginBtn</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;From beginning of file to cursor position</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check all text from the beginning of the file to the current cursor position.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>endBtn</cstring>
+ </property>
+ <property name="text">
+ <string>F&amp;rom cursor position to end of file</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check all text from the current cursor position to the end of the file.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>markedBtn</cstring>
+ </property>
+ <property name="text">
+ <string>S&amp;elected text only</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Spell check only the selected text.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>defaultBtn</cstring>
+ </property>
+ <property name="text">
+ <string>U&amp;se this selection as default</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Check this, to store the current selection as default selection.</string>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>allBtn</tabstop>
+ <tabstop>beginBtn</tabstop>
+ <tabstop>markedBtn</tabstop>
+ <tabstop>currentBtn</tabstop>
+ <tabstop>endBtn</tabstop>
+ <tabstop>defaultBtn</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbabel/kbabel/taglistview.cpp b/kbabel/kbabel/taglistview.cpp
new file mode 100644
index 00000000..8dedccea
--- /dev/null
+++ b/kbabel/kbabel/taglistview.cpp
@@ -0,0 +1,78 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+
+#include "taglistview.h"
+
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+#include <kcursor.h>
+#include <klistbox.h>
+#include <klocale.h>
+
+#include "kbcatalog.h"
+
+using namespace KBabel;
+
+TagListView::TagListView(KBCatalog* catalog,QWidget *parent, Project::Ptr project)
+ : KBCatalogView(catalog,parent,project)
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setResizeMode( QLayout::Minimum );
+
+ _tagBox = new KListBox (this, "taglist textview");
+
+ layout->addWidget (_tagBox);
+
+ connect(_tagBox,SIGNAL(selected(const QString&))
+ , this, SIGNAL(signalTagSelected(const QString&)));
+ connect(_tagBox,SIGNAL(highlighted(int))
+ , this, SIGNAL(signalHighlightedTagChanged(int)));
+
+ connect(_catalog, SIGNAL(signalFileOpened(bool))
+ , this, SLOT(setDisabled(bool)));
+}
+
+void TagListView::updateView()
+{
+ _tagBox->clear();
+ _tagBox->insertStringList(_catalog->tagList(_currentIndex));
+ _tagBox->setCurrentItem(0);
+}
+
+void TagListView::highlightTag(int index)
+{
+ _tagBox->setCurrentItem(index);
+}
+
+#include "taglistview.moc"
diff --git a/kbabel/kbabel/taglistview.h b/kbabel/kbabel/taglistview.h
new file mode 100644
index 00000000..0435e3ba
--- /dev/null
+++ b/kbabel/kbabel/taglistview.h
@@ -0,0 +1,61 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2004 by Stanislav Visnovsky
+ <visnovsky@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+**************************************************************************** */
+#ifndef TAGLISTVIEW_H
+#define TAGLISTVIEW_H
+
+#include "kbcatalogview.h"
+
+class KListBox;
+
+class TagListView : public KBCatalogView
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ TagListView(KBCatalog* catalog,QWidget *parent, KBabel::Project::Ptr project);
+
+public slots:
+ virtual void updateView();
+ void highlightTag (int index);
+
+signals:
+ void signalHighlightedTagChanged (int index);
+ void signalTagSelected (const QString& tag);
+
+private:
+ KListBox* _tagBox;
+};
+
+#endif // TAGLISTVIEW_H