diff options
Diffstat (limited to 'kbabel/kbabel')
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>&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 &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 &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&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><qt>Here you can setup a color to display identified <b>mispelled</b> words and +phrases.</qt></string> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Color for &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&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 &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&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&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 &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&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>&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&utomatically unset fuzzy status</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt><p><b>Automatically unset fuzzy status</b></p> +<p>If this is activated and you are editing a fuzzy entry, the fuzzy status is automatically +unset (this means the string <i>, fuzzy</i> +is removed from the entry's comment).</p></qt></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_CleverEditing</cstring> + </property> + <property name="text"> + <string>Use cle&ver editing</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt><p><b>Use clever editing</b></p> +<p>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.</p> +<p>Note that this is just a hint: it is still possible to +generate syntactically incorrect text.</p></qt></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><qt><p><b>Error recognition</b></p> +<p>Here you can set how to show that an error occurred. +<b>Beep on error</b> beeps and <b>Change text color on error +</b> changes the color of the translated text. If none is +activated, you will still see a message in the statusbar. +</p></qt></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>&Beep on error</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_AutoCheckColorError</cstring> + </property> + <property name="text"> + <string>Change te&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&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&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&nd</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>kcfg_WhitespacePoints</cstring> + </property> + <property name="text"> + <string>Mark &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>&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><qt><p><b>Status LEDs</b></p> +<p>Choose here where the status LEDs are displayed and what color they have.</p></qt></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&usbar</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioButton2</cstring> + </property> + <property name="text"> + <string>Display in edi&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&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>&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>&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>&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 Binary files differnew file mode 100644 index 00000000..3b062e51 --- /dev/null +++ b/kbabel/kbabel/hi16-app-kbabel.png diff --git a/kbabel/kbabel/hi32-app-kbabel.png b/kbabel/kbabel/hi32-app-kbabel.png Binary files differnew file mode 100644 index 00000000..b7f1e843 --- /dev/null +++ b/kbabel/kbabel/hi32-app-kbabel.png diff --git a/kbabel/kbabel/hi48-app-kbabel.png b/kbabel/kbabel/hi48-app-kbabel.png Binary files differnew file mode 100644 index 00000000..77bd3530 --- /dev/null +++ b/kbabel/kbabel/hi48-app-kbabel.png 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 Binary files differnew file mode 100644 index 00000000..d79e471f --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-autodiff.png diff --git a/kbabel/kbabel/icons/hi16-action-catalogmanager.png b/kbabel/kbabel/icons/hi16-action-catalogmanager.png Binary files differnew file mode 100644 index 00000000..369ab591 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-catalogmanager.png diff --git a/kbabel/kbabel/icons/hi16-action-diff.png b/kbabel/kbabel/icons/hi16-action-diff.png Binary files differnew file mode 100644 index 00000000..9e13d750 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-diff.png diff --git a/kbabel/kbabel/icons/hi16-action-insert_arg.png b/kbabel/kbabel/icons/hi16-action-insert_arg.png Binary files differnew file mode 100644 index 00000000..e133f0e4 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-insert_arg.png diff --git a/kbabel/kbabel/icons/hi16-action-insert_tag.png b/kbabel/kbabel/icons/hi16-action-insert_tag.png Binary files differnew file mode 100644 index 00000000..e0757463 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-insert_tag.png diff --git a/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png Binary files differnew file mode 100644 index 00000000..6f5534fa --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-msgid2msgstr.png diff --git a/kbabel/kbabel/icons/hi16-action-nexterror.png b/kbabel/kbabel/icons/hi16-action-nexterror.png Binary files differnew file mode 100644 index 00000000..78876d16 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-nexterror.png diff --git a/kbabel/kbabel/icons/hi16-action-nextfuzzy.png b/kbabel/kbabel/icons/hi16-action-nextfuzzy.png Binary files differnew file mode 100644 index 00000000..6bcc43ed --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-nextfuzzy.png diff --git a/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..d17b402f --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-nextfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi16-action-nextuntranslated.png b/kbabel/kbabel/icons/hi16-action-nextuntranslated.png Binary files differnew file mode 100644 index 00000000..317bb595 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-nextuntranslated.png diff --git a/kbabel/kbabel/icons/hi16-action-preverror.png b/kbabel/kbabel/icons/hi16-action-preverror.png Binary files differnew file mode 100644 index 00000000..630da7d7 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-preverror.png diff --git a/kbabel/kbabel/icons/hi16-action-prevfuzzy.png b/kbabel/kbabel/icons/hi16-action-prevfuzzy.png Binary files differnew file mode 100644 index 00000000..a381d93e --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-prevfuzzy.png diff --git a/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..64995893 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-prevfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi16-action-prevuntranslated.png b/kbabel/kbabel/icons/hi16-action-prevuntranslated.png Binary files differnew file mode 100644 index 00000000..49610f03 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-prevuntranslated.png diff --git a/kbabel/kbabel/icons/hi16-action-search2msgstr.png b/kbabel/kbabel/icons/hi16-action-search2msgstr.png Binary files differnew file mode 100644 index 00000000..99986bba --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-search2msgstr.png diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png b/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png Binary files differnew file mode 100644 index 00000000..1a653f5e --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-spellcheck_actual.png diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_all.png b/kbabel/kbabel/icons/hi16-action-spellcheck_all.png Binary files differnew file mode 100644 index 00000000..c0b622d2 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-spellcheck_all.png diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png b/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png Binary files differnew file mode 100644 index 00000000..0bbd0a61 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-spellcheck_from_cursor.png diff --git a/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png b/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png Binary files differnew file mode 100644 index 00000000..feacd83d --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-spellcheck_selected.png diff --git a/kbabel/kbabel/icons/hi16-action-togglefuzzy.png b/kbabel/kbabel/icons/hi16-action-togglefuzzy.png Binary files differnew file mode 100644 index 00000000..3538fde6 --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-togglefuzzy.png diff --git a/kbabel/kbabel/icons/hi16-action-transsearch.png b/kbabel/kbabel/icons/hi16-action-transsearch.png Binary files differnew file mode 100644 index 00000000..e1776a6e --- /dev/null +++ b/kbabel/kbabel/icons/hi16-action-transsearch.png diff --git a/kbabel/kbabel/icons/hi22-action-autodiff.png b/kbabel/kbabel/icons/hi22-action-autodiff.png Binary files differnew file mode 100644 index 00000000..91988ede --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-autodiff.png diff --git a/kbabel/kbabel/icons/hi22-action-catalogmanager.png b/kbabel/kbabel/icons/hi22-action-catalogmanager.png Binary files differnew file mode 100644 index 00000000..48bbade3 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-catalogmanager.png diff --git a/kbabel/kbabel/icons/hi22-action-diff.png b/kbabel/kbabel/icons/hi22-action-diff.png Binary files differnew file mode 100644 index 00000000..321ed59e --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-diff.png diff --git a/kbabel/kbabel/icons/hi22-action-insert_arg.png b/kbabel/kbabel/icons/hi22-action-insert_arg.png Binary files differnew file mode 100644 index 00000000..6aa1da61 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-insert_arg.png diff --git a/kbabel/kbabel/icons/hi22-action-insert_tag.png b/kbabel/kbabel/icons/hi22-action-insert_tag.png Binary files differnew file mode 100644 index 00000000..cbd50021 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-insert_tag.png diff --git a/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png Binary files differnew file mode 100644 index 00000000..3323ada2 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-msgid2msgstr.png diff --git a/kbabel/kbabel/icons/hi22-action-nexterror.png b/kbabel/kbabel/icons/hi22-action-nexterror.png Binary files differnew file mode 100644 index 00000000..24a94589 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-nexterror.png diff --git a/kbabel/kbabel/icons/hi22-action-nextfuzzy.png b/kbabel/kbabel/icons/hi22-action-nextfuzzy.png Binary files differnew file mode 100644 index 00000000..2e302679 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-nextfuzzy.png diff --git a/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..47a3c36a --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-nextfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi22-action-nextuntranslated.png b/kbabel/kbabel/icons/hi22-action-nextuntranslated.png Binary files differnew file mode 100644 index 00000000..eb4ea46c --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-nextuntranslated.png diff --git a/kbabel/kbabel/icons/hi22-action-preverror.png b/kbabel/kbabel/icons/hi22-action-preverror.png Binary files differnew file mode 100644 index 00000000..089e5a12 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-preverror.png diff --git a/kbabel/kbabel/icons/hi22-action-prevfuzzy.png b/kbabel/kbabel/icons/hi22-action-prevfuzzy.png Binary files differnew file mode 100644 index 00000000..aec1f219 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-prevfuzzy.png diff --git a/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..4e7c88d4 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-prevfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi22-action-prevuntranslated.png b/kbabel/kbabel/icons/hi22-action-prevuntranslated.png Binary files differnew file mode 100644 index 00000000..8f5c764f --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-prevuntranslated.png diff --git a/kbabel/kbabel/icons/hi22-action-search2msgstr.png b/kbabel/kbabel/icons/hi22-action-search2msgstr.png Binary files differnew file mode 100644 index 00000000..9df8dfca --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-search2msgstr.png diff --git a/kbabel/kbabel/icons/hi22-action-togglefuzzy.png b/kbabel/kbabel/icons/hi22-action-togglefuzzy.png Binary files differnew file mode 100644 index 00000000..40227189 --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-togglefuzzy.png diff --git a/kbabel/kbabel/icons/hi22-action-transsearch.png b/kbabel/kbabel/icons/hi22-action-transsearch.png Binary files differnew file mode 100644 index 00000000..06d5852c --- /dev/null +++ b/kbabel/kbabel/icons/hi22-action-transsearch.png diff --git a/kbabel/kbabel/icons/hi32-action-autodiff.png b/kbabel/kbabel/icons/hi32-action-autodiff.png Binary files differnew file mode 100644 index 00000000..471ece08 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-autodiff.png diff --git a/kbabel/kbabel/icons/hi32-action-catalogmanager.png b/kbabel/kbabel/icons/hi32-action-catalogmanager.png Binary files differnew file mode 100644 index 00000000..d527b872 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-catalogmanager.png diff --git a/kbabel/kbabel/icons/hi32-action-diff.png b/kbabel/kbabel/icons/hi32-action-diff.png Binary files differnew file mode 100644 index 00000000..535d508a --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-diff.png diff --git a/kbabel/kbabel/icons/hi32-action-insert_arg.png b/kbabel/kbabel/icons/hi32-action-insert_arg.png Binary files differnew file mode 100644 index 00000000..ea8c8179 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-insert_arg.png diff --git a/kbabel/kbabel/icons/hi32-action-insert_tag.png b/kbabel/kbabel/icons/hi32-action-insert_tag.png Binary files differnew file mode 100644 index 00000000..d11981ef --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-insert_tag.png diff --git a/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png b/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png Binary files differnew file mode 100644 index 00000000..8dc03384 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-msgid2msgstr.png diff --git a/kbabel/kbabel/icons/hi32-action-nexterror.png b/kbabel/kbabel/icons/hi32-action-nexterror.png Binary files differnew file mode 100644 index 00000000..ee458abc --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-nexterror.png diff --git a/kbabel/kbabel/icons/hi32-action-nextfuzzy.png b/kbabel/kbabel/icons/hi32-action-nextfuzzy.png Binary files differnew file mode 100644 index 00000000..089e6357 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-nextfuzzy.png diff --git a/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..82f535e6 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-nextfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi32-action-nextuntranslated.png b/kbabel/kbabel/icons/hi32-action-nextuntranslated.png Binary files differnew file mode 100644 index 00000000..8b9db6f7 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-nextuntranslated.png diff --git a/kbabel/kbabel/icons/hi32-action-preverror.png b/kbabel/kbabel/icons/hi32-action-preverror.png Binary files differnew file mode 100644 index 00000000..7ff8da13 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-preverror.png diff --git a/kbabel/kbabel/icons/hi32-action-prevfuzzy.png b/kbabel/kbabel/icons/hi32-action-prevfuzzy.png Binary files differnew file mode 100644 index 00000000..0280c02f --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-prevfuzzy.png diff --git a/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..bcfb55aa --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-prevfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/hi32-action-prevuntranslated.png b/kbabel/kbabel/icons/hi32-action-prevuntranslated.png Binary files differnew file mode 100644 index 00000000..e4bdb694 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-prevuntranslated.png diff --git a/kbabel/kbabel/icons/hi32-action-search2msgstr.png b/kbabel/kbabel/icons/hi32-action-search2msgstr.png Binary files differnew file mode 100644 index 00000000..3337b646 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-search2msgstr.png diff --git a/kbabel/kbabel/icons/hi32-action-togglefuzzy.png b/kbabel/kbabel/icons/hi32-action-togglefuzzy.png Binary files differnew file mode 100644 index 00000000..0a9492a0 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-togglefuzzy.png diff --git a/kbabel/kbabel/icons/hi32-action-transsearch.png b/kbabel/kbabel/icons/hi32-action-transsearch.png Binary files differnew file mode 100644 index 00000000..19e766c5 --- /dev/null +++ b/kbabel/kbabel/icons/hi32-action-transsearch.png diff --git a/kbabel/kbabel/icons/lo16-action-autodiff.png b/kbabel/kbabel/icons/lo16-action-autodiff.png Binary files differnew file mode 100644 index 00000000..7cb56260 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-autodiff.png diff --git a/kbabel/kbabel/icons/lo16-action-catalogmanager.png b/kbabel/kbabel/icons/lo16-action-catalogmanager.png Binary files differnew file mode 100644 index 00000000..75a95c0c --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-catalogmanager.png diff --git a/kbabel/kbabel/icons/lo16-action-diff.png b/kbabel/kbabel/icons/lo16-action-diff.png Binary files differnew file mode 100644 index 00000000..05b82b53 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-diff.png diff --git a/kbabel/kbabel/icons/lo16-action-insert_arg.png b/kbabel/kbabel/icons/lo16-action-insert_arg.png Binary files differnew file mode 100644 index 00000000..bc67bc15 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-insert_arg.png diff --git a/kbabel/kbabel/icons/lo16-action-insert_tag.png b/kbabel/kbabel/icons/lo16-action-insert_tag.png Binary files differnew file mode 100644 index 00000000..283b0793 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-insert_tag.png diff --git a/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png b/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png Binary files differnew file mode 100644 index 00000000..8cb33ccb --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-msgid2msgstr.png diff --git a/kbabel/kbabel/icons/lo16-action-nexterror.png b/kbabel/kbabel/icons/lo16-action-nexterror.png Binary files differnew file mode 100644 index 00000000..a2d48527 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-nexterror.png diff --git a/kbabel/kbabel/icons/lo16-action-nextfuzzy.png b/kbabel/kbabel/icons/lo16-action-nextfuzzy.png Binary files differnew file mode 100644 index 00000000..828bfc3b --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-nextfuzzy.png diff --git a/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..ad150c58 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-nextfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/lo16-action-nextuntranslated.png b/kbabel/kbabel/icons/lo16-action-nextuntranslated.png Binary files differnew file mode 100644 index 00000000..bbcda8c3 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-nextuntranslated.png diff --git a/kbabel/kbabel/icons/lo16-action-preverror.png b/kbabel/kbabel/icons/lo16-action-preverror.png Binary files differnew file mode 100644 index 00000000..10c2f7e5 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-preverror.png diff --git a/kbabel/kbabel/icons/lo16-action-prevfuzzy.png b/kbabel/kbabel/icons/lo16-action-prevfuzzy.png Binary files differnew file mode 100644 index 00000000..a19cb6ac --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-prevfuzzy.png diff --git a/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..f63b3598 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-prevfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/lo16-action-prevuntranslated.png b/kbabel/kbabel/icons/lo16-action-prevuntranslated.png Binary files differnew file mode 100644 index 00000000..a3ad3431 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-prevuntranslated.png diff --git a/kbabel/kbabel/icons/lo16-action-search2msgstr.png b/kbabel/kbabel/icons/lo16-action-search2msgstr.png Binary files differnew file mode 100644 index 00000000..36d25867 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-search2msgstr.png diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png b/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png Binary files differnew file mode 100644 index 00000000..1a653f5e --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-spellcheck_actual.png diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_all.png b/kbabel/kbabel/icons/lo16-action-spellcheck_all.png Binary files differnew file mode 100644 index 00000000..c0b622d2 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-spellcheck_all.png diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png b/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png Binary files differnew file mode 100644 index 00000000..0bbd0a61 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-spellcheck_from_cursor.png diff --git a/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png b/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png Binary files differnew file mode 100644 index 00000000..feacd83d --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-spellcheck_selected.png diff --git a/kbabel/kbabel/icons/lo16-action-togglefuzzy.png b/kbabel/kbabel/icons/lo16-action-togglefuzzy.png Binary files differnew file mode 100644 index 00000000..3538fde6 --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-togglefuzzy.png diff --git a/kbabel/kbabel/icons/lo16-action-transsearch.png b/kbabel/kbabel/icons/lo16-action-transsearch.png Binary files differnew file mode 100644 index 00000000..f933a6eb --- /dev/null +++ b/kbabel/kbabel/icons/lo16-action-transsearch.png diff --git a/kbabel/kbabel/icons/lo32-action-autodiff.png b/kbabel/kbabel/icons/lo32-action-autodiff.png Binary files differnew file mode 100644 index 00000000..b6cb074a --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-autodiff.png diff --git a/kbabel/kbabel/icons/lo32-action-catalogmanager.png b/kbabel/kbabel/icons/lo32-action-catalogmanager.png Binary files differnew file mode 100644 index 00000000..1e9da58f --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-catalogmanager.png diff --git a/kbabel/kbabel/icons/lo32-action-diff.png b/kbabel/kbabel/icons/lo32-action-diff.png Binary files differnew file mode 100644 index 00000000..8be1d0a4 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-diff.png diff --git a/kbabel/kbabel/icons/lo32-action-insert_arg.png b/kbabel/kbabel/icons/lo32-action-insert_arg.png Binary files differnew file mode 100644 index 00000000..39fcf1fd --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-insert_arg.png diff --git a/kbabel/kbabel/icons/lo32-action-insert_tag.png b/kbabel/kbabel/icons/lo32-action-insert_tag.png Binary files differnew file mode 100644 index 00000000..820bc66f --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-insert_tag.png diff --git a/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png b/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png Binary files differnew file mode 100644 index 00000000..7497c265 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-msgid2msgstr.png diff --git a/kbabel/kbabel/icons/lo32-action-nexterror.png b/kbabel/kbabel/icons/lo32-action-nexterror.png Binary files differnew file mode 100644 index 00000000..de06b7e8 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-nexterror.png diff --git a/kbabel/kbabel/icons/lo32-action-nextfuzzy.png b/kbabel/kbabel/icons/lo32-action-nextfuzzy.png Binary files differnew file mode 100644 index 00000000..9218c291 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-nextfuzzy.png diff --git a/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png b/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..6efbd5a7 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-nextfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/lo32-action-nextuntranslated.png b/kbabel/kbabel/icons/lo32-action-nextuntranslated.png Binary files differnew file mode 100644 index 00000000..c6954974 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-nextuntranslated.png diff --git a/kbabel/kbabel/icons/lo32-action-preverror.png b/kbabel/kbabel/icons/lo32-action-preverror.png Binary files differnew file mode 100644 index 00000000..c8196a3e --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-preverror.png diff --git a/kbabel/kbabel/icons/lo32-action-prevfuzzy.png b/kbabel/kbabel/icons/lo32-action-prevfuzzy.png Binary files differnew file mode 100644 index 00000000..4a078602 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-prevfuzzy.png diff --git a/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png b/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png Binary files differnew file mode 100644 index 00000000..902c84cb --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-prevfuzzyuntrans.png diff --git a/kbabel/kbabel/icons/lo32-action-prevuntranslated.png b/kbabel/kbabel/icons/lo32-action-prevuntranslated.png Binary files differnew file mode 100644 index 00000000..32ea00c4 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-prevuntranslated.png diff --git a/kbabel/kbabel/icons/lo32-action-search2msgstr.png b/kbabel/kbabel/icons/lo32-action-search2msgstr.png Binary files differnew file mode 100644 index 00000000..b2a83b66 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-search2msgstr.png diff --git a/kbabel/kbabel/icons/lo32-action-togglefuzzy.png b/kbabel/kbabel/icons/lo32-action-togglefuzzy.png Binary files differnew file mode 100644 index 00000000..0a9492a0 --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-togglefuzzy.png diff --git a/kbabel/kbabel/icons/lo32-action-transsearch.png b/kbabel/kbabel/icons/lo32-action-transsearch.png Binary files differnew file mode 100644 index 00000000..e91eedcc --- /dev/null +++ b/kbabel/kbabel/icons/lo32-action-transsearch.png 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>&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>&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>&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>&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>&Tools</text> + <Menu name="spellcheck" icon="spellcheck"><text>&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&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>&Dictionaries</text> + <Action name="dict_search_all"/> + <Action name="dict_search_selected"/> + <Action name="dict_edit"/> + </Menu> + <Menu name="settings"><text>&Settings</text> + <Action name="dict_configure" append="configure_merge"/> + </Menu> + <Menu name="bookmark"><text>&Bookmarks</text> + <Action name="add_bookmark"/> + <Action name="clear_bookmarks"/> + <Separator/> + </Menu> + <Menu name="help"><text>&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( "<", "<" ); + tmp_msgid = tmp_msgid.replace( ">", ">" ); + + 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 Binary files differnew file mode 100644 index 00000000..98ee2659 --- /dev/null +++ b/kbabel/kbabel/lo16-app-kbabel.png diff --git a/kbabel/kbabel/lo32-app-kbabel.png b/kbabel/kbabel/lo32-app-kbabel.png Binary files differnew file mode 100644 index 00000000..8d52961b --- /dev/null +++ b/kbabel/kbabel/lo32-app-kbabel.png 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( ¶From, &idxFrom, ¶To, &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(¶,&index); + + return pos2Offset( para, index ); +} + + +void MyMultiLineEdit::offset2Pos(int offset, int ¶graph, 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 Binary files differnew file mode 100644 index 00000000..d0948e92 --- /dev/null +++ b/kbabel/kbabel/pics/broken.png diff --git a/kbabel/kbabel/pics/missing.png b/kbabel/kbabel/pics/missing.png Binary files differnew file mode 100644 index 00000000..e0311068 --- /dev/null +++ b/kbabel/kbabel/pics/missing.png diff --git a/kbabel/kbabel/pics/needwork.png b/kbabel/kbabel/pics/needwork.png Binary files differnew file mode 100644 index 00000000..e31413d8 --- /dev/null +++ b/kbabel/kbabel/pics/needwork.png diff --git a/kbabel/kbabel/pics/noflag.png b/kbabel/kbabel/pics/noflag.png Binary files differnew file mode 100644 index 00000000..5b6ad0c2 --- /dev/null +++ b/kbabel/kbabel/pics/noflag.png diff --git a/kbabel/kbabel/pics/ok.png b/kbabel/kbabel/pics/ok.png Binary files differnew file mode 100644 index 00000000..f2b731a0 --- /dev/null +++ b/kbabel/kbabel/pics/ok.png diff --git a/kbabel/kbabel/pics/pref_identity.png b/kbabel/kbabel/pics/pref_identity.png Binary files differnew file mode 100644 index 00000000..de7e1459 --- /dev/null +++ b/kbabel/kbabel/pics/pref_identity.png diff --git a/kbabel/kbabel/pics/splash.png b/kbabel/kbabel/pics/splash.png Binary files differnew file mode 100644 index 00000000..26f908c7 --- /dev/null +++ b/kbabel/kbabel/pics/splash.png 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&tomatically start search</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt><p><b>Automatically start search</b></p> +<p>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 <b>Default Dictionary</b>. +</p><p>You can also start searching manually by choosing an entry in +the popup menu that appears either when clicking +<b>Dictionaries->Find...</b> or keeping the dictionary button +in the toolbar pressed for a while.</p></qt></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&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><qt><p><b>Default Dictionary</b></p> +<p>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.</p> +<p>You can configure the different dictionaries by selecting +the desired dictionary from <b>Settings->Configure Dictionary</b>. +</p></qt></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&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&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&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>&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&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&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&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 |