summaryrefslogtreecommitdiffstats
path: root/kbabel/catalogmanager
diff options
context:
space:
mode:
Diffstat (limited to 'kbabel/catalogmanager')
-rw-r--r--kbabel/catalogmanager/Makefile.am64
-rw-r--r--kbabel/catalogmanager/catalogmanager.cpp1371
-rw-r--r--kbabel/catalogmanager/catalogmanager.desktop98
-rw-r--r--kbabel/catalogmanager/catalogmanager.h218
-rw-r--r--kbabel/catalogmanager/catalogmanagerapp.h73
-rw-r--r--kbabel/catalogmanager/catalogmanageriface.h67
-rw-r--r--kbabel/catalogmanager/catalogmanagerui.rc262
-rw-r--r--kbabel/catalogmanager/catalogmanagerview.cpp3132
-rw-r--r--kbabel/catalogmanager/catalogmanagerview.h474
-rw-r--r--kbabel/catalogmanager/catmanlistitem.cpp932
-rw-r--r--kbabel/catalogmanager/catmanlistitem.h238
-rw-r--r--kbabel/catalogmanager/catmanresource.h73
-rw-r--r--kbabel/catalogmanager/findinfilesdialog.cpp229
-rw-r--r--kbabel/catalogmanager/findinfilesdialog.h85
-rw-r--r--kbabel/catalogmanager/future.cpp17
-rw-r--r--kbabel/catalogmanager/hi16-app-catalogmanager.pngbin0 -> 865 bytes
-rw-r--r--kbabel/catalogmanager/hi22-app-catalogmanager.pngbin0 -> 1396 bytes
-rw-r--r--kbabel/catalogmanager/hi32-app-catalogmanager.pngbin0 -> 2446 bytes
-rw-r--r--kbabel/catalogmanager/hi48-app-catalogmanager.pngbin0 -> 4498 bytes
-rw-r--r--kbabel/catalogmanager/icons/Makefile.am5
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-nextmarked.pngbin0 -> 329 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-nextpo.pngbin0 -> 348 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-nexttemplate.pngbin0 -> 354 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-prevmarked.pngbin0 -> 341 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-prevpo.pngbin0 -> 356 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-prevtemplate.pngbin0 -> 363 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-statistics.pngbin0 -> 702 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi16-action-syntax.pngbin0 -> 623 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-nextmarked.pngbin0 -> 566 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-nextpo.pngbin0 -> 454 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-nexttemplate.pngbin0 -> 447 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-prevmarked.pngbin0 -> 560 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-prevpo.pngbin0 -> 440 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-prevtemplate.pngbin0 -> 436 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-statistics.pngbin0 -> 1180 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi22-action-syntax.pngbin0 -> 1378 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-nextmarked.pngbin0 -> 706 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-nextpo.pngbin0 -> 593 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-nexttemplate.pngbin0 -> 568 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-prevmarked.pngbin0 -> 726 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-prevpo.pngbin0 -> 624 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-prevtemplate.pngbin0 -> 627 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-statistics.pngbin0 -> 1456 bytes
-rw-r--r--kbabel/catalogmanager/icons/hi32-action-syntax.pngbin0 -> 1332 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-nextmarked.pngbin0 -> 315 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-nextpo.pngbin0 -> 353 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-nexttemplate.pngbin0 -> 325 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-prevmarked.pngbin0 -> 319 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-prevpo.pngbin0 -> 362 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-prevtemplate.pngbin0 -> 340 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-statistics.pngbin0 -> 362 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo16-action-syntax.pngbin0 -> 311 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo22-action-statistics.pngbin0 -> 420 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo22-action-syntax.pngbin0 -> 402 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-nextmarked.pngbin0 -> 582 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-nextpo.pngbin0 -> 593 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-nexttemplate.pngbin0 -> 568 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-prevmarked.pngbin0 -> 502 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-prevpo.pngbin0 -> 497 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-prevtemplate.pngbin0 -> 484 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-statistics.pngbin0 -> 471 bytes
-rw-r--r--kbabel/catalogmanager/icons/lo32-action-syntax.pngbin0 -> 497 bytes
-rw-r--r--kbabel/catalogmanager/libcvs/Makefile.am11
-rw-r--r--kbabel/catalogmanager/libcvs/cvsdialog.cpp423
-rw-r--r--kbabel/catalogmanager/libcvs/cvsdialog.h158
-rw-r--r--kbabel/catalogmanager/libcvs/cvshandler.cpp398
-rw-r--r--kbabel/catalogmanager/libcvs/cvshandler.h114
-rw-r--r--kbabel/catalogmanager/libcvs/cvsresources.h41
-rw-r--r--kbabel/catalogmanager/libsvn/Makefile.am11
-rw-r--r--kbabel/catalogmanager/libsvn/svndialog.cpp400
-rw-r--r--kbabel/catalogmanager/libsvn/svndialog.h151
-rw-r--r--kbabel/catalogmanager/libsvn/svnhandler.cpp544
-rw-r--r--kbabel/catalogmanager/libsvn/svnhandler.h138
-rw-r--r--kbabel/catalogmanager/libsvn/svnresources.h50
-rw-r--r--kbabel/catalogmanager/lo16-app-catalogmanager.pngbin0 -> 323 bytes
-rw-r--r--kbabel/catalogmanager/lo32-app-catalogmanager.pngbin0 -> 554 bytes
-rw-r--r--kbabel/catalogmanager/main.cpp232
-rw-r--r--kbabel/catalogmanager/markpatterndialog.cpp172
-rw-r--r--kbabel/catalogmanager/markpatterndialog.h75
-rw-r--r--kbabel/catalogmanager/markpatternwidget.ui127
-rw-r--r--kbabel/catalogmanager/multiroughtransdlg.cpp148
-rw-r--r--kbabel/catalogmanager/multiroughtransdlg.h63
-rw-r--r--kbabel/catalogmanager/validateprogress.cpp313
-rw-r--r--kbabel/catalogmanager/validateprogress.h109
-rw-r--r--kbabel/catalogmanager/validateprogresswidget.ui129
-rw-r--r--kbabel/catalogmanager/validateprogresswidget.ui.h48
-rw-r--r--kbabel/catalogmanager/validationoptions.ui60
87 files changed, 11253 insertions, 0 deletions
diff --git a/kbabel/catalogmanager/Makefile.am b/kbabel/catalogmanager/Makefile.am
new file mode 100644
index 00000000..2d8d1836
--- /dev/null
+++ b/kbabel/catalogmanager/Makefile.am
@@ -0,0 +1,64 @@
+## Makefile.am for KBabel catalogmanager
+
+# this has all of the subdirectories that make will recurse into. If
+# there are none, comment this out
+SUBDIRS = libcvs libsvn icons
+
+# this is the program that gets installed. Its name is used for all
+# of the other Makefile.am variables
+noinst_LTLIBRARIES = libcatalogmanager.la
+bin_PROGRAMS = catalogmanager
+
+# set the include path for X, qt and KDE. Let $(all_includes) be always last.
+INCLUDES = -I$(srcdir)/../common -I../common -I$(srcdir)/../kbabeldict \
+-I$(srcdir)/../commonui -I../commonui -I./libsvn -I./libcvs \
+-I$(srcdir)/libsvn -I$(srcdir)/libcvs $(all_includes)
+
+
+# which sources should be compiled for kbabel
+libcatalogmanager_la_SOURCES = catalogmanageriface.skel \
+ validationoptions.ui \
+ catalogmanagerview.cpp \
+ catalogmanager.cpp findinfilesdialog.cpp \
+ catmanlistitem.cpp multiroughtransdlg.cpp validateprogresswidget.ui \
+ validateprogress.cpp markpatternwidget.ui markpatterndialog.cpp
+
+
+libcatalogmanager_la_LIBADD = ../commonui/libkbabelcommonui.la \
+../kbabeldict/libkbabeldict.la ./libcvs/libcatalogmanagercvs.la \
+./libsvn/libcatalogmanagersvn.la $(LIB_KIO)
+libcatalogmanager_la_LDFLAGS = $(all_libraries) -no-undefined
+
+
+catalogmanager_SOURCES = main.cpp
+
+# the libraries to link against.
+catalogmanager_LDADD = libcatalogmanager.la
+catalogmanager_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# these are the headers for your project
+noinst_HEADERS = catalogmanageriface.h catalogmanager.h \
+ catalogmanagerview.h catalogmanagerapp.h findinfilesdialog.h \
+ catmanlistitem.h catmanresource.h multiroughtransdlg.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+rcdir = $(kde_datadir)/catalogmanager
+rc_DATA = catalogmanagerui.rc
+
+
+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 = AUTO
+
+# this is where the kdelnk file will go
+xdg_apps_DATA = catalogmanager.desktop
+
+catalogmanager.lo: ../common/version.h
+main.o: ../common/version.h
+
diff --git a/kbabel/catalogmanager/catalogmanager.cpp b/kbabel/catalogmanager/catalogmanager.cpp
new file mode 100644
index 00000000..6cbe964d
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanager.cpp
@@ -0,0 +1,1371 @@
+/*****************************************************************************
+ 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>
+
+ 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 "catmanresource.h"
+#include "catalogmanager.h"
+#include "catalog.h"
+#include "catalogmanagerapp.h"
+#include "findinfilesdialog.h"
+#include "kbabeldictbox.h"
+#include "resources.h"
+#include "projectpref.h"
+#include "kbprojectmanager.h"
+#include "projectwizard.h"
+#include "msgfmt.h"
+#include "toolaction.h"
+
+#include <qlabel.h>
+#include <qpainter.h>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <kcmenumngr.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kdatatool.h>
+#include <kdialogbase.h>
+//#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kprogress.h>
+#include <kstdaccel.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <ktoolbar.h>
+#include <kwin.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qtimer.h>
+#include <qbitmap.h>
+#include <qwhatsthis.h>
+#include <qheader.h>
+#include <qdragobject.h>
+#include <qlayout.h>
+#include <qhbox.h>
+
+using namespace KBabel;
+
+WId CatalogManagerApp::_preferredWindow = 0;
+
+QStringList CatalogManager::_foundFilesList;
+QStringList CatalogManager::_toBeSearched;
+
+CatalogManager::CatalogManager(QString configFile )
+ :KMainWindow(0,0)
+{
+ if ( configFile.isEmpty() )
+ configFile = KBabel::ProjectManager::defaultProjectName();
+ _configFile = configFile;
+
+ init();
+ restoreSettings();
+ updateSettings();
+}
+
+CatalogManager::~CatalogManager()
+{
+ saveView();
+ saveSettings(_configFile);
+ delete config;
+}
+
+void CatalogManager::init()
+{
+ _foundToBeSent = 0;
+ _totalFound = 0;
+ _foundFilesList.clear();
+ _toBeSearched.clear();
+ _timerFind = new QTimer( this );
+ connect(_timerFind, SIGNAL( timeout() ), this, SLOT(findNextFile()) );
+ _searchStopped = false;
+
+ _prefDialog=0;
+ _findDialog=0;
+ _replaceDialog=0;
+
+ _project = KBabel::ProjectManager::open(_configFile);
+
+ if ( _project == NULL )
+ {
+ KMessageBox::error( this, i18n("Cannot open project file\n%1").arg(_configFile)
+ , i18n("Project File Error"));
+
+ _project = KBabel::ProjectManager::open(KBabel::ProjectManager::defaultProjectName());
+ }
+
+ connect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+
+ QWidget *view = new QWidget(this);
+ QVBoxLayout* layout= new QVBoxLayout(view);
+ layout->setMargin(0);
+ layout->setSpacing(KDialog::spacingHint());
+
+ _catalogManager=new CatalogManagerView(_project, view,"catalog manager");
+ layout->addWidget(_catalogManager);
+ layout->setStretchFactor(_catalogManager,1);
+
+ connect(this,SIGNAL(settingsChanged(KBabel::CatManSettings))
+ ,_catalogManager,SLOT(setSettings(KBabel::CatManSettings)));
+ connect(_catalogManager,SIGNAL(openFile(QString,QString))
+ ,this,SLOT(openFile(QString,QString)));
+ connect(_catalogManager,SIGNAL(openFileInNewWindow(QString,QString))
+ ,this,SLOT(openFileInNewWindow(QString,QString)));
+ connect(_catalogManager,SIGNAL(openTemplate(QString,QString,QString))
+ ,this,SLOT(openTemplate(QString,QString,QString)));
+ connect(_catalogManager,SIGNAL(openTemplateInNewWindow(QString,QString,QString))
+ ,this,SLOT(openTemplateInNewWindow(QString,QString,QString)));
+ connect(_catalogManager,SIGNAL(gotoFileEntry(QString,QString,int))
+ ,this,SLOT(openFile(QString,QString,int)));
+ connect(_catalogManager, SIGNAL(selectedChanged(uint)),
+ this, SLOT(selectedChanged(uint)));
+
+ KWin::setIcons(winId(),BarIcon("catalogmanager",32)
+ ,SmallIcon("catalogmanager"));
+
+ QHBoxLayout* hBoxL = new QHBoxLayout(layout);
+ _progressLabel = new QLabel(view);
+ hBoxL->addWidget(_progressLabel);
+ _progressBar=new KProgress(view);
+ hBoxL->addWidget(_progressBar);
+ hBoxL->setStretchFactor(_progressBar,1);
+
+ _progressLabel->hide();
+ _progressBar->hide();
+
+ connect(_catalogManager,SIGNAL(prepareProgressBar(QString,int))
+ , this, SLOT(prepareProgressBar(QString,int)));
+ connect(_catalogManager,SIGNAL(clearProgressBar())
+ , this, SLOT(clearProgressBar()));
+ connect(_catalogManager,SIGNAL(progress(int))
+ , _progressBar, SLOT(setProgress(int)));
+// connect(_catalogManager, SIGNAL(signalBuildTree(bool))
+// , this, SLOT(enableMenuForFiles(bool)));
+ connect(_catalogManager, SIGNAL(signalBuildTree(bool))
+ , this, SLOT(enableActions(bool)));
+ connect(this, SIGNAL(searchStopped())
+ , _catalogManager, SLOT(stopSearch()));
+ connect(_catalogManager, SIGNAL(prepareFindProgressBar(int))
+ , this, SLOT(prepareStatusProgressBar(int)));
+
+ setCentralWidget(view);
+ resize( 600,300);
+
+ setupStatusBar();
+ setupActions();
+
+
+ QPopupMenu* popup;
+ popup = (QPopupMenu*)(factory()->container("rmb_file", this));
+ if(popup)
+ {
+ _catalogManager->setRMBMenuFile(popup);
+ }
+ popup = (QPopupMenu*)(factory()->container("rmb_dir", this));
+ if(popup)
+ {
+ _catalogManager->setRMBMenuDir(popup);
+ }
+
+ connect(_catalogManager, SIGNAL(signalSearchedFile(int))
+ , _statusProgressBar, SLOT(advance(int)));
+
+ restoreView();
+}
+
+void CatalogManager::setupActions()
+{
+ KGlobal::iconLoader()->addAppDir("kbabel");
+
+ KAction *action;
+
+ // the file menu
+ action = new KAction( i18n("&Open"), CTRL+Key_O, _catalogManager,
+ SLOT(slotOpenFile()),actionCollection(), "open");
+ action->setEnabled(false);
+ action = new KAction(i18n("&Open Template"),Key_Space,_catalogManager,
+ SLOT(slotOpenTemplate()),actionCollection(), "open_template");
+ action->setEnabled(false);
+ action = new KAction(i18n("Open in &New Window"),CTRL+SHIFT+Key_O,_catalogManager,
+ SLOT(slotOpenFileInNewWindow()),actionCollection(), "open_new_window");
+ action->setEnabled(false);
+
+ action = KStdAction::quit(kapp, SLOT (closeAllWindows()), actionCollection());
+
+ actionMap["open_template"] = NEEDS_POT;
+
+ // the edit menu
+ action = new KAction( i18n("Fi&nd in Files..."), CTRL+Key_F, this,
+ SLOT(find()), actionCollection(), "find_in_files");
+ action->setEnabled(false);
+ action = new KAction( i18n("Re&place in Files..."), CTRL+Key_R, this,
+ SLOT(replace()), actionCollection(), "replace_in_files");
+ action->setEnabled(false);
+ action = new KAction( i18n("&Stop Searching"), "stop", Key_Escape, this,
+ SLOT(stopSearching()), actionCollection(), "stop_search");
+ action->setEnabled(false);
+ action = new KAction( i18n("&Reload"), "reload", KStdAccel::reload(), _catalogManager,
+ SLOT(updateCurrent()), actionCollection(), "reload");
+ action->setEnabled(false);
+
+ // the marking menu
+ action = new KAction( i18n("&Toggle Marking"), CTRL+Key_M, _catalogManager,
+ SLOT(toggleMark()), actionCollection(), "toggle_marking");
+ action->setEnabled(false);
+ action = new KAction( i18n("Remove Marking"), 0, _catalogManager,
+ SLOT(slotClearMarksInDir()), actionCollection(), "remove_marking");
+ action->setEnabled(false);
+ action = new KAction( i18n("Toggle All Markings"), 0, _catalogManager,
+ SLOT(toggleAllMarks()), actionCollection(), "toggle_all_marking");
+ action->setEnabled(false);
+ action = new KAction( i18n("Remove All Markings"), 0, _catalogManager,
+ SLOT(clearAllMarks()), actionCollection(), "remove_all_marking");
+ action->setEnabled(false);
+ action = new KAction( i18n("Mark Modified Files"), 0, _catalogManager,
+ SLOT(markModifiedFiles()), actionCollection(), "mark_modified_files");
+ // fixme to enabling this when loading is done using updateFinished() signal
+ action->setEnabled(true);
+ action = new KAction( i18n("&Load Markings..."), 0, _catalogManager,
+ SLOT(loadMarks()), actionCollection(), "load_marking");
+ action->setEnabled(false);
+ action = new KAction( i18n("&Save Markings..."), 0, _catalogManager,
+ SLOT(saveMarks()), actionCollection(), "save_marking");
+ action->setEnabled(false);
+ (void)new KAction(i18n("&Mark Files..."), 0, _catalogManager,
+ SLOT(slotMarkPattern()), actionCollection(), "mark_pattern");
+ (void)new KAction(i18n("&Unmark Files..."), 0, _catalogManager,
+ SLOT(slotUnmarkPattern()), actionCollection(), "unmark_pattern");
+
+ actionMap["remove_marking"] = NEEDS_MARK;
+ actionMap["remove_all_marking"] = NEEDS_MARK;
+ actionMap["mark_pattern"] = NEEDS_DIR;
+ actionMap["unmark_pattern"] = NEEDS_DIR | NEEDS_MARK;
+
+ // go menu
+ action = new KAction(i18n("Nex&t Untranslated"), "nextuntranslated", ALT+Key_Next,
+ _catalogManager, SLOT(gotoNextUntranslated()),actionCollection(), "go_next_untrans");
+ action->setEnabled(false);
+ action = new KAction(i18n("Prev&ious Untranslated"), "prevuntranslated", ALT+Key_Prior,
+ _catalogManager, SLOT(gotoPreviousUntranslated()),actionCollection(), "go_prev_untrans");
+ action->setEnabled(false);
+ action = new KAction(i18n("Ne&xt Fuzzy"), "nextfuzzy", CTRL+Key_Next,
+ _catalogManager, SLOT(gotoNextFuzzy()),actionCollection(), "go_next_fuzzy");
+ action->setEnabled(false);
+ action = new KAction(i18n("Pre&vious Fuzzy"), "prevfuzzy", CTRL+Key_Prior,
+ _catalogManager, SLOT(gotoPreviousFuzzy()),actionCollection(), "go_prev_fuzzy");
+ action->setEnabled(false);
+ action = new KAction(i18n("N&ext Fuzzy or Untranslated"), "nextfuzzyuntrans", CTRL+SHIFT+Key_Next,
+ _catalogManager, SLOT(gotoNextFuzzyOrUntranslated()),actionCollection(), "go_next_fuzzyUntr");
+ action->setEnabled(false);
+ action = new KAction(i18n("P&revious Fuzzy or Untranslated"), "prevfuzzyuntrans", CTRL+SHIFT+Key_Prior,
+ _catalogManager, SLOT(gotoPreviousFuzzyOrUntranslated()),actionCollection(), "go_prev_fuzzyUntr");
+ action->setEnabled(false);
+
+ action = new KAction(i18n("Next Err&or"), "nexterror", ALT+SHIFT+Key_Next,
+ _catalogManager, SLOT(gotoNextError()),actionCollection(), "go_next_error");
+ action->setEnabled(false);
+ action = new KAction(i18n("Previo&us Error"), "preverror", ALT+SHIFT+Key_Prior,
+ _catalogManager, SLOT(gotoPreviousError()),actionCollection(), "go_prev_error");
+ action->setEnabled(false);
+ action = new KAction(i18n("Next Te&mplate Only"), "nexttemplate", CTRL+Key_Down,
+ _catalogManager, SLOT(gotoNextTemplate()),actionCollection(), "go_next_template");
+ action->setEnabled(false);
+ action = new KAction(i18n("Previous Temp&late Only"), "prevtemplate", CTRL+Key_Up,
+ _catalogManager, SLOT(gotoPreviousTemplate()),actionCollection(), "go_prev_template");
+ action->setEnabled(false);
+ action = new KAction(i18n("Next Tran&slation Exists"), "nextpo", ALT+Key_Down,
+ _catalogManager, SLOT(gotoNextPo()),actionCollection(), "go_next_po");
+ action->setEnabled(false);
+ action = new KAction(i18n("Previous Transl&ation Exists"), "prevpo", ALT+Key_Up,
+ _catalogManager, SLOT(gotoPreviousPo()),actionCollection(), "go_prev_po");
+ action->setEnabled(false);
+
+ action = new KAction(i18n("Previous Marke&d"), "prevmarked", SHIFT+Key_Up,
+ _catalogManager, SLOT(gotoPreviousMarked()),actionCollection(), "go_prev_marked");
+ action->setEnabled(false);
+ action = new KAction(i18n("Next &Marked"), "nextmarked", SHIFT+Key_Down,
+ _catalogManager, SLOT(gotoNextMarked()),actionCollection(), "go_next_marked");
+ action->setEnabled(false);
+
+ // project menu
+ // 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");
+
+ // tools menu
+ action = new KAction( i18n("&Statistics"), "statistics", CTRL+Key_S,
+ _catalogManager, SLOT(statistics()), actionCollection(), "statistics");
+ action->setEnabled(false);
+ action = new KAction( i18n("S&tatistics in Marked"), "statistics", CTRL+ALT+Key_S,
+ _catalogManager, SLOT(markedStatistics()), actionCollection(), "statistics_marked");
+ action->setEnabled(false);
+ action = new KAction( i18n("Check S&yntax"), "syntax", CTRL+Key_Y,
+ _catalogManager, SLOT(checkSyntax()), actionCollection(), "syntax");
+ action->setEnabled(false);
+ action = new KAction( i18n("S&pell Check"), "spellcheck", CTRL+Key_I,
+ this, SLOT(spellcheck()), actionCollection(), "spellcheck");
+ action->setEnabled(false);
+ action = new KAction( i18n("Spell Check in &Marked"), "spellcheck", CTRL+ALT+Key_I,
+ this, SLOT(markedSpellcheck()), actionCollection(), "spellcheck_marked");
+ action->setEnabled(false);
+ action = new KAction( i18n("&Rough Translation"), CTRL+Key_T,
+ _catalogManager, SLOT(roughTranslation()), actionCollection(), "rough_translation");
+ action->setEnabled(false);
+ action = new KAction( i18n("Rough Translation in M&arked"), CTRL+ALT+Key_T,
+ _catalogManager, SLOT(markedRoughTranslation()), actionCollection(), "rough_translation_marked");
+ action->setEnabled(false);
+ action = new KAction( i18n("Mai&l"), "mail_send", CTRL+Key_A,
+ _catalogManager, SLOT(mailFiles()), actionCollection(), "mail_file");
+ action->setEnabled(false);
+ action = new KAction( i18n("Mail Mar&ked"), "mail_send", CTRL+ALT+Key_A,
+ _catalogManager, SLOT(mailMarkedFiles()), actionCollection(), "mail_file_marked");
+ action->setEnabled(false);
+
+ action = new KAction( i18n("&Pack"), "tar", CTRL+Key_B,
+ _catalogManager, SLOT(packageFiles()), actionCollection(), "package_file");
+ action = new KAction( i18n("Pack &Marked"), "tar", CTRL+ALT+Key_B, _catalogManager, SLOT(packageMarkedFiles()), actionCollection(), "package_file_marked");
+ action->setEnabled(false);
+
+ actionMap["statistics_marked"] = NEEDS_DIR | NEEDS_MARK;
+ actionMap["syntax"] = NEEDS_PO;
+ actionMap["spellcheck"] = NEEDS_PO;
+ actionMap["spellcheck_marked"] = NEEDS_PO | NEEDS_MARK;
+ actionMap["rough_translation_marked"] = NEEDS_MARK;
+ actionMap["mail_file"] = NEEDS_PO;
+ actionMap["mail_file_marked"] = NEEDS_PO | NEEDS_MARK;
+ actionMap["package_file_marked"] = NEEDS_PO | NEEDS_MARK;
+
+ // dynamic tools
+ QValueList<KDataToolInfo> tools = ToolAction::validationTools();
+
+ QPtrList<KAction> actions = ToolAction::dataToolActionList(
+ tools, _catalogManager, SLOT(validateUsingTool( const KDataToolInfo &, const QString& ))
+ ,"validate", false, actionCollection() );
+
+ KActionMenu* m_menu = new KActionMenu(i18n("&Validation"), actionCollection(),
+ "dynamic_validation");
+
+ KAction*ac;
+
+ for(ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ actions = ToolAction::dataToolActionList(
+ tools, _catalogManager, SLOT(validateMarkedUsingTool( const KDataToolInfo &, const QString& ))
+ ,"validate", false, actionCollection(), "marked_" );
+ m_menu = new KActionMenu(i18n("V&alidation Marked"), actionCollection(),
+ "dynamic_validation_marked");
+
+ for( ac = actions.first(); ac ; ac = actions.next() )
+ {
+ m_menu->insert(ac);
+ }
+
+ actionMap["dynamic_validation"] = NEEDS_PO;
+ actionMap["dynamic_validation_marked"] = NEEDS_PO | NEEDS_MARK;
+
+ // CVS submenu
+ // Actions for PO files
+ (void)new KAction( i18n( "Update" ), "down", 0, _catalogManager,
+ SLOT( cvsUpdate( ) ), actionCollection( ), "cvs_update" );
+ (void)new KAction( i18n( "Update Marked" ), 0, _catalogManager,
+ SLOT( cvsUpdateMarked( ) ), actionCollection( ), "cvs_update_marked" );
+ (void)new KAction( i18n( "Commit" ), "up", 0, _catalogManager,
+ SLOT( cvsCommit( ) ), actionCollection( ), "cvs_commit" );
+ (void)new KAction( i18n( "Commit Marked" ), 0, _catalogManager,
+ SLOT( cvsCommitMarked( ) ), actionCollection( ), "cvs_commit_marked" );
+ (void)new KAction( i18n( "Status" ), 0, _catalogManager,
+ SLOT( cvsStatus( ) ), actionCollection( ), "cvs_status" );
+ (void)new KAction( i18n( "Status for Marked" ), 0, _catalogManager,
+ SLOT( cvsStatusMarked( ) ), actionCollection( ), "cvs_status_marked" );
+ (void)new KAction( i18n( "Show Diff" ), 0, _catalogManager,
+ SLOT( cvsDiff( ) ), actionCollection( ), "cvs_diff" );
+
+ // CVS
+ actionMap["cvs_update"] = NEEDS_PO | NEEDS_PO_CVS;
+ actionMap["cvs_update_marked"] = NEEDS_PO | NEEDS_PO_CVS | NEEDS_MARK;
+ actionMap["cvs_commit"] = NEEDS_PO | NEEDS_PO_CVS;
+ actionMap["cvs_commit_marked"] = NEEDS_PO | NEEDS_PO_CVS | NEEDS_MARK;
+ actionMap["cvs_status"] = NEEDS_PO | NEEDS_PO_CVS;
+ actionMap["cvs_status_marked"] = NEEDS_PO | NEEDS_PO_CVS | NEEDS_MARK;
+ actionMap["cvs_diff"] = NEEDS_PO | NEEDS_PO_CVS;
+
+ // SVN submenu
+ // Actions for PO files
+ (void)new KAction( i18n( "Update" ), "down", 0, _catalogManager,
+ SLOT( svnUpdate( ) ), actionCollection( ), "svn_update" );
+ (void)new KAction( i18n( "Update Marked" ), 0, _catalogManager,
+ SLOT( svnUpdateMarked( ) ), actionCollection( ), "svn_update_marked" );
+ (void)new KAction( i18n( "Commit" ), "up", 0, _catalogManager,
+ SLOT( svnCommit( ) ), actionCollection( ), "svn_commit" );
+ (void)new KAction( i18n( "Commit Marked" ), 0, _catalogManager,
+ SLOT( svnCommitMarked( ) ), actionCollection( ), "svn_commit_marked" );
+ (void)new KAction( i18n( "Status (Local)" ), 0, _catalogManager,
+ SLOT( svnStatusLocal() ), actionCollection( ), "svn_status_local" );
+ (void)new KAction( i18n( "Status (Local) for Marked" ), 0, _catalogManager,
+ SLOT( svnStatusLocalMarked() ), actionCollection( ), "svn_status_local_marked" );
+ (void)new KAction( i18n( "Status (Remote)" ), 0, _catalogManager,
+ SLOT( svnStatusRemote() ), actionCollection( ), "svn_status_remote" );
+ (void)new KAction( i18n( "Status (Remote) for Marked" ), 0, _catalogManager,
+ SLOT( svnStatusRemoteMarked() ), actionCollection( ), "svn_status_remote_marked" );
+ (void)new KAction( i18n( "Show Diff" ), 0, _catalogManager,
+ SLOT( svnDiff( ) ), actionCollection( ), "svn_diff" );
+ (void)new KAction( i18n( "Show Information" ), 0, _catalogManager,
+ SLOT( svnInfo() ), actionCollection( ), "svn_info" );
+ (void)new KAction( i18n( "Show Information for Marked" ), 0, _catalogManager,
+ SLOT( svnInfoMarked() ), actionCollection( ), "svn_info_marked" );
+
+ // SVN
+ actionMap["svn_update"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_update_marked"] = NEEDS_PO | NEEDS_PO_SVN | NEEDS_MARK;
+ actionMap["svn_commit"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_commit_marked"] = NEEDS_PO | NEEDS_PO_SVN | NEEDS_MARK;
+ actionMap["svn_status_local"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_status_local_marked"] = NEEDS_PO | NEEDS_PO_SVN | NEEDS_MARK;
+ actionMap["svn_status_remote"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_status_remote_marked"] = NEEDS_PO | NEEDS_PO_SVN | NEEDS_MARK;
+ actionMap["svn_diff"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_info"] = NEEDS_PO | NEEDS_PO_SVN;
+ actionMap["svn_info_marked"] = NEEDS_PO | NEEDS_PO_SVN | NEEDS_MARK;
+
+ // CVS Actions for POT files
+ (void)new KAction( i18n( "Update Templates" ), 0, _catalogManager,
+ SLOT( cvsUpdateTemplate( ) ), actionCollection( ), "cvs_update_template" );
+ (void)new KAction( i18n( "Update Marked Templates" ), 0, _catalogManager,
+ SLOT( cvsUpdateMarkedTemplate( ) ), actionCollection( ), "cvs_update_marked_template" );
+ (void)new KAction( i18n( "Commit Templates" ), 0, _catalogManager,
+ SLOT( cvsCommitTemplate( ) ), actionCollection( ), "cvs_commit_template" );
+ (void)new KAction( i18n( "Commit Marked Templates" ), 0, _catalogManager,
+ SLOT( cvsCommitMarkedTemplate( ) ), actionCollection( ), "cvs_commit_marked_template" );
+
+ actionMap["cvs_update_template"] = NEEDS_POT | NEEDS_POT_CVS;
+ actionMap["cvs_update_marked_template"] = NEEDS_POT | NEEDS_POT_CVS | NEEDS_MARK;
+ actionMap["cvs_commit_template"] = NEEDS_POT | NEEDS_POT_CVS;
+ actionMap["cvs_commit_marked_template"] = NEEDS_POT | NEEDS_POT_CVS | NEEDS_MARK;
+
+ // SVN Actions for POT files
+ (void)new KAction( i18n( "Update Templates" ), 0, _catalogManager,
+ SLOT( svnUpdateTemplate( ) ), actionCollection( ), "svn_update_template" );
+ (void)new KAction( i18n( "Update Marked Templates" ), 0, _catalogManager,
+ SLOT( svnUpdateMarkedTemplate( ) ), actionCollection( ), "svn_update_marked_template" );
+ (void)new KAction( i18n( "Commit Templates" ), 0, _catalogManager,
+ SLOT( svnCommitTemplate( ) ), actionCollection( ), "svn_commit_template" );
+ (void)new KAction( i18n( "Commit Marked Templates" ), 0, _catalogManager,
+ SLOT( svnCommitMarkedTemplate( ) ), actionCollection( ), "svn_commit_marked_template" );
+
+ actionMap["svn_update_template"] = NEEDS_POT | NEEDS_POT_SVN;
+ actionMap["svn_update_marked_template"] = NEEDS_POT | NEEDS_POT_SVN | NEEDS_MARK;
+ actionMap["svn_commit_template"] = NEEDS_POT | NEEDS_POT_SVN;
+ actionMap["svn_commit_marked_template"] = NEEDS_POT | NEEDS_POT_SVN | NEEDS_MARK;
+
+ // settings menu
+ // FIXME: KStdAction::preferences(this, SLOT( optionsPreferences()), actionCollection());
+
+ createStandardStatusBarAction();
+
+ setStandardToolBarMenuEnabled ( true );
+
+ // commands menus
+ KActionMenu* actionMenu=new KActionMenu(i18n("Commands"), 0,
+ actionCollection(), "dir_commands");
+ _catalogManager->setDirCommandsMenu( actionMenu->popupMenu());
+
+ actionMenu=new KActionMenu(i18n("Commands"), 0,
+ actionCollection(), "file_commands");
+ _catalogManager->setFileCommandsMenu( actionMenu->popupMenu());
+
+ action = new KAction(i18n("&Delete"),Key_Delete,_catalogManager,SLOT(slotDeleteFile()),actionCollection(), "delete");
+ action->setEnabled(false);
+
+#if KDE_IS_VERSION( 3, 2, 90 )
+ setupGUI();
+#else
+ createGUI();
+#endif
+}
+
+void CatalogManager::setupStatusBar()
+{
+ _foundLabel = new QLabel( " ", statusBar());
+ statusBar()->addWidget(_foundLabel,0);
+
+ QHBox* progressBox = new QHBox(statusBar(), "progressBox" );
+ progressBox->setSpacing(2);
+ _statusProgressLabel = new QLabel( "", progressBox );
+ _statusProgressBar = new KProgress( progressBox, "progressBar");
+ _statusProgressBar->hide();
+
+ statusBar()->addWidget(progressBox,1);
+ statusBar()->setMinimumHeight(_statusProgressBar->sizeHint().height());
+
+ QWhatsThis::add(statusBar(),
+ i18n("<qt><p><b>Statusbar</b></p>\n"
+ "<p>The statusbar displays information about progress of"
+ " the current find or replace operation. The first number in <b>Found:</b>"
+ " displays the number of files with an occurrence of the searched text not"
+ " yet shown in the KBabel window. The second shows the total number of files"
+ " containing the searched text found so far.</p></qt>"));
+}
+
+void CatalogManager::enableMenuForFiles(bool enable)
+{
+ stateChanged( "treeBuilt", enable ? StateNoReverse: StateReverse );
+}
+
+void CatalogManager::selectedChanged(uint actionValue)
+{
+ QMap<QString,uint>::Iterator it;
+ for (it = actionMap.begin( ); it != actionMap.end( ); ++it) {
+ KAction * action = actionCollection()->action(it.key( ).latin1( ));
+ if (action) action->setEnabled((actionValue & it.data( )) == it.data( ));
+ }
+}
+
+CatManSettings CatalogManager::settings() const
+{
+ return _catalogManager->settings();
+}
+
+void CatalogManager::updateSettings()
+{
+ _settings = _project->catManSettings();
+ _catalogManager->setSettings(_settings);
+ _openNewWindow=_settings.openWindow;
+}
+
+void CatalogManager::saveSettings( QString configFile )
+{
+ _settings = _catalogManager->settings(); // restore settings from the view
+
+ _project->setSettings( _settings );
+
+ config = new KConfig(configFile);
+
+ _catalogManager->saveView(config);
+
+ config->sync();
+}
+
+void CatalogManager::restoreSettings()
+{
+ _settings = _project->catManSettings();
+ _openNewWindow=_settings.openWindow;
+ _catalogManager->restoreView(_project->config());
+}
+
+void CatalogManager::setPreferredWindow(WId window)
+{
+ _preferredWindow = window;
+ kdDebug(KBABEL_CATMAN) << "setPrefereedWindow set to :" << _preferredWindow << endl;
+}
+
+void CatalogManager::updateFile(QString fileWithPath)
+{
+ _catalogManager->updateFile(fileWithPath,true); //force update
+}
+
+void CatalogManager::updateAfterSave(QString fileWithPath, PoInfo &info)
+{
+ _catalogManager->updateAfterSave(fileWithPath, info);
+}
+
+CatalogManagerView *CatalogManager::view()
+{
+ return _catalogManager;
+}
+
+void CatalogManager::openFile(QString filename, QString package)
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ if( startKBabel() )
+ {
+
+ QByteArray data;
+ QCString url = filename.local8Bit();
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url;
+ arg << package.utf8();
+ arg << CatalogManagerApp::_preferredWindow;
+ arg << ( _openNewWindow ? 1 : 0 );
+
+ kdDebug(KBABEL_CATMAN) << "Open file with project " << _configFile << endl;
+
+ QCString callfunc="openURL(QCString, QCString, WId,int)";
+ if(_configFile != "kbabelrc" )
+ {
+ arg << _configFile.utf8();
+ callfunc="openURL(QCString, QCString, WId,int,QCString)";
+ }
+
+ kdDebug(KBABEL_CATMAN) << callfunc << endl;
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", callfunc, data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::openFile(QString filename, QString package, int msgid)
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ if( startKBabel() )
+ {
+ QByteArray data;
+ QCString url = filename.local8Bit();
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url;
+ arg << package.utf8();
+ arg << msgid;
+
+ kdDebug(KBABEL_CATMAN) << "Open file with project " << _configFile << endl;
+
+ QCString callfunc="gotoFileEntry(QCString, QCString, int)";
+ if(_configFile != "kbabelrc" )
+ {
+ arg << _configFile.utf8();
+ callfunc="gotoFileEntry(QCString, QCString,int,QCString)";
+ }
+
+ kdDebug(KBABEL_CATMAN) << callfunc << endl;
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", callfunc, data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::openFileInNewWindow(QString filename, QString package)
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ if( startKBabel() )
+ {
+
+ QByteArray data;
+ QCString url = filename.local8Bit();
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url;
+ arg << package.utf8();
+ arg << CatalogManagerApp::_preferredWindow;
+ arg << ((int)1);
+
+ QCString callfunc="openURL(QCString, QCString, WId,int)";
+ if(_configFile != "kbabelrc" )
+ {
+ arg << _configFile.utf8();
+ callfunc="openURL(QCString, QCString, WId,int,QCString)";
+ }
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", callfunc, data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::openTemplate(QString openFilename,QString saveFilename,QString package)
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ if( startKBabel() ) {
+ QByteArray data;
+ QCString url = openFilename.local8Bit();
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url;
+ url = saveFilename.utf8();
+ arg << url;
+ arg << package.utf8();
+ arg << (_openNewWindow ? 1 : 0 );
+
+ QCString callfunc="openTemplate(QCString,QCString,QCString,int)";
+ if(_configFile != "kbabelrc" )
+ {
+ arg << _configFile.utf8();
+ callfunc="openTemplate(QCString,QCString,QCString,int,QCString)";
+ }
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", callfunc, data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::openTemplateInNewWindow(QString openFilename,QString saveFilename,QString package)
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ if( startKBabel() ) {
+ QByteArray data;
+ QCString url = openFilename.local8Bit();
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url;
+ url = saveFilename.utf8();
+ arg << url;
+ arg << package.utf8();
+ arg << ((int)1);
+
+ QCString callfunc="openTemplate(QCString,QCString,QCString,int)";
+ if(_configFile != "kbabelrc" )
+ {
+ arg << _configFile.utf8();
+ callfunc="openTemplate(QCString,QCString,QCString,int,QCString)";
+ }
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", callfunc, data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::spellcheck()
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ QStringList fileList = _catalogManager->current();
+
+ if( startKBabel() ) {
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << fileList;
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", "spellcheck(QStringList)", data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+void CatalogManager::markedSpellcheck()
+{
+ DCOPClient * client = kapp->dcopClient();
+
+ QStringList fileList = _catalogManager->marked();
+
+ if( startKBabel() ) {
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << fileList;
+
+ // update the user timestamp for KBabel to get it a focus
+ kapp->updateRemoteUserTimestamp ("kbabel");
+
+ if( !client->send("kbabel","KBabelIFace", "spellcheck(QStringList)", data) )
+ KMessageBox::error(this, i18n("Cannot send a message to KBabel.\n"
+ "Please check your installation of KDE."));
+ }
+}
+
+bool CatalogManager::startKBabel()
+{
+ QCString service;
+ QString result;
+
+ DCOPClient * client = kapp->dcopClient();
+
+ // find out, if there is a running kbabel
+ QCStringList apps = client->registeredApplications();
+ for( QCStringList::Iterator it = apps.begin() ; it != apps.end() ; ++it )
+ {
+ QString clientID = *it;
+ if( clientID=="kbabel" )
+ {
+ service = *it;
+ break;
+ }
+ }
+
+ // if there is no running kbabel, start one
+ if( service.isEmpty() )
+ {
+ QString app = "kbabel";
+ QString url = "";
+ if( kapp->startServiceByDesktopName(app,url, &result, &service))
+ {
+ KMessageBox::error( this, i18n("Unable to use KLauncher to start KBabel.\n"
+ "You should check the installation of KDE.\n"
+ "Please start KBabel manually."));
+ return false;
+ } else sleep(1);
+ }
+
+ return true;
+}
+
+
+void CatalogManager::prepareProgressBar(QString msg, int max)
+{
+ _progressBar->setTotalSteps(max);
+ _progressBar->setProgress(0);
+ _progressLabel->setText(msg);
+
+ _progressBar->show();
+ _progressLabel->show();
+}
+
+void CatalogManager::clearProgressBar()
+{
+ _progressBar->setProgress(0);
+
+ _progressBar->hide();
+ _progressLabel->hide();
+}
+
+void CatalogManager::prepareStatusProgressBar(QString msg, int max)
+{
+ _totalFound = 0;
+ _foundToBeSent = 0;
+ _statusProgressBar->setTotalSteps(max);
+ _statusProgressLabel->setText(msg);
+ _foundLabel->setText( i18n("Found: 0/0") );
+
+ _statusProgressBar->show();
+ _statusProgressLabel->show();
+}
+
+void CatalogManager::prepareStatusProgressBar(int max)
+{
+ _statusProgressBar->setTotalSteps(max);
+}
+
+void CatalogManager::clearStatusProgressBar()
+{
+ _statusProgressBar->setValue(0);
+
+ _statusProgressBar->hide();
+ _statusProgressLabel->hide();
+ _foundLabel->setText(" ");
+}
+
+void CatalogManager::setNumberOfFound(int toBeSent, int total)
+{
+ _foundLabel->setText(i18n("Found: %1/%2").arg(toBeSent).arg(total));
+}
+
+void CatalogManager::decreaseNumberOfFound()
+{
+ if( _foundToBeSent > 0 ) {
+ _foundToBeSent--;
+ setNumberOfFound( _foundToBeSent, _totalFound );
+ }
+}
+
+void CatalogManager::slotHelp()
+{
+ kapp->invokeHelp("CATALOGMANAGER","kbabel");
+}
+
+void CatalogManager::find()
+{
+ if( !_findDialog ) _findDialog = new FindInFilesDialog(false,this);
+
+ if( _findDialog->exec("") == QDialog::Accepted )
+ {
+ _timerFind->stop();
+ _searchStopped = false;
+ _catalogManager->stop(false); // surely we are not in process of quitting, since there is no window and user cannot invoke Find
+ prepareStatusProgressBar(i18n("Searching"),1); // just show the progress bar
+
+ // enable stop action to stop searching
+ KAction *action = (KAction*)actionCollection()->action("stop_search");
+ action->setEnabled(true);
+
+ _findOptions = _findDialog->findOpts();
+
+ // get from options the information for ignoring text parts
+ _findOptions.contextInfo = QRegExp( _project->miscSettings().contextInfo );
+ _findOptions.accelMarker = _project->miscSettings().accelMarker;
+
+ _foundFilesList.clear();
+ kdDebug(KBABEL_CATMAN) << "Calling catalogmanagerview::find" << endl;
+ QString url = _catalogManager->find(_findOptions, _toBeSearched );
+
+ if( _catalogManager->isStopped() ) return;
+ if( !url.isEmpty() )
+ {
+ if( startKBabel() )
+ {
+ QCString funcCall("findInFile(QCString,QCString,QString,int,int,int,int,int,int,int,int,int,int)");
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << client->appId();
+ arg << url.utf8();
+ arg << _findOptions.findStr;
+ arg << (_findOptions.caseSensitive ? 1 : 0);
+ arg << (_findOptions.wholeWords ? 1 : 0);
+ arg << (_findOptions.isRegExp ? 1 : 0);
+ arg << (_findOptions.inMsgid ? 1 : 0);
+ arg << (_findOptions.inMsgstr ? 1 : 0);
+ arg << (_findOptions.inComment ? 1 : 0);
+ arg << (_findOptions.ignoreAccelMarker ? 1 : 0);
+ arg << (_findOptions.ignoreContextInfo ? 1 : 0);
+ arg << (_findOptions.askForNextFile ? 1 : 0);
+ arg << (_findOptions.askForSave ? 1 : 0);
+ if(_configFile != "kbabelrc" ) {
+ arg << _configFile.utf8();
+ funcCall="findInFile(QCString,QCString,QString,int,int,int,int,int,int,int,int,int,int,QCString)";
+ }
+ kdDebug(KBABEL) << "DCOP: " << QString(data.data()) << endl;
+ if( !client->send("kbabel","KBabelIFace",
+ funcCall, data)
+ ) {
+ KMessageBox::error( this, i18n("DCOP communication with KBabel failed."), i18n("DCOP Communication Error"));
+ stopSearching();
+ return;
+ }
+
+ if( !_toBeSearched.isEmpty() )
+ {
+ _totalFound = 1;
+ _foundToBeSent = 0;
+ setNumberOfFound( 0, 1 ); // one found, but already sent
+ _timerFind->start(100,true);
+ } else stopSearching();
+ }
+ else
+ {
+ KMessageBox::error( this, i18n("KBabel cannot be started."), i18n("Cannot Start KBabel"));
+ stopSearching();
+ }
+
+ }
+ else
+ {
+ if( !_searchStopped) KMessageBox::information(this, i18n("Search string not found!"));
+ stopSearching();
+ }
+ }
+}
+
+void CatalogManager::replace()
+{
+ if( !_replaceDialog ) _replaceDialog = new FindInFilesDialog(true,this);
+
+
+ if( _replaceDialog->exec("") == QDialog::Accepted )
+ {
+ _timerFind->stop();
+ _searchStopped = false;
+ _catalogManager->stop(false); // surely we are not in process of quitting, since there is no window and user cannot invoke Find
+ prepareStatusProgressBar(i18n("Searching"),1); // just show the progress bar
+
+ // enable stop action to stop searching
+ KAction *action = (KAction*)actionCollection()->action("stop_search");
+ action->setEnabled(true);
+
+ ReplaceOptions options = _replaceDialog->replaceOpts();
+
+ _findOptions = options;
+
+ // get from options the information for ignoring text parts
+ options.contextInfo = QRegExp( _project->miscSettings().contextInfo );
+ options.accelMarker = _project->miscSettings().accelMarker;
+
+ _foundFilesList.clear();
+ QString url = _catalogManager->find(options, _toBeSearched );
+
+ if( _catalogManager->isStopped() ) return;
+ if( !url.isEmpty() )
+ {
+ if( startKBabel() )
+ {
+ QCString funcCall("replaceInFile(QCString,QCString,QString,QString,int,int,int,int,int,int,int,int,int,int,int)");
+ DCOPClient *client = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+
+ arg << client->appId();
+ arg << url.utf8();
+ arg << options.findStr;
+ arg << options.replaceStr;
+ arg << (options.caseSensitive ? 1 : 0);
+ arg << (options.wholeWords ? 1 : 0);
+ arg << (options.isRegExp ? 1 : 0);
+ arg << (options.inMsgid ? 1 : 0);
+ arg << (options.inMsgstr ? 1 : 0);
+ arg << (options.inComment ? 1 : 0);
+ arg << (options.ignoreAccelMarker ? 1 : 0);
+ arg << (options.ignoreContextInfo ? 1 : 0);
+ arg << (options.ask ? 1 : 0);
+ arg << (options.askForNextFile ? 1 : 0);
+ arg << (options.askForSave ? 1 : 0);
+ if(_configFile != "kbabelrc" ) {
+ arg << _configFile.utf8();
+ funcCall="replaceInFile(QCString,QCString,QString,QString,int,int,int,int,int,int,int,int,int,int,int,QCString)";
+ }
+ if( !client->send("kbabel","KBabelIFace",
+ funcCall, data)
+ ) {
+ KMessageBox::error( this, i18n("DCOP communication with KBabel failed."), i18n("DCOP Communication Error"));
+ stopSearching();
+ return;
+ }
+
+ if( !_toBeSearched.isEmpty() )
+ {
+ _totalFound = 1;
+ setNumberOfFound( 0, 1 );
+ _timerFind->start(100,true);
+ } else stopSearching();
+ }
+ else
+ {
+ KMessageBox::error( this, i18n("KBabel cannot be started."), i18n("Cannot Start KBabel"));
+ stopSearching(); // update window
+ }
+
+ }
+ else
+ {
+ if( !_searchStopped ) KMessageBox::information(this, i18n("Search string not found!"));
+ stopSearching(); // update window
+ }
+ }
+}
+
+void CatalogManager::findNextFile()
+{
+ _timerFind->stop(); // stop the timer for lookup time
+ if(_toBeSearched.empty() )
+ {
+ stopSearching();
+ return;
+ }
+ QString file = _toBeSearched.first();
+ _toBeSearched.pop_front();
+ if( PoInfo::findInFile( file, _findOptions ) )
+ {
+ _foundFilesList.append(file);
+ _totalFound++;
+ _foundToBeSent++;
+ setNumberOfFound(_foundToBeSent,_totalFound);
+ }
+ _statusProgressBar->advance(1);
+ if( !_toBeSearched.empty() )
+ _timerFind->start(100,true); // if there is more files to be searched, start the timer again
+ else
+ stopSearching();
+}
+
+void CatalogManager::stopSearching()
+{
+ _searchStopped = true;
+ emit searchStopped();
+ // clear the list of files to be searched
+ _toBeSearched.clear();
+
+ // fake that we are over (fake, because findNextFile can still be running for the last file
+ clearStatusProgressBar(); // clear the status bar, we are finished
+ // disable stop action as well
+ KAction *action = (KAction*)actionCollection()->action("stop_search");
+ action->setEnabled(false);
+}
+
+void CatalogManager::optionsPreferences()
+{
+ if(!_prefDialog)
+ {
+ _prefDialog = new KBabel::ProjectDialog(_project);
+ }
+
+ _prefDialog->exec();
+}
+
+void CatalogManager::newToolbarConfig()
+{
+ createGUI();
+ restoreView();
+}
+
+void CatalogManager::optionsShowStatusbar(bool on)
+{
+ if( on )
+ statusBar()->show();
+ else
+ statusBar()->hide();
+}
+
+bool CatalogManager::queryClose()
+{
+ _catalogManager->stop();
+ saveView();
+ saveSettings(_configFile);
+ return true;
+}
+
+void CatalogManager::saveView()
+{
+ saveMainWindowSettings( KGlobal::config(), "View");
+}
+
+
+void CatalogManager::restoreView()
+{
+ applyMainWindowSettings( KGlobal::config(), "View");
+
+ KToggleAction * toggle = (KToggleAction*)actionCollection()->
+ action(KStdAction::stdName(KStdAction::ShowStatusbar));
+ toggle->setChecked(!statusBar()->isHidden() );
+}
+
+
+void CatalogManager::projectNew()
+{
+ KBabel::Project::Ptr p = KBabel::ProjectWizard::newProject();
+ if( p )
+ {
+ disconnect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+ _project = p;
+ connect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+
+ _configFile = _project->filename();
+ restoreSettings();
+ updateSettings();
+ changeProjectActions(p->filename());
+ emit settingsChanged(_settings);
+ }
+}
+
+void CatalogManager::projectOpen()
+{
+ QString oldproject = _project->filename();
+ if( oldproject == KBabel::ProjectManager::defaultProjectName() )
+ {
+ oldproject = QString();
+ }
+ const QString file = KFileDialog::getOpenFileName(oldproject, QString::null, this);
+ if (file.isEmpty())
+ {
+ return;
+ }
+ KBabel::Project::Ptr p = KBabel::ProjectManager::open(file);
+ if( p )
+ {
+ disconnect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+ _project = p;
+ connect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+
+ _configFile = p->filename();
+ restoreSettings();
+ updateSettings();
+ changeProjectActions(file);
+ emit settingsChanged(_settings);
+
+ }
+ else
+ {
+ KMessageBox::error (this, i18n("Cannot open project file %1").arg(file));
+ }
+}
+
+void CatalogManager::projectClose()
+{
+ disconnect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+ _project = KBabel::ProjectManager::open(KBabel::ProjectManager::defaultProjectName());
+ connect( _project, SIGNAL (signalCatManSettingsChanged())
+ , this, SLOT (updateSettings()));
+ _configFile = _project->filename();
+ restoreSettings();
+ updateSettings();
+ changeProjectActions(KBabel::ProjectManager::defaultProjectName());
+ emit settingsChanged(_settings);
+}
+
+void CatalogManager::changeProjectActions(const QString& project)
+{
+ bool def = ( project == KBabel::ProjectManager::defaultProjectName() ) ;
+
+ KAction* saveAction=(KAction*)actionCollection()->action( "project_close" );
+ saveAction->setEnabled( ! def );
+}
+
+void CatalogManager::projectConfigure()
+{
+ KBabel::ProjectDialog* _projectDialog = new ProjectDialog(_project);
+
+ connect (_projectDialog, SIGNAL (settingsChanged())
+ , this, SLOT (updateSettings()));
+
+ // settings are updated via signals
+ _projectDialog->exec();
+
+ delete _projectDialog;
+}
+
+void CatalogManager::enableActions()
+{
+ enableActions(true);
+}
+
+void CatalogManager::disableActions()
+{
+ enableActions(false);
+}
+
+void CatalogManager::enableActions(bool enable)
+{
+ KAction* action;
+ // the file menu
+
+ action = (KAction*)actionCollection()->action( "open" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "open_new_window" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "find_in_files" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "replace_in_files" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "reload" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "toggle_marking" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "toggle_all_marking" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "mark_modified_files" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "load_marking" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "save_marking" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_untrans" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_untrans" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_fuzzy" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_fuzzy" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_fuzzyUntr" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_fuzzyUntr" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_error" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_error" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_template" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_template" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_po" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_po" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_next_marked" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "go_prev_marked" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "statistics" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "package_file" );
+ action->setEnabled(enable);
+
+ action = (KAction*)actionCollection()->action( "rough_translation" );
+ action->setEnabled(enable);
+}
+
+#include "catalogmanager.moc"
diff --git a/kbabel/catalogmanager/catalogmanager.desktop b/kbabel/catalogmanager/catalogmanager.desktop
new file mode 100644
index 00000000..3c470b1c
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanager.desktop
@@ -0,0 +1,98 @@
+[Desktop Entry]
+Name=KBabel Catalog Manager
+Name[bg]=Управление на каталога - KBabel
+Name[br]=Merour katalogoù KBabel
+Name[ca]=Gestor de catàlegs de KBabel
+Name[cs]=Správce katalogů
+Name[da]=KBabel kataloghåndtering
+Name[de]=KBabel-Katalogmanager
+Name[el]=Διαχειριστής καταλόγων του KBabel
+Name[en_GB]=KBabel Catalogue Manager
+Name[eo]=Babelo-katalogadministrilo
+Name[es]=Administrador de catálogos de KBabel
+Name[et]=Kataloogihaldur
+Name[eu]=KBabel katalogo kudeatzailea
+Name[fa]= مدیر فهرست KBabel
+Name[fi]=KBabel - käännöspakettien hallinta
+Name[fr]=Gestionnaire de catalogues de KBabel
+Name[ga]=KBabel - Bainisteoir na gCatalóg
+Name[gl]=Xestor de Catálogos de KBabel
+Name[he]=KBabel - מנהל הקטלוגים
+Name[hu]=KBabel listakezelő
+Name[is]=KBabel Þýðingarstjóri
+Name[it]=Gestore dei cataloghi di KBabel
+Name[ja]=KBabel カタログマネージャ
+Name[ka]=KBabel-ის კატალოგის მმართველი
+Name[kk]=KBabel каталог менеджері
+Name[lt]=KBabel katalogo tvarkytuvė
+Name[nb]=KBabel-katalogbehandler
+Name[nds]=KBabel-Kataloogpleger
+Name[ne]=केब्याबल विवरणिका प्रबन्धक
+Name[nl]=KBabel catalogusbeheer
+Name[nn]=KBabel Kataloghandsamar
+Name[pa]=KBabel ਸੂਚੀ ਪ੍ਰਬੰਧਕ
+Name[pl]=KBabel - Menedżer tłumaczeń
+Name[pt]=Gestor de Catálogos do KBabel
+Name[pt_BR]=Gerenciador de Catálogos do KBabel
+Name[ru]=Менеджер сообщений Gettext
+Name[sk]=KBabel - správca katalógov
+Name[sl]=Upravitelj katalogov KBabel
+Name[sr]=KBabel-ов Менаџер каталога
+Name[sr@Latn]=KBabel-ov Menadžer kataloga
+Name[sv]=Kbabel kataloghanterare
+Name[tr]=KBabel Katalog Yöneticisi
+Name[uk]=Менеджер каталогів KBabel
+Name[zh_CN]=KBabel 目录管理器
+Name[zh_TW]=KBabel - 目錄管理員
+GenericName=Translation Tool Catalog Manager
+GenericName[bg]=Инструмент за превод
+GenericName[ca]=Gestor de catàlegs de l'eina de traducció
+GenericName[cs]=Správce katalogů překladů
+GenericName[da]=Oversættelsesværktøjs kataloghåndtering
+GenericName[de]=Katalogmanager für Übersetzungsprogramm
+GenericName[el]=Διαχειριστής καταλόγων εργαλείου μετάφρασης
+GenericName[en_GB]=Translation Tool Catalogue Manager
+GenericName[eo]=Katalogadministrilo por Tradukiloj
+GenericName[es]=Administrador de catálogos de la herramienta de traducción
+GenericName[et]=KBabel'i kataloogihaldur
+GenericName[eu]=Itzulpen tresnen katalogo kudeatzailea
+GenericName[fa]=مدیر فهرست ابزار ترجمه
+GenericName[fi]=Käännöstyökalun käännöspakettien hallinta
+GenericName[fr]=Gestionnaire de catalogues de traduction
+GenericName[ga]=Uirlis Aistriúcháin - Bainisteoir na gCatalóg
+GenericName[gl]=Xestor de Catálogos de Tradución
+GenericName[he]=מנהל הקטלוגים של כלי התרגום
+GenericName[hu]=Fordítássegítő
+GenericName[is]=Þýðingarforrit - Þýðingarstjóri
+GenericName[it]=Gestore dei cataloghi di uno strumento di traduzione
+GenericName[ja]=翻訳ツール カタログマネージャ
+GenericName[ka]=კატალოგის მმართველის სათარგმნი ხელსაწყო
+GenericName[kk]=Аудару құралының Каталог менеджері
+GenericName[lt]=Vertimo įrankio katalogo tvarkytuvė
+GenericName[nb]=Verktøy for håndtering av oversettelseskataloger
+GenericName[nds]=Översettenwarktüüch-Kataloogpleger
+GenericName[ne]=अनुबाद उपकरण विवरणिका प्रबन्धक
+GenericName[nl]=Vertaalhulpmiddel catalogusbeheer
+GenericName[nn]=Verktøy for handtering av omsetjingskatalogar
+GenericName[pa]=ਅਨੁਵਾਦ ਸੰਦ ਲਈ ਸੂਚੀ ਪ੍ਰਬੰਧਕ
+GenericName[pl]=Menedżer tłumaczeń
+GenericName[pt]=Gestor de Catálogos de Ferramenta de Tradução
+GenericName[pt_BR]=Gerenciador de Catálogo da Ferramenta de Tradução
+GenericName[ru]=Локализация приложений
+GenericName[sk]=Správca katalógov pre prekladací nástroj
+GenericName[sl]=Upravitelj katalogov orodja za prevajanje
+GenericName[sr]=Менаџер каталога преводилачких алата
+GenericName[sr@Latn]=Menadžer kataloga prevodilačkih alata
+GenericName[sv]=Översättningsverktyg kataloghanterare
+GenericName[tr]=Çeviri Aracı Katalog Yöneticisi
+GenericName[uk]=Менеджер каталогів засобу для перекладів
+GenericName[zh_CN]=翻译工具目录管理器
+GenericName[zh_TW]=翻譯工具目錄管理員
+Exec=catalogmanager %i %m -caption "%c" %U
+Icon=catalogmanager
+Type=Application
+DocPath=kbabel/index.html
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Development;Translation;
diff --git a/kbabel/catalogmanager/catalogmanager.h b/kbabel/catalogmanager/catalogmanager.h
new file mode 100644
index 00000000..67f871fa
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanager.h
@@ -0,0 +1,218 @@
+/* ****************************************************************************
+ 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>
+
+ 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 CATALOGMANAGER_H
+#define CATALOGMANAGER_H
+
+#include <qdict.h>
+#include <qlistview.h>
+#include <qdatetime.h>
+#include <qfileinfo.h>
+#include <qguardedptr.h>
+#include <qmap.h>
+
+#include <kdeversion.h>
+#include <kmainwindow.h>
+#include <kdirwatch.h>
+#include <kprocess.h>
+#include <qptrlist.h>
+
+#include "projectsettings.h"
+#include "kbproject.h"
+#include "catalog.h"
+#include "catalogmanagerview.h"
+
+class CatManListItem;
+class QPixmap;
+class QPopupMenu;
+class QTimer;
+class KProgress;
+class KAction;
+class KConfig;
+class FindInFilesDialog;
+
+namespace KBabel
+{
+ class PoInfo;
+ class ProjectDialog;
+}
+
+class CatalogManager : public KMainWindow
+{
+ Q_OBJECT
+public:
+ CatalogManager(QString configfile = QString() );
+ ~CatalogManager();
+
+ KBabel::CatManSettings settings() const;
+ /**
+ * Sets the window, in which the files should be opened.
+ * This is set by KBabel::openCatalogManager
+ */
+ void setPreferredWindow(WId id);
+
+ /** updates the file fileWithPath in the @ref CatalogManagerView */
+ void updateFile(QString fileWithPath);
+ void updateAfterSave(QString fileWithPath, KBabel::PoInfo &info);
+
+ CatalogManagerView *view();
+
+ void pause(bool flag) { if( _catalogManager ) _catalogManager->pause (flag); }
+
+ static QStringList _foundFilesList;
+ static QStringList _toBeSearched;
+
+public slots:
+ /** updates the settings from the project */
+ void updateSettings();
+ void enableMenuForFiles(bool enable);
+ void selectedChanged(uint actionValue);
+ virtual void slotHelp();
+
+ virtual void find();
+ virtual void replace();
+ virtual void stopSearching();
+ virtual void optionsPreferences();
+ virtual void optionsShowStatusbar(bool on);
+ virtual void dummySlot() {}
+
+ void projectNew();
+ void projectOpen();
+ void projectClose();
+ void projectConfigure();
+ void changeProjectActions(const QString& project);
+
+ virtual void clearProgressBar();
+ virtual void prepareProgressBar(QString msg, int max);
+
+ virtual void clearStatusProgressBar();
+ virtual void prepareStatusProgressBar(QString msg, int max);
+ virtual void prepareStatusProgressBar(int max);
+
+ virtual void setNumberOfFound( int toBeSent, int total );
+ virtual void decreaseNumberOfFound();
+
+protected slots:
+ virtual void findNextFile();
+ virtual bool queryClose();
+
+signals:
+ void settingsChanged(KBabel::CatManSettings);
+ void signalQuit();
+ void searchStopped();
+
+private:
+ void init();
+
+ void restoreView();
+ void saveView();
+
+ void saveSettings( QString configFile = QString::null );
+
+ void setupActions();
+ void setupStatusBar();
+
+ bool startKBabel();
+
+private slots:
+ /**
+ * calls @ref KBabel::open where as preferred windos _preferredWindow
+ * is used. If this is deleted meanwhile, the first window in
+ * @ref KMainWindow::memberList is used.
+ */
+ void openFile(QString filename,QString package);
+ void openFile(QString filename,QString package, int msgid);
+ void openFileInNewWindow(QString filename,QString package);
+ /**
+ * calls @ref KBabel::openTemplate where as preferred windos _preferredWindow
+ * is used. If this is deleted meanwhile, the first window in
+ * @ref KMainWindow::memberList is used.
+ */
+ void openTemplate(QString openFilename,QString saveFileName,QString package);
+ void openTemplateInNewWindow(QString openFilename,QString saveFileName,QString package);
+
+ void markedSpellcheck();
+ void spellcheck();
+
+ void newToolbarConfig();
+
+ /** updates views and _settings variable */
+ void restoreSettings();
+
+ void enableActions();
+ void disableActions();
+
+ void enableActions(bool enable);
+
+private:
+ CatalogManagerView* _catalogManager;
+
+ WId _preferredWindow;
+
+ bool _openNewWindow;
+
+ FindInFilesDialog* _findDialog;
+ FindInFilesDialog* _replaceDialog;
+ KBabel::ProjectDialog* _prefDialog;
+
+ /// update progress bar
+ KProgress* _progressBar;
+ QLabel* _progressLabel;
+
+ /// statusbar progress bar
+ KProgress* _statusProgressBar;
+ QLabel* _statusProgressLabel;
+ QLabel* _foundLabel;
+ int _foundToBeSent;
+ int _totalFound;
+
+ QTimer* _timerFind;
+ bool _searchStopped;
+
+ KBabel::CatManSettings _settings;
+ KBabel::MiscSettings _miscSettings;
+
+ /// options used in findNextFile
+ KBabel::FindOptions _findOptions;
+
+
+ /// project configuration file
+ QString _configFile;
+ KBabel::Project::Ptr _project;
+
+ KConfig* config;
+
+ QMap<QString,uint> actionMap;
+};
+
+#endif // CATALOGMANAGER_H
diff --git a/kbabel/catalogmanager/catalogmanagerapp.h b/kbabel/catalogmanager/catalogmanagerapp.h
new file mode 100644
index 00000000..e0762e5b
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanagerapp.h
@@ -0,0 +1,73 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2001 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 CATALOGMANAGERAPP_H
+#define CATALOGMANAGERAPP_H
+
+#include "catalogmanager.h"
+#include "catalogmanageriface.h"
+
+#include "version.h"
+
+#include <kapplication.h>
+#include <kwin.h>
+
+class CatalogManagerInterface : public CatalogManagerIface
+{
+public:
+ CatalogManagerInterface();
+
+ virtual void setPreferredWindow( WId id );
+ virtual QCString findNextFile();
+ virtual void updatedFile( QCString url );
+};
+
+class CatalogManagerApp : public KApplication
+{
+public:
+ CatalogManagerApp();
+ virtual ~CatalogManagerApp();
+
+ virtual int newInstance();
+
+ static void setPreferredWindow( WId id );
+ static QCString findNextFile();
+ static void updatedFile( QCString url );
+ static WId _preferredWindow;
+private:
+ CatalogManagerInterface *kbInterface;
+ static CatalogManager * _view;
+};
+
+#endif
diff --git a/kbabel/catalogmanager/catalogmanageriface.h b/kbabel/catalogmanager/catalogmanageriface.h
new file mode 100644
index 00000000..232a694c
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanageriface.h
@@ -0,0 +1,67 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2001 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 CATALOGMANAGERIFACE_H
+#define CATALOGMANAGERIFACE_H
+
+#include <dcopobject.h>
+
+class CatalogManagerIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+
+k_dcop:
+
+ /**
+ * Sets the WId of the preferred window. The window will get
+ * calls to open files or templates when requested in catalog manager.
+ * @param id is the WId of the window to be used
+ */
+ virtual void setPreferredWindow( WId id ) { id = 0; }
+
+ /**
+ * Returns a next file containing the searched string. Invoked from
+ * KBabel in case the FindNext() finishes a file and wants to continue in
+ * the next one.
+ * @returns a URL to the next file, QString:null if there is no more
+ * files to be searched or empty string if the search string
+ * is not found yet, but there is more files to be searched in.
+ */
+ virtual QCString findNextFile() = 0;
+
+ /**
+ * If you care about this file, you should update information shown.
+ */
+ virtual void updatedFile( QCString url) = 0;
+};
+
+#endif // CATALOGMANAGERIFACE_H
diff --git a/kbabel/catalogmanager/catalogmanagerui.rc b/kbabel/catalogmanager/catalogmanagerui.rc
new file mode 100644
index 00000000..498a4bc7
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanagerui.rc
@@ -0,0 +1,262 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="catalogmanager" version="26">
+ <MenuBar>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="find_in_files"/>
+ <Action name="replace_in_files"/>
+ <Action name="stop_search"/>
+ <Separator/>
+ <Action name="reload"/>
+ </Menu>
+ <Menu name="go"><text>&amp;Go</text>
+ <Action name="go_next_fuzzyUntr"/>
+ <Action name="go_prev_fuzzyUntr"/>
+ <Action name="go_next_fuzzy"/>
+ <Action name="go_prev_fuzzy"/>
+ <Action name="go_next_untrans"/>
+ <Action name="go_prev_untrans"/>
+ <Separator/>
+ <Action name="go_next_error"/>
+ <Action name="go_prev_error"/>
+ <Separator/>
+ <Action name="go_next_marked"/>
+ <Action name="go_prev_marked"/>
+ <Separator/>
+ <Action name="go_next_template"/>
+ <Action name="go_prev_template"/>
+ <Action name="go_next_po"/>
+ <Action name="go_prev_po"/>
+ </Menu>
+ <Menu name="markings"><text>&amp;Markings</text>
+ <Action name="toggle_marking"/>
+ <Action name="remove_marking"/>
+ <Action name="toggle_all_marking"/>
+ <Action name="remove_all_marking"/>
+ <Action name="mark_modified_files"/>
+ <Separator/>
+ <Action name="mark_pattern"/>
+ <Action name="unmark_pattern"/>
+ <Separator/>
+ <Action name="load_marking"/>
+ <Action name="save_marking"/>
+ </Menu>
+ <Menu name="projects"><text>&amp;Project</text>
+ <Action name="project_new"/>
+ <Action name="project_open"/>
+ <Action name="project_close"/>
+ <Action name="project_settings"/>
+ </Menu>
+ <Menu name="tools"><text>&amp;Tools</text>
+ <Action name="statistics"/>
+ <Action name="statistics_marked"/>
+ <Action name="syntax"/>
+ <Separator/>
+ <Action name="spellcheck"/>
+ <Action name="spellcheck_marked"/>
+ <Separator/>
+ <Action name="rough_translation"/>
+ <Action name="rough_translation_marked"/>
+ <Separator/>
+ <Menu name="cvs_menu"><text>CVS</text>
+ <Action name="cvs_update"/>
+ <Action name="cvs_update_marked"/>
+ <Separator/>
+ <Action name="cvs_commit"/>
+ <Action name="cvs_commit_marked"/>
+ <Separator/>
+ <Action name="cvs_status"/>
+ <Action name="cvs_status_marked"/>
+ <Separator/>
+ <Action name="cvs_update_template"/>
+ <Action name="cvs_update_marked_template"/>
+ <Separator/>
+ <Action name="cvs_commit_template"/>
+ <Action name="cvs_commit_marked_template"/>
+ <Separator/>
+ <Action name="cvs_diff"/>
+ </Menu>
+ <Menu name="svn_menu"><text>SVN</text>
+ <Action name="svn_update"/>
+ <Action name="svn_update_marked"/>
+ <Separator/>
+ <Action name="svn_commit"/>
+ <Action name="svn_commit_marked"/>
+ <Separator/>
+ <Action name="svn_status_local"/>
+ <Action name="svn_status_local_marked"/>
+ <Separator/>
+ <Action name="svn_status_remote"/>
+ <Action name="svn_status_remote_marked"/>
+ <Separator/>
+ <Action name="svn_update_template"/>
+ <Action name="svn_update_marked_template"/>
+ <Separator/>
+ <Action name="svn_commit_template"/>
+ <Action name="svn_commit_marked_template"/>
+ <Separator/>
+ <Action name="svn_diff"/>
+ <Separator/>
+ <Action name="svn_info"/>
+ <Action name="svn_info_marked"/>
+ </Menu>
+ <Separator/>
+ <Action name="mail_file"/>
+ <Action name="mail_file_marked"/>
+ <Separaator/>
+ <Action name="package_file"/>
+ <Action name="package_file_marked"/>
+ <Separator/>
+ <Action name="dynamic_validation"/>
+ <Action name="dynamic_validation_marked"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="settings_show_navbar" append="show_merge"/>
+ <Action name="settings_show_comments" append="show_merge"/>
+ <Action name="settings_show_tools" append="show_merge"/>
+ </Menu>
+ <Menu name="help"><text>&amp;Help</text>
+ <Action name="help_gettext"/>
+ <Action name="dict_about" append="about_merge"/>
+ </Menu>
+ </MenuBar>
+ <ToolBar name="mainToolBar"><text>Main</text>
+ <Action name="reload"/>
+ <Action name="statistics"/>
+ <Action name="syntax"/>
+ <Action name="stop_search"/>
+ </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_prev_marked"/>
+ <Action name="go_next_marked"/>
+ <Separator/>
+ <Action name="go_prev_template"/>
+ <Action name="go_next_template"/>
+ <Action name="go_prev_po"/>
+ <Action name="go_next_po"/>
+ </ToolBar>
+ <Menu name="rmb_file">
+ <Action name="open"/>
+ <Action name="open_new_window"/>
+ <Action name="open_template"/>
+ <Action name="toggle_marking"/>
+ <Separator/>
+ <Action name="reload"/>
+ <Separator/>
+ <Action name="syntax"/>
+ <Action name="statistics"/>
+ <Action name="dynamic_validation"/>
+ <Action name="file_commands"/>
+ <Separator/>
+ <Menu name="rmb_file_cvs"><text>CVS</text>
+ <Action name="cvs_update"/>
+ <Action name="cvs_commit"/>
+ <Action name="cvs_status"/>
+ <Separator/>
+ <Action name="cvs_update_template"/>
+ <Action name="cvs_commit_template"/>
+ <Separator/>
+ <Action name="cvs_diff"/>
+ </Menu>
+ <Menu name="rmb_file_svn"><text>SVN</text>
+ <Action name="svn_update"/>
+ <Action name="svn_commit"/>
+ <Action name="svn_status_local"/>
+ <Action name="svn_status_remote"/>
+ <Separator/>
+ <Action name="svn_update_template"/>
+ <Action name="svn_commit_template"/>
+ <Separator/>
+ <Action name="svn_diff"/>
+ </Menu>
+ <Separator/>
+ <Action name="delete"/>
+ </Menu>
+ <Menu name="rmb_dir">
+ <Action name="toggle_marking"/>
+ <Action name="remove_marking"/>
+ <Action name="toggle_all_marking"/>
+ <Action name="remove_all_marking"/>
+ <Separator/>
+ <Action name="reload"/>
+ <Separator/>
+ <Action name="syntax"/>
+ <Action name="statistics"/>
+ <Action name="dynamic_validation"/>
+ <Action name="dir_commands"/>
+ <Separator/>
+ <Menu name="rmb_dir_cvs"><text>CVS</text>
+ <Action name="cvs_update"/>
+ <Action name="cvs_commit"/>
+ <Action name="cvs_status"/>
+ <Separator/>
+ <Action name="cvs_update_template"/>
+ <Action name="cvs_commit_template"/>
+ <Separator/>
+ <Action name="cvs_diff"/>
+ </Menu>
+ <Menu name="rmb_dir_svn"><text>SVN</text>
+ <Action name="svn_update"/>
+ <Action name="svn_commit"/>
+ <Action name="svn_status_local"/>
+ <Action name="svn_status_remote"/>
+ <Separator/>
+ <Action name="svn_update_template"/>
+ <Action name="svn_commit_template"/>
+ <Separator/>
+ <Action name="svn_diff"/>
+ </Menu>
+ </Menu>
+
+<State name="treeBuilt">
+ <Enable>
+ <Action name="open"/>
+ <Action name="open_new_window"/>
+ <Action name="find_in_files"/>
+ <Action name="replace_in_files"/>
+ <Action name="reload"/>
+
+ <Action name="go_next_fuzzyUntr"/>
+ <Action name="go_prev_fuzzyUntr"/>
+ <Action name="go_next_fuzzy"/>
+ <Action name="go_prev_fuzzy"/>
+ <Action name="go_next_untrans"/>
+ <Action name="go_prev_untrans"/>
+ <Action name="go_next_error"/>
+ <Action name="go_prev_error"/>
+ <Action name="go_next_marked"/>
+ <Action name="go_prev_marked"/>
+ <Action name="go_next_template"/>
+ <Action name="go_prev_template"/>
+ <Action name="go_next_po"/>
+ <Action name="go_prev_po"/>
+ <Action name="load_marking"/>
+ <Action name="save_marking"/>
+ <Action name="toggle_marking"/>
+ <Action name="toggle_all_marking"/>
+ <Action name="statistics"/>
+ <Action name="rough_translation"/>
+ <Action name="reload"/>
+ <Action name="dynamic_validation"/>
+ <Action name="dynamic_validation_marked"/>
+ <Action name="mail_file"/>
+ <Action name="mark_pattern"/>
+ <Action name="unmark_pattern"/>
+ </Enable>
+</State>
+
+</kpartgui>
diff --git a/kbabel/catalogmanager/catalogmanagerview.cpp b/kbabel/catalogmanager/catalogmanagerview.cpp
new file mode 100644
index 00000000..6bb4c88f
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanagerview.cpp
@@ -0,0 +1,3132 @@
+/* ****************************************************************************
+ 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>
+ Copyright (C) 2005, 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 "catmanresource.h"
+#include "catalogmanager.h"
+#include "catmanlistitem.h"
+#include "catalog.h"
+#include "kbabeldictbox.h"
+
+#include "resources.h"
+#include "multiroughtransdlg.h"
+#include "msgfmt.h"
+#include "kbmailer.h"
+#include "validateprogress.h"
+#include "cvshandler.h"
+#include "svnhandler.h"
+#include "markpatterndialog.h"
+#include "validationoptions.h"
+
+#include <qcheckbox.h>
+#include <qpopupmenu.h>
+#include <qlabel.h>
+#include <qpainter.h>
+
+#include <kcmenumngr.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kconfig.h>
+#include <kdatatool.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <kfiledialog.h>
+#include <kio/netaccess.h>
+#include <kprogress.h>
+#include <kwin.h>
+#include <kdeversion.h>
+#include <ktempfile.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qtimer.h>
+#include <qbitmap.h>
+#include <qwhatsthis.h>
+#include <qheader.h>
+#include <qdragobject.h>
+#include <qlayout.h>
+#include <qtextedit.h>
+
+using namespace KBabel;
+
+const char* columnNames[] = {
+ I18N_NOOP("Name"),
+ I18N_NOOP("M"),
+ I18N_NOOP("Fuzzy"),
+ I18N_NOOP("Untranslated"),
+ I18N_NOOP("Total"),
+ I18N_NOOP("CVS/SVN Status"),
+ I18N_NOOP("Last Revision"),
+ I18N_NOOP("Last Translator")
+};
+
+#define COLTEXT(a) (i18n(columnNames[a]))
+
+CatalogManagerView::CatalogManagerView(KBabel::Project::Ptr project, QWidget* parent,const char* name)
+ : QListView(parent,name)
+ , _dirWatch(0)
+ , _readInfoCount(0)
+ , _active(false)
+ , _stop(false)
+ , _stopSearch(false)
+ , _updateNesting(0)
+ , _logView(0)
+ , _logWindow(0)
+ , m_validPOCVSRepository( false )
+ , m_validPOTCVSRepository( false )
+ , m_validPOSVNRepository( false )
+ , m_validPOTSVNRepository( false )
+ , markPatternDialog(0)
+ , _validateDialog(0)
+ , _validateOptions(0)
+ , _validateOptionsDlg(0)
+ , _markAsFuzzy(false)
+ , _ignoreFuzzy(false)
+ , _project(project)
+{
+ _dirList.resize(200);
+ _fileList.resize(500);
+ _readInfoFileList.clear();
+
+ _pendingProcesses.setAutoDelete(true);
+
+ setSelectionMode(Single);
+
+ _dictBox = new KBabelDictBox(this, "dictbox");
+ _dictBox->hide();
+
+ _updateTimer = new QTimer(this);
+ connect(_updateTimer,SIGNAL(timeout()),this,SLOT(checkUpdate()));
+
+ addColumn(COLTEXT(COL_NAME));
+ addColumn(COLTEXT(COL_MARKER),25);
+ setColumnAlignment(1,AlignCenter);
+ addColumn(COLTEXT(COL_FUZZY));
+ setColumnAlignment(1,AlignCenter);
+ addColumn(COLTEXT(COL_UNTRANS));
+ setColumnAlignment(2,AlignCenter);
+ addColumn(COLTEXT(COL_TOTAL));
+ setColumnAlignment(3,AlignCenter);
+ addColumn(QString::null); // CVS/SVN column, header is set later
+ addColumn(COLTEXT(COL_REVISION));
+ addColumn(COLTEXT(COL_TRANSLATOR));
+
+
+ header()->setMovingEnabled(false);
+ setAllColumnsShowFocus(true);
+ setSorting(0);
+
+ if(KContextMenuManager::showOnButtonPress())
+ {
+ connect(this,SIGNAL(rightButtonPressed(QListViewItem*,const QPoint &, int))
+ ,this, SLOT(showContentsMenu(QListViewItem*,const QPoint &, int)));
+ }
+ else
+ {
+ connect(this,SIGNAL(rightButtonClicked(QListViewItem*,const QPoint &, int))
+ ,this, SLOT(showContentsMenu(QListViewItem*,const QPoint &, int)));
+ }
+ connect(this, SIGNAL(returnPressed(QListViewItem*))
+ ,this, SLOT(activateItem(QListViewItem*)));
+ connect(this, SIGNAL(doubleClicked(QListViewItem*))
+ ,this, SLOT(activateItem(QListViewItem*)));
+ connect(this,SIGNAL(selectionChanged()),this,SLOT(checkSelected()));
+ connect( this, SIGNAL( clicked(QListViewItem *, const QPoint &, int)),
+ this, SLOT( columnClicked(QListViewItem *, const QPoint &, int)));
+
+ _dirCommandsMenu = 0;
+ _fileCommandsMenu = 0;
+ _dirContentsMenu = 0;
+ _fileContentsMenu = 0;
+
+ _logWindow = new KDialogBase(0,"log window",false,i18n("Log Window")
+ ,KDialogBase::Close | KDialogBase::User1,KDialogBase::Close);
+ _logWindow->setButtonText(KDialogBase::User1,i18n("C&lear"));
+ _logWindow->setInitialSize(QSize(300,200));
+
+ QWhatsThis::add(_logWindow,i18n("<qt><p><b>Log window</b></p>\n"
+ "<p>In this window the output of "
+ "the executed commands are shown.</p></qt>"));
+
+ _logView = new QTextEdit(_logWindow);
+ _logView->setReadOnly(true);
+
+ _logWindow->setMainWidget(_logView);
+
+ connect(_logWindow,SIGNAL(user1Clicked()),_logView,SLOT(clear()));
+
+ QWhatsThis::add(this,i18n("<qt><p><b>Catalog Manager</b></p>\n"
+"<p>The Catalog Manager merges two folders into one tree and displays all\n"
+"PO and POT files in these folders. This way you can easily see if a\n"
+"template has been added or removed. Also some information about the files\n"
+"is displayed.</p>"
+"<p>For more information see section <b>The Catalog Manager</b>"
+" in the online help.</p></qt>"));
+
+ setAcceptDrops(true); // just to get the drag displayed immediately
+
+ mailer = new KBabelMailer( this, _project );
+
+ // CVS
+ cvshandler = new CVSHandler( );
+ connect( cvshandler, SIGNAL( signalIsPORepository( bool ) ),
+ this, SLOT( slotValidPOCVSRepository( bool ) ) );
+ connect( cvshandler, SIGNAL( signalIsPOTRepository( bool ) ),
+ this, SLOT( slotValidPOTCVSRepository( bool ) ) );
+ connect( cvshandler, SIGNAL( signalFilesCommitted( const QStringList& ) ),
+ this, SLOT( updateFiles( const QStringList& ) ) );
+
+ // SVN
+ svnhandler = new SVNHandler( );
+ connect( svnhandler, SIGNAL( signalIsPORepository( bool ) ),
+ this, SLOT( slotValidPOSVNRepository( bool ) ) );
+ connect( svnhandler, SIGNAL( signalIsPOTRepository( bool ) ),
+ this, SLOT( slotValidPOTSVNRepository( bool ) ) );
+ connect( svnhandler, SIGNAL( signalFilesCommitted( const QStringList& ) ),
+ this, SLOT( updateFiles( const QStringList& ) ) );
+
+ KConfig *config = KGlobal::config();
+ restoreView(config);
+
+ _dictBox->readSettings(_project->config());
+}
+
+CatalogManagerView::~CatalogManagerView()
+{
+ if(_active)
+ stop();
+
+ if(_dirWatch)
+ delete _dirWatch;
+
+ if(_settings.killCmdOnExit)
+ {
+ KProcess* proc;
+ for ( proc=_pendingProcesses.first(); proc != 0; proc=_pendingProcesses.next() )
+ {
+ proc->kill(SIGKILL);
+ }
+ }
+
+ delete _logWindow;
+ delete mailer;
+ delete cvshandler;
+ delete svnhandler;
+ if (markPatternDialog) delete markPatternDialog;
+}
+
+
+void CatalogManagerView::saveView( KConfig *config) const
+{
+ saveMarker(config);
+
+ KConfigGroupSaver( config, "CatalogManager" );
+
+ config->writeEntry( "ValidateMarkAsFuzzy", _markAsFuzzy );
+ config->writeEntry( "ValidateIgnoreFuzzy", _ignoreFuzzy );
+}
+
+
+void CatalogManagerView::restoreView( KConfig *config)
+{
+ readMarker(config);
+
+ _markAsFuzzy = config->readBoolEntry( "ValidateMarkAsFuzzy", false );
+ _ignoreFuzzy = config->readBoolEntry( "ValidateIgnoreFuzzy", false );
+}
+
+void CatalogManagerView::setRMBMenuFile( QPopupMenu *m )
+{
+ _fileContentsMenu = m;
+}
+
+void CatalogManagerView::setRMBMenuDir( QPopupMenu *m )
+{
+ _dirContentsMenu = m;
+}
+
+void CatalogManagerView::setDirCommandsMenu( QPopupMenu *m )
+{
+ _dirCommandsMenu = m;
+ connect(_dirCommandsMenu,SIGNAL(activated(int)),this,SLOT(slotDirCommand(int)));
+}
+
+void CatalogManagerView::setFileCommandsMenu( QPopupMenu *m )
+{
+ _fileCommandsMenu = m;
+ connect(_fileCommandsMenu,SIGNAL(activated(int)),this,SLOT(slotFileCommand(int)));
+}
+
+void CatalogManagerView::checkUpdate()
+{
+ _updateNesting++;
+ pause(true);
+
+ QDictIterator<CatManListItem> it( _fileList ); // iterator for dict
+
+ while ( it.current() && !_stop)
+ {
+ CatManListItem* item=it.current();
+
+ item->checkUpdate();
+ ++it;
+ }
+
+ pause(false);
+ --_updateNesting;
+ if( _updateNesting == 0 )
+ {
+ emit updateFinished();
+ }
+}
+
+
+
+void CatalogManagerView::pause(bool flag)
+{
+ if(flag)
+ {
+ _updateTimer->stop();
+ }
+ else
+ {
+ _updateTimer->start(10000);
+ }
+}
+
+
+void CatalogManagerView::stop(bool s)
+{
+ kdDebug(KBABEL_CATMAN) << "Stopping " << s << endl;
+ pause(s);
+ _stop=s;
+ PoInfo::stopStaticRead = true;
+}
+
+void CatalogManagerView::stopSearch()
+{
+ _stopSearch = true;
+}
+
+void CatalogManagerView::clear()
+{
+ pause(true);
+
+ // first clear up
+ if(_dirWatch)
+ delete _dirWatch;
+
+ _dirWatch= new KDirWatch();
+ connect(_dirWatch,SIGNAL(deleted(const QString&)),this
+ ,SLOT(directoryDeleted(const QString&)));
+ connect(_dirWatch,SIGNAL(dirty(const QString&)),this
+ ,SLOT(directoryChanged(const QString&)));
+ connect(_dirWatch,SIGNAL(created(const QString&)),this
+ ,SLOT(directoryChanged(const QString&)));
+
+ _dirList.clear();
+ _fileList.clear();
+
+ QListView::clear();
+}
+
+void CatalogManagerView::toggleAllMarks()
+{
+ _markerList.clear();
+
+ QListViewItemIterator it( this );
+ CatManListItem* item;
+
+ for ( ; it.current(); ++it )
+ {
+ item = (CatManListItem*) it.current();
+ if(item->isFile())
+ {
+ bool wasMarked=item->marked();
+ item->setMarked(!wasMarked);
+ if(!wasMarked)
+ {
+ _markerList.append(item->package());
+ }
+ else
+ {
+ _markerList.remove(item->package());
+ }
+ }
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::clearAllMarks()
+{
+ _markerList.clear();
+ QDictIterator<CatManListItem> it( _fileList ); // iterator for dict
+
+ while ( it.current() )
+ {
+ CatManListItem* item=it.current();
+
+ if(item->marked())
+ _markerList.remove(item->package());
+
+ item->setMarked(false);
+ ++it;
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::markModifiedFiles()
+{
+ QDictIterator<CatManListItem> it( _fileList );
+ while ( it.current() )
+ {
+ CatManListItem* item=it.current();
+ /*if(item->marked())
+ _markerList.remove(item->package());
+ */
+ if(item->isModified() && ! item->marked() ) {
+ item->setMarked(true);
+ _markerList.append(item->package( ));
+ }
+ ++it;
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::loadMarks()
+{
+ const KURL url = KFileDialog::getOpenURL( QString(),"*.marklist", this );
+ if( url.isEmpty() ) return;
+
+ QString filename;
+#if KDE_IS_VERSION( 3, 2, 90 )
+ if (!KIO::NetAccess::download( url, filename, this ) )
+#else
+ if( !KIO::NetAccess::download( url, filename ) )
+#endif
+ {
+ KMessageBox::error(this,i18n(
+ "Error while trying to open file:\n %1").arg(url.prettyURL()));
+ return;
+ }
+
+ // now load from file
+ QStringList newMarkerList; // better create new list in case of problems
+ QFile f( filename );
+ if( f.open( IO_ReadOnly) )
+ {
+ QTextStream s(&f);
+
+ QString input;
+
+ s >> input ;
+ if( input == "[Markers]" )
+ {
+ while( !s.atEnd() )
+ {
+ s >> input;
+ newMarkerList.append(input);
+ }
+ }
+ else
+ {
+ KMessageBox::error(this
+ ,i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid file with list of markings.").arg(url.prettyURL()));
+ f.close();
+ return;
+ }
+ f.close();
+ }
+ else
+ {
+ KMessageBox::error(this,i18n(
+ "Error while trying to open file:\n %1").arg(url.prettyURL()));
+ }
+
+ KIO::NetAccess::removeTempFile( filename );
+
+ // test validity of list items
+ QStringList testedList;
+ QStringList::const_iterator it;
+ for( it=newMarkerList.constBegin() ; it!=newMarkerList.constEnd() ; ++it )
+ if( _fileList[(*it)] != 0 ) testedList.append( (*it) );
+
+ // apply new list
+ for( it=_markerList.constBegin() ; it!=_markerList.constEnd() ; ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+ if( item ) item->setMarked(false);
+ }
+
+ _markerList = testedList;
+ for( it=_markerList.constBegin() ; it!=_markerList.constEnd() ; ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+ if( item ) item->setMarked(true);
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::saveMarks()
+{
+ const KURL url2 = KFileDialog::getSaveURL( QString(), "*.marklist", this );
+ if( url2.isEmpty() ) return;
+
+ // ### FIXME: why is the file dialog not doing this?
+ if ( KIO::NetAccess::exists( url2, false, this ) )
+ {
+ if(KMessageBox::warningContinueCancel(this,QString("<qt>%1</qt>").arg(i18n("The file %1 already exists. "
+ "Do you want to overwrite it?").arg(url2.prettyURL())),i18n("Warning"),i18n("&Overwrite"))==KMessageBox::Cancel)
+ {
+ return;
+ }
+ }
+
+#if KDE_IS_VERSION( 3, 4, 92 )
+ // Support for partially remote KIO slave like media:
+ const KURL url ( KIO::NetAccess::mostLocalURL( url2, this ) );
+#else
+ const KURL url ( url2 );
+#endif
+ kdDebug() << "Saving marks: " << url2.prettyURL() << " most-local: " << url.prettyURL() << endl;
+
+ QFile* file = 0;
+ KTempFile* tempFile = 0;
+ QTextStream* stream = 0;
+ bool error = false;
+
+ const bool localFile = url.isLocalFile();
+ if ( localFile )
+ {
+ // We have a local file
+ file = new QFile( url.path() );
+ if ( file->open (IO_WriteOnly) )
+ {
+ stream = new QTextStream( file );
+ }
+ else
+ {
+ error = true;
+ }
+ }
+ else
+ {
+ tempFile = new KTempFile();
+ tempFile->setAutoDelete(true);
+ stream = tempFile->textStream();
+ error = !stream;
+ }
+ if ( !error )
+ {
+ // ### TODO: try to get a better file format for KDE4 (XML?), one working with real relative paths (no / at start) and working with UTF-8
+ *stream << "[Markers]" << endl;
+ for( QStringList::const_iterator it = _markerList.constBegin(); it!=_markerList.constEnd() ; ++it )
+ *stream << (*it) << endl;
+ }
+ if ( error )
+ {
+ // ### KDE4 FIXME: strip the final \n of the message
+ KMessageBox::error( this,
+ i18n( "An error occurred while trying to write to file:\n%1\n" ).arg( url.prettyURL()) );
+ }
+ else if ( !localFile )
+ {
+ tempFile->close();
+ if( !KIO::NetAccess::upload( tempFile->name(), url, this ) )
+ {
+ // ### KDE4 FIXME: strip the final \n of the message
+ KMessageBox::error(this,
+ i18n("An error occurred while trying to upload the file:\n%1\n").arg(url.prettyURL()));
+ }
+ }
+
+ // We have finished so clean up
+ if ( localFile )
+ {
+ delete stream;
+ file->close();
+ delete file;
+ }
+ else
+ {
+ delete tempFile;
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::slotMarkPattern( )
+{
+ setPatternMarks(true);
+}
+
+void CatalogManagerView::slotUnmarkPattern( )
+{
+ setPatternMarks(false);
+}
+
+void CatalogManagerView::setPatternMarks(bool mark)
+{
+ CatManListItem * item = (CatManListItem*)currentItem( );
+ if (!item)
+ item = (CatManListItem*)_dirList["/"];
+ if (!item->isDir( ))
+ return;
+
+ if (!markPatternDialog)
+ markPatternDialog = new MarkPatternDialog(this);
+
+ markPatternDialog->setMode(mark);
+
+ if (markPatternDialog->exec( ) != KDialog::Accepted)
+ return;
+
+ QRegExp rx(markPatternDialog->pattern( ));
+ rx.setWildcard(!markPatternDialog->useRegExp( ));
+ rx.setCaseSensitive(markPatternDialog->isCaseSensitive( ));
+
+ QStringList fileList = item->allChildrenList(true);
+ for (QStringList::const_iterator it = fileList.constBegin( ); it != fileList.constEnd( ); ++it) {
+ CatManListItem * i = _fileList[*it];
+
+ QString matchName;
+ if (i->hasPo( ))
+ matchName = i->poFile( );
+ else if (i->hasPot( ) && markPatternDialog->includeTemplates( ))
+ matchName = i->potFile( );
+ matchName = QFileInfo(matchName).baseName( );
+
+ if (mark) {
+ if (!matchName.isEmpty( ) && rx.exactMatch(matchName) && !i->marked( )) {
+ i->setMarked(true);
+ _markerList.append(i->package( ));
+ }
+ } else {
+ if (!matchName.isEmpty( ) && rx.exactMatch(matchName) && i->marked( )) {
+ i->setMarked(false);
+ _markerList.remove(i->package( ));
+ }
+ }
+ }
+}
+
+void CatalogManagerView::statistics()
+{
+ CatManListItem* i=(CatManListItem*) currentItem();
+
+ if(!i)
+ i=(CatManListItem*)_dirList["/"];
+
+ if(isActive() && i->isDir())
+ {
+ if(KMessageBox::warningContinueCancel(this
+ ,i18n("The Catalog Manager is still updating information about the files.\n"
+"If you continue, it will try to update all necessary files, however this can take "
+"a long time and may lead to wrong results. Please wait until all files are updated."),i18n("Warning")
+ ,KStdGuiItem::cont()) == KMessageBox::Cancel)
+ {
+ return;
+ }
+ }
+
+ QStringList doList;
+
+ if( i->isFile() ) doList.append(i->package());
+ else doList = i->allChildrenList(true);
+
+ showStatistics( i, doList );
+}
+
+void CatalogManagerView::markedStatistics()
+{
+ CatManListItem* i=(CatManListItem*) currentItem();
+
+ if(!i)
+ i=(CatManListItem*)_dirList["/"];
+
+ if(isActive() && i->isDir())
+ {
+ if(KMessageBox::warningContinueCancel(this
+ ,i18n("The Catalog Manager is still updating information about the files.\n"
+"If you continue, it will try to update all necessary files, however this can take "
+"a long time and may lead to wrong results. Please wait until all files are updated."),i18n("Warning")
+ ,KStdGuiItem::cont()) == KMessageBox::Cancel)
+ {
+ return;
+ }
+ }
+
+ QStringList doList;
+
+ if( i->isFile() ) doList.append(i->package());
+ else doList = i->allChildrenList(true);
+
+ QStringList markedDoList;
+ QStringList::const_iterator it;
+ for( it = doList.constBegin(); it != doList.constEnd(); ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+ if( item->marked() ) markedDoList.append(item->package());
+ }
+
+ showStatistics( i, markedDoList );
+}
+
+void CatalogManagerView::showStatistics( CatManListItem *i, QStringList &childrenList )
+{
+ KLocale *locale = KGlobal::locale();
+
+ QString msg;
+ int totalPackages=0;
+ int totalPo=0;
+ int totalNoPot=0;
+ int needworkPo=0;
+ int totalMsgid=0;
+ int totalFuzzy=0;
+ int totalUntranslated=0;
+
+ QStringList::const_iterator it;
+ for( it = childrenList.constBegin(); it != childrenList.constEnd(); ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+
+ /*
+ KASSERT1(item,KDEBUG_FATAL,KBABEL_CATMAN,"CatalogManagerView::statistics: item not in list %s"
+ ,(*it).ascii());
+ */
+ // be sure, that the information is updated
+ _updateNesting++;
+ item->checkUpdate();
+ _updateNesting--;
+ if( _stop ) return;
+
+ totalPackages++;
+
+ int fuzzy=item->fuzzy();
+ int total=item->total();
+ int untrans=item->untranslated();
+
+ if(item->hasPo())
+ totalPo++;
+
+ if(!item->hasPot())
+ totalNoPot++;
+
+
+ if(fuzzy || untrans)
+ needworkPo++;
+
+ totalMsgid+=total;
+ totalFuzzy+=fuzzy;
+ totalUntranslated+=untrans;
+ }
+
+ double percent;
+
+ const QString name=i->package(false);
+ if(name.isEmpty())
+ msg = i18n("Statistics for all:\n");
+ else
+ msg = i18n("Statistics for %1:\n").arg(name);
+
+ msg+=i18n("Number of packages: %1\n").arg(locale->formatNumber(totalPackages, 0));
+
+ percent=100.0-((double)needworkPo*100.0)/totalPackages;
+ msg+=i18n("Complete translated: %1 % (%2)\n").arg(locale->formatNumber(percent,2)).arg(locale->formatNumber(totalPackages-needworkPo, 0));
+
+ percent=100.0-((double)totalPo*100.0)/totalPackages;
+ msg+=i18n("Only template available: %1 % (%2)\n").arg(locale->formatNumber(percent,2)).arg(locale->formatNumber(totalPackages-totalPo,0));
+ percent=((double)totalNoPot*100.0)/totalPackages;
+ msg+=i18n("Only PO file available: %1 % (%2)\n").arg(locale->formatNumber(percent,02)).arg(locale->formatNumber(totalNoPot, 0));
+
+ msg+=i18n("Number of messages: %1\n").arg(locale->formatNumber(totalMsgid, 0));
+
+ long int totalTranslated = totalMsgid - totalFuzzy - totalUntranslated;
+ percent=((double)totalTranslated*100.0)/totalMsgid;
+ msg+=i18n("Translated: %1 % (%2)\n").arg(locale->formatNumber(percent,2)).arg(locale->formatNumber(totalTranslated, 0));
+
+ percent=((double)totalFuzzy*100.0)/totalMsgid;
+ msg+=i18n("Fuzzy: %1 % (%2)\n").arg(locale->formatNumber(percent,2)).arg(locale->formatNumber(totalFuzzy, 0));
+
+ percent=((double)totalUntranslated*100.0)/totalMsgid;
+ msg+=i18n("Untranslated: %1 % (%2)\n").arg(locale->formatNumber(percent,2)).arg(locale->formatNumber(totalUntranslated, 0));
+
+ KMessageBox::information(this,msg,i18n("Statistics"));
+}
+
+void CatalogManagerView::checkSyntax()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(!item)
+ item=(CatManListItem*) _dirList["/"];
+
+ if(item->isFile())
+ {
+ if(!item->hasPo())
+ return;
+
+ Msgfmt::Status status;
+ QString output;
+ Msgfmt msgfmt;
+
+ status=msgfmt.checkSyntax(item->poFile(),output);
+
+ switch(status)
+ {
+ case Msgfmt::Ok:
+ {
+ KMessageBox::information(this,i18n("The file is syntactically correct.\nOutput of \"msgfmt --statistics\":")+"\n"+output);
+ break;
+ }
+ case Msgfmt::SyntaxError:
+ {
+ KMessageBox::information(this,i18n("The file has syntax errors.\nOutput of \"msgfmt --statistics\":")+"\n"+output);
+ break;
+ }
+ case Msgfmt::HeaderError:
+ {
+ KMessageBox::information(this,i18n("The file has header syntax error.\nOutput of \"msgfmt --statistics\":")+"\n"+output);
+ break;
+ }
+ case Msgfmt::Error:
+ {
+ KMessageBox::error(this,i18n("An error occurred while processing \"msgfmt --statistics\""));
+ break;
+ }
+ case Msgfmt::NoExecutable:
+ {
+ KMessageBox::sorry(this,i18n("Cannot execute msgfmt. Please make sure that you have msgfmt in your PATH."));
+ break;
+ }
+ case Msgfmt::Unsupported:
+ {
+ KMessageBox::sorry(this,i18n("You can use gettext tools only for checking PO files."));
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ Msgfmt::Status status;
+ QString output;
+ Msgfmt msgfmt;
+
+ status=msgfmt.checkSyntaxInDir(item->poFile(), "*.po", output);
+
+ QString name=item->package(false);
+
+ switch(status)
+ {
+ case Msgfmt::Ok:
+ {
+ QString msg;
+ if(!name.isEmpty())
+ {
+ msg=i18n("All files in folder %1 are syntactically correct.\n"
+"Output of \"msgfmt --statistics\":\n").arg(name)+output;
+ }
+ else
+ {
+ msg=i18n("All files in the base folder are syntactically correct.\n"
+"Output of \"msgfmt --statistics\":\n")+output;
+ }
+ KMessageBox::information(this,msg);
+ break;
+ }
+ case Msgfmt::SyntaxError:
+ {
+ QString msg;
+ if(!name.isEmpty())
+ {
+ msg=i18n("At least one file in folder %1 has syntax errors.\n"
+"Output of \"msgfmt --statistics\":\n").arg(name)+output;
+ }
+ else
+ {
+ msg=i18n("At least one file in the base folder has syntax errors.\n"
+"Output of \"msgfmt --statistics\":\n")+output;
+ }
+ KMessageBox::information(this,msg);
+ break;
+ }
+ case Msgfmt::HeaderError:
+ {
+ QString msg;
+ if(!name.isEmpty())
+ {
+ msg=i18n("At least one file in folder %1 has header syntax errors.\n"
+"Output of \"msgfmt --statistics\":\n").arg(name)+output;
+ }
+ else
+ {
+ msg=i18n("At least one file in the base folder has header syntax errors.\n"
+"Output of \"msgfmt --statistics\":\n")+output;
+ }
+ KMessageBox::information(this,msg);
+ break;
+ }
+ case Msgfmt::Error:
+ {
+ QString msg;
+ if(!name.isEmpty())
+ {
+ msg=i18n("An error occurred while processing \"msgfmt --statistics *.po\" "
+"in folder %1").arg(name);
+ }
+ else
+ {
+ msg=i18n("An error occurred while processing \"msgfmt --statistics *.po\" "
+"in the base folder");
+ }
+ KMessageBox::error(this,msg);
+ break;
+ }
+ case Msgfmt::NoExecutable:
+ {
+ KMessageBox::sorry(this,i18n("Cannot execute msgfmt. Please make sure that you have msgfmt in your PATH."));
+ break;
+ }
+ case Msgfmt::Unsupported:
+ {
+ KMessageBox::sorry(this,i18n("You can use gettext tools only for checking PO files."));
+ break;
+ }
+ }
+ }
+}
+
+void CatalogManagerView::roughTranslation()
+{
+ QPtrList<CatManListItem> result;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ if( current->isDir() )
+ {
+ QStringList s = current->allChildrenList(true);
+ QStringList::const_iterator it;
+ for( it = s.constBegin() ; it != s.constEnd(); ++it )
+ {
+ CatManListItem *item = _fileList[(*it)];
+ if( item ) result.append( item );
+ }
+ }
+ else
+ {
+ result.append( current );
+ }
+
+ MultiRoughTransDlg* dialog=new MultiRoughTransDlg( _dictBox, result, this );
+ dialog->exec();
+ delete dialog;
+}
+
+void CatalogManagerView::markedRoughTranslation()
+{
+ if( _markerList.count() == 0 ) return;
+
+ QPtrList<CatManListItem> result;
+
+ QStringList::const_iterator it;
+ for( it = _markerList.constBegin() ; it != _markerList.constEnd(); ++it )
+ {
+ CatManListItem *item = _fileList[(*it)];
+ result.append( item );
+ }
+
+ MultiRoughTransDlg* dialog=new MultiRoughTransDlg( _dictBox, result, this );
+ dialog->exec();
+ delete dialog;
+}
+
+void CatalogManagerView::mailFiles()
+{
+ CatManListItem* item = (CatManListItem*)currentItem();
+ if(item->isDir()) {
+ QStringList filesToSend;
+ QStringList childrenList = item->allChildrenList(true);
+
+ QStringList::const_iterator it;
+ for (it = childrenList.constBegin(); it != childrenList.constEnd(); ++it) {
+ CatManListItem* i = _fileList[(*it)];
+ if (i->hasPo()) {
+ filesToSend << i->poFile();
+ }
+ }
+ mailer->sendFiles(filesToSend, item->text(0));
+ } else {
+ if (item->hasPo()) {
+ mailer->sendOneFile(item->poFile());
+ }
+ }
+}
+
+void CatalogManagerView::mailMarkedFiles()
+{
+ if (_markerList.count() == 0)
+ return;
+
+ QStringList filesToSend;
+ QStringList::const_iterator it;
+ for (it = _markerList.constBegin(); it != _markerList.constEnd(); ++it) {
+ CatManListItem* i = _fileList[(*it)];
+ if (i->hasPo()) {
+ filesToSend << i->poFile();
+ }
+ }
+ mailer->sendFiles(filesToSend);
+}
+
+void CatalogManagerView::packageFiles( )
+{
+ CatManListItem* item = (CatManListItem*)currentItem();
+ if(item->isDir()) {
+ QStringList filesToPackage;
+ QStringList childrenList = item->allChildrenList(true);
+
+ QStringList::const_iterator it;
+ for (it = childrenList.constBegin(); it != childrenList.constEnd(); ++it) {
+ CatManListItem* i = _fileList[(*it)];
+ if (i->hasPo()) {
+ filesToPackage << i->poFile();
+ }
+ }
+ QString packageFileName = KFileDialog::getSaveFileName(QString::null,"*.tar.bz2\n*.tar.gz",this);
+ mailer->buildArchive( filesToPackage, packageFileName, QString::null, false );
+ }
+ else {
+ if (item->hasPo()) {
+ QStringList fileToPackage(item->poFile());
+ QString packageFileName = KFileDialog::getSaveFileName(QString::null,"*.tar.bz2\n*.tar.gz",this);
+ mailer->buildArchive( fileToPackage, packageFileName, QString::null, false );
+ }
+ }
+}
+void CatalogManagerView::packageMarkedFiles( )
+{
+ if (_markerList.count() == 0)
+ return;
+
+ QStringList filesToPackage;
+ QStringList::const_iterator it;
+ for (it = _markerList.constBegin(); it != _markerList.constEnd(); ++it) {
+ CatManListItem* i = _fileList[(*it)];
+ if (i->hasPo()) {
+ filesToPackage << i->poFile();
+ }
+ }
+
+ QString packageFileName = KFileDialog::getSaveFileName(QString::null,"*.tar.bz2\n*.tar.gz",this);
+ mailer->buildArchive( filesToPackage, packageFileName, QString::null, false );
+}
+
+// CVS
+void CatalogManagerView::cvsUpdate( )
+{
+ doCVSCommand( CVS::Update );
+}
+
+void CatalogManagerView::cvsUpdateMarked( )
+{
+ doCVSCommand( CVS::Update, true );
+}
+
+void CatalogManagerView::cvsCommit( )
+{
+ doCVSCommand( CVS::Commit );
+}
+
+void CatalogManagerView::cvsCommitMarked( )
+{
+ doCVSCommand( CVS::Commit, true );
+}
+
+void CatalogManagerView::cvsStatus( )
+{
+ doCVSCommand( CVS::Status );
+}
+
+void CatalogManagerView::cvsStatusMarked( )
+{
+ doCVSCommand( CVS::Status, true );
+}
+
+void CatalogManagerView::cvsUpdateTemplate( )
+{
+ doCVSCommand( CVS::Update, false, true );
+}
+
+void CatalogManagerView::cvsUpdateMarkedTemplate( )
+{
+ doCVSCommand( CVS::Update, true, true );
+}
+
+void CatalogManagerView::cvsCommitTemplate( )
+{
+ doCVSCommand( CVS::Commit, false, true );
+}
+
+void CatalogManagerView::cvsCommitMarkedTemplate( )
+{
+ doCVSCommand( CVS::Commit, true, true );
+}
+
+void CatalogManagerView::cvsDiff( )
+{
+ doCVSCommand( CVS::Diff, false, false );
+}
+
+void CatalogManagerView::doCVSCommand( CVS::Command cmd, bool marked, bool templates )
+{
+ KSharedConfig* config = _project->sharedConfig();
+ if ( marked ) {
+ if ( _markerList.isEmpty() ) return;
+ QStringList fileList;
+ QStringList::const_iterator it;
+ for ( it = _markerList.constBegin( ); it != _markerList.constEnd( ); ++it ) {
+ CatManListItem * i = _fileList[(*it)];
+ if ( templates && i->hasPot( ) )
+ fileList << i->potFile( );
+ else if ( !templates && i->hasPo( ) )
+ fileList << i->poFile( );
+ }
+ cvshandler->execCVSCommand( this, cmd, fileList, templates, config );
+ } else {
+ const QString basedir = ( templates ? _settings.potBaseDir : _settings.poBaseDir );
+ QString cvsItem;
+ CatManListItem * item = (CatManListItem*)currentItem( );
+ if ( ( cmd == CVS::Commit || cmd == CVS::Diff ) && item->isDir( ) ) {
+ // all children including directories
+ QStringList cvsItems = item->allChildrenFileList (true, false, true);
+ if ( !cvsItems.isEmpty( ) )
+ cvshandler->execCVSCommand( this, cmd, cvsItems, templates, config );
+ } else {
+ if ( templates && item->hasPot( ) )
+ cvsItem = item->potFile( );
+ else if ( !templates && item->hasPo( ) )
+ cvsItem = item->poFile( );
+
+ if ( !cvsItem.isEmpty( ) )
+ cvshandler->execCVSCommand( this, cmd, cvsItem, templates, config );
+ }
+ }
+}
+
+//SVN
+void CatalogManagerView::svnUpdate( )
+{
+ doSVNCommand( SVN::Update );
+}
+
+void CatalogManagerView::svnUpdateMarked( )
+{
+ doSVNCommand( SVN::Update, true );
+}
+
+void CatalogManagerView::svnCommit( )
+{
+ doSVNCommand( SVN::Commit );
+}
+
+void CatalogManagerView::svnCommitMarked( )
+{
+ doSVNCommand( SVN::Commit, true );
+}
+
+void CatalogManagerView::svnStatusRemote( )
+{
+ doSVNCommand( SVN::StatusRemote );
+}
+
+void CatalogManagerView::svnStatusRemoteMarked( )
+{
+ doSVNCommand( SVN::StatusRemote, true );
+}
+
+void CatalogManagerView::svnStatusLocal( )
+{
+ doSVNCommand( SVN::StatusLocal );
+}
+
+void CatalogManagerView::svnStatusLocalMarked( )
+{
+ doSVNCommand( SVN::StatusLocal, true );
+}
+
+void CatalogManagerView::svnInfo()
+{
+ doSVNCommand( SVN::Info );
+}
+
+void CatalogManagerView::svnInfoMarked()
+{
+ doSVNCommand( SVN::Info, true );
+}
+
+void CatalogManagerView::svnUpdateTemplate( )
+{
+ doSVNCommand( SVN::Update, false, true );
+}
+
+void CatalogManagerView::svnUpdateMarkedTemplate( )
+{
+ doSVNCommand( SVN::Update, true, true );
+}
+
+void CatalogManagerView::svnCommitTemplate( )
+{
+ doSVNCommand( SVN::Commit, false, true );
+}
+
+void CatalogManagerView::svnCommitMarkedTemplate( )
+{
+ doSVNCommand( SVN::Commit, true, true );
+}
+
+void CatalogManagerView::svnDiff( )
+{
+ doSVNCommand( SVN::Diff, false, false );
+}
+
+void CatalogManagerView::doSVNCommand( SVN::Command cmd, bool marked, bool templates )
+{
+ KSharedConfig* config = _project->sharedConfig();
+ if ( marked ) {
+ if ( _markerList.isEmpty() ) return;
+ QStringList fileList;
+ QStringList::const_iterator it;
+ for ( it = _markerList.constBegin( ); it != _markerList.constEnd( ); ++it ) {
+ CatManListItem * i = _fileList[(*it)];
+ if ( templates && i->hasPot( ) )
+ fileList << i->potFile( );
+ else if ( !templates && i->hasPo( ) )
+ fileList << i->poFile( );
+ }
+ svnhandler->execSVNCommand( this, cmd, fileList, templates, config );
+ } else {
+ const QString basedir = ( templates ? _settings.potBaseDir : _settings.poBaseDir );
+ QString svnItem;
+ CatManListItem * item = (CatManListItem*)currentItem( );
+ if ( ( cmd == SVN::Commit || cmd == SVN::Diff ) && item->isDir( ) ) {
+ // all children including directories
+ QStringList svnItems = item->allChildrenFileList (true, false, true);
+ if ( !svnItems.isEmpty( ) )
+ svnhandler->execSVNCommand( this, cmd, svnItems, templates, config );
+ } else {
+ if ( templates && item->hasPot( ) )
+ svnItem = item->potFile( );
+ else if ( !templates && item->hasPo( ) )
+ svnItem = item->poFile( );
+
+ if ( !svnItem.isEmpty( ) )
+ svnhandler->execSVNCommand( this, cmd, svnItem, templates, config );
+ }
+ }
+}
+
+void CatalogManagerView::showLog()
+{
+ _logWindow->show();
+}
+
+QString CatalogManagerView::find( FindOptions &options, QStringList &rest )
+{
+ CatManListItem* i=(CatManListItem*) currentItem();
+
+ if(!i || options.inAllFiles)
+ i=(CatManListItem*)_dirList["/"];
+
+ QValueList<QString> foundFiles;
+ _stopSearch = false;
+
+ const QString search = options.findStr.lower().simplifyWhiteSpace();
+ QStringList searchWords = QStringList::split(' ', search);
+
+ QStringList childrenList;
+ if( i->isFile() ) childrenList.append(i->name());
+ else childrenList =i->allChildrenList(true);
+
+ emit prepareFindProgressBar(childrenList.size());
+
+ QStringList::const_iterator it;
+ for( it = childrenList.constBegin(); it != childrenList.constEnd(); ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+
+ if( !item )
+ {
+ kdWarning(KBABEL_CATMAN) << "The file information not found, skipping" << endl;
+ continue;
+ }
+
+ // skip if not marked and we lookup in marked
+ if( options.inMarkedFiles && !item->marked() )
+ {
+ kdDebug(KBABEL_CATMAN) << "Skipping due marking " << item->name() << endl;
+ emit signalSearchedFile(1);
+ continue;
+ }
+
+ bool doSearch = options.isRegExp || options.inTemplates; // for regexp and templates we do not support index search
+ if( item->wordsUpdated() )
+ doSearch = doSearch || hasMatchingWords(item->wordList(), searchWords);
+ else doSearch = true; // we do not have index, we need to search
+ if( doSearch )
+ {
+ QString itemFile;
+ if( options.inTemplates )
+ {
+ if( item->hasPot() ) itemFile=item->potFile();
+ } else {
+ if( item->hasPo() ) itemFile=item->poFile();
+ }
+
+ if( itemFile.isNull() )
+ {
+ emit signalSearchedFile(1);
+ continue;
+ }
+
+ if( PoInfo::findInFile( itemFile , options ) )
+ {
+ emit signalSearchedFile(1);
+ rest.clear();
+ if( _stopSearch )
+ {
+ // if we are stopped, return what we found and clear the rest
+ _stopSearch = false;
+ return itemFile;
+ }
+ const QString foundItemFile = itemFile;
+
+ it++;
+ while( it != childrenList.constEnd() )
+ {
+ CatManListItem *item = _fileList[(*it)];
+
+ itemFile = QString::null;
+ if( options.inTemplates )
+ {
+ if( item->hasPot() ) itemFile=item->potFile();
+ } else {
+ if( item->hasPo() )itemFile=item->poFile();
+ }
+ if( options.inMarkedFiles && !item->marked() )
+ itemFile=QString::null;
+
+ if( !itemFile.isNull())
+ {
+ if( item->wordsUpdated() && !options.inTemplates )
+ {
+ if( options.isRegExp || hasMatchingWords(item->wordList(), searchWords) )
+ {
+ rest.append( itemFile );
+ }
+ else kdDebug(KBABEL_CATMAN) << "Don't try to lookup in " << itemFile << endl;
+ } else {
+ rest.append( itemFile ); // there is no word index, add the file
+ }
+ } else emit signalSearchedFile(1);
+
+ it++;
+ }
+ return foundItemFile;
+
+ }
+ } else kdDebug(KBABEL_CATMAN) << "Skipping " << item->poFile() << endl;
+ emit signalSearchedFile(1);
+ if( _stop || _stopSearch ) {
+ _stopSearch = false;
+ rest.clear();
+ if( _updateNesting == 0 && !_stop ) emit updateFinished();
+ return QString::null;
+ }
+ }
+ return QString::null;
+}
+
+bool CatalogManagerView::hasMatchingWords( QStringList &itemWords, QStringList &searchWords)
+{
+ for( QStringList::const_iterator it1 = searchWords.constBegin() ; it1 != searchWords.constEnd() ; ++it1 )
+ for( QStringList::const_iterator it2 = itemWords.constBegin() ; it2 != itemWords.constEnd() ; ++it2 )
+ if( *it1 == *it2
+ || (*it1).contains(*it2)
+ || (*it2).contains(*it1) ) return true;
+ return false;
+}
+
+void CatalogManagerView::showContentsMenu(QListViewItem *i, const QPoint &point, int)
+{
+ CatManListItem* item = (CatManListItem*) i;
+
+ if(!item)
+ return;
+
+ if(item->isDir())
+ {
+ _dirContentsMenu->exec(point);
+ }
+ else
+ {
+ _fileContentsMenu->exec(point);
+ }
+}
+
+void CatalogManagerView::checkSelected()
+{
+ CatManListItem* item=(CatManListItem*)selectedItem();
+ if(!item) return;
+
+ const uint actionValue =
+ NEEDS_PO * item->hasPo() + NEEDS_POT * item->hasPot() +
+ NEEDS_MARK * item->marked() + NEEDS_DIR * item->isDir() +
+ NEEDS_PO_CVS * m_validPOCVSRepository + NEEDS_POT_CVS * m_validPOTCVSRepository +
+ NEEDS_PO_SVN * m_validPOSVNRepository + NEEDS_POT_SVN * m_validPOTSVNRepository;
+
+ emit selectedChanged(actionValue);
+}
+
+void CatalogManagerView::activateItem(QListViewItem *)
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(!item)
+ return;
+
+ if(item->isDir())
+ {
+ item->setOpen(!item->isOpen());
+ return;
+ }
+
+ if(item->hasPo())
+ {
+ emit openFile(item->poFile(),item->package());
+ }
+ else if(item->hasPot())
+ {
+ emit openTemplate(item->potFile(),item->poFile(),item->package());
+ }
+ else
+ {
+ kdError(KBABEL_CATMAN) << "CatalogManagerView::activateItem: item has no file?" << endl;
+ }
+
+}
+
+void CatalogManagerView::slotOpenFile()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(item && item->isFile())
+ {
+ activateItem(item);
+ }
+}
+
+void CatalogManagerView::slotOpenFileInNewWindow()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(item && item->isFile())
+ {
+ QString filename;
+ if(item->hasPo())
+ {
+ emit openFileInNewWindow(item->poFile(),item->package());
+ }
+ else if(item->hasPot())
+ {
+ emit openTemplateInNewWindow(item->potFile(),item->poFile(),item->package());
+ }
+ }
+}
+
+void CatalogManagerView::slotOpenTemplate()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(item && item->isFile())
+ {
+ emit openFile(item->potFile(),item->package());
+ }
+}
+
+void CatalogManagerView::slotDeleteFile()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(item && item->isFile() && item->hasPo() && !item->hasPot())
+ {
+ const QString msg=i18n("Do you really want to delete the file %1?").arg(item->poFile());
+ if(KMessageBox::warningContinueCancel(this,msg,i18n("Warning"),KGuiItem( i18n("Delete"), "editdelete"))== KMessageBox::Continue)
+ {
+ if(!QFile::remove(item->poFile()))
+ {
+ KMessageBox::sorry(this,i18n("Was not able to delete the file %1!").arg(item->poFile()));
+ }
+ }
+ }
+}
+
+void CatalogManagerView::toggleMark()
+{
+ CatManListItem* i = (CatManListItem*) currentItem();
+ if( i && i->isDir() ) slotToggleMarksInDir();
+ else slotToggleMark();
+}
+
+void CatalogManagerView::slotToggleMark()
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(item && item->isFile())
+ {
+ bool wasMarked=item->marked();
+ item->setMarked(!wasMarked);
+
+ if(wasMarked)
+ {
+ _markerList.remove(item->package());
+ }
+ else
+ {
+ _markerList.append(item->package());
+ }
+ }
+
+ checkSelected();
+}
+
+void CatalogManagerView::slotToggleMarksInDir()
+{
+ CatManListItem* i=(CatManListItem*) currentItem();
+
+ if(i && i->isDir())
+ {
+ const QStringList contentList = i->allChildrenList(true);
+
+ QStringList::const_iterator it;
+ for( it = contentList.constBegin(); it != contentList.constEnd(); ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+
+ if ( item == 0 )
+ kdFatal(KBABEL_CATMAN) << "CatalogManagerView::slotToggleMarkInDir: item not in list" << endl;
+
+ const bool wasMarked=item->marked();
+ item->setMarked(!wasMarked);
+
+ if(wasMarked)
+ {
+ _markerList.remove(item->package());
+ }
+ else
+ {
+ _markerList.append(item->package());
+ }
+ }
+ }
+
+ checkSelected();
+}
+
+
+void CatalogManagerView::slotClearMarksInDir()
+{
+ CatManListItem* i=(CatManListItem*) currentItem();
+
+ if(i && i->isDir())
+ {
+ const QStringList contentList=i->contentsList(true);
+
+ QStringList::const_iterator it;
+ for( it = contentList.constBegin(); it != contentList.constEnd(); ++it )
+ {
+ CatManListItem* item = _fileList[(*it)];
+
+ if ( item == 0 )
+ kdFatal(KBABEL_CATMAN) << "CatalogManagerView::slotClearMarkInDir: item not in list" << endl;
+
+ if(item->marked())
+ {
+ _markerList.remove(item->package());
+ }
+ item->setMarked(false);
+ }
+ }
+
+ checkSelected();
+}
+
+
+void CatalogManagerView::slotDirCommand(int index)
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+
+ if(index>=0 && item && item->isDir())
+ {
+ QString cmd=*(_settings.dirCommands).at(index);
+ cmd.replace("@PACKAGE@",item->name());
+ cmd.replace("@PODIR@",item->poFile());
+ cmd.replace("@POTDIR@",item->potFile());
+ cmd.replace("@POFILES@",current().join(" "));
+ cmd.replace("@MARKEDPOFILES@",marked().join(" "));
+
+ kdDebug(KBABEL_CATMAN) << cmd << endl;
+
+ KProcess* proc = new KShellProcess();
+ _pendingProcesses.append(proc);
+
+ connect( proc,SIGNAL( processExited(KProcess *) ), this
+ ,SLOT( processEnded(KProcess*) ) );
+ connect( proc,SIGNAL( receivedStdout(KProcess*,char*,int) ), this
+ ,SLOT( showOutput(KProcess*,char*,int) ) );
+ connect( proc,SIGNAL( receivedStderr(KProcess*,char*,int) ), this
+ ,SLOT( showOutput(KProcess*,char*,int) ) );
+
+ *proc << "cd" << item->poFile() << ";" << cmd;
+ proc->start(KProcess::NotifyOnExit,KProcess::AllOutput);
+ }
+}
+
+void CatalogManagerView::slotFileCommand(int index)
+{
+ CatManListItem* item=(CatManListItem*) currentItem();
+
+ if(index>=0 && item && item->isFile())
+ {
+ CatManListItem* parent = (CatManListItem*)item->parent();
+
+ QString cmd=*(_settings.fileCommands).at(index);
+ cmd.replace("@PACKAGE@",item->name());
+ cmd.replace("@POFILE@",item->poFile());
+ cmd.replace("@POTFILE@",item->potFile());
+ cmd.replace("@PODIR@",parent->poFile());
+ cmd.replace("@POTDIR@",parent->potFile());
+ cmd.replace("@POEMAIL@",item->text(COL_TRANSLATOR));
+
+ kdDebug(KBABEL_CATMAN) << cmd << endl;
+
+ KProcess* proc = new KShellProcess();
+ _pendingProcesses.append(proc);
+
+ connect( proc,SIGNAL( processExited(KProcess *) ), this
+ ,SLOT( processEnded(KProcess*) ) );
+ connect( proc,SIGNAL( receivedStdout(KProcess*,char*,int) ), this
+ ,SLOT( showOutput(KProcess*,char*,int) ) );
+ connect( proc,SIGNAL( receivedStderr(KProcess*,char*,int) ), this
+ ,SLOT( showOutput(KProcess*,char*,int) ) );
+
+ *proc << "cd" << parent->poFile() << ";" << cmd;
+ proc->start(KProcess::NotifyOnExit,KProcess::AllOutput);
+ }
+
+}
+
+
+void CatalogManagerView::updateFile(QString fileWithPath, bool force)
+{
+ QString relFile;
+ if(fileWithPath.startsWith(_settings.poBaseDir))
+ {
+ relFile=fileWithPath.mid(_settings.poBaseDir.length());
+ }
+ else if(fileWithPath.startsWith(_settings.potBaseDir))
+ {
+ relFile=fileWithPath.mid(_settings.potBaseDir.length());
+ }
+ else
+ {
+ return;
+ }
+
+ if(relFile.endsWith(".pot"))
+ {
+ relFile.truncate(relFile.length()-4);
+ }
+ else if(relFile.endsWith(".po"))
+ {
+ relFile.truncate(relFile.length()-3);
+ }
+
+ CatManListItem* item=_fileList[relFile];
+
+ if(item)
+ {
+ _updateNesting++;
+ if( force ) item->forceUpdate();
+ else item->checkUpdate();
+ _updateNesting--;
+ }
+
+}
+
+void CatalogManagerView::updateAfterSave(QString fileWithPath, PoInfo &newInfo)
+{
+ QString relFile;
+ if(fileWithPath.startsWith(_settings.poBaseDir))
+ {
+ relFile=fileWithPath.mid(_settings.poBaseDir.length());
+ }
+ else if(fileWithPath.startsWith(_settings.potBaseDir))
+ {
+ relFile=fileWithPath.mid(_settings.potBaseDir.length());
+ }
+ else
+ {
+ return;
+ }
+
+ if(relFile.endsWith(".pot"))
+ {
+ relFile.truncate(relFile.length()-4);
+ }
+ else if(relFile.endsWith(".po"))
+ {
+ relFile.truncate(relFile.length()-3);
+ }
+
+ CatManListItem* item=_fileList[relFile];
+
+ if(item)
+ {
+ item->updateAfterSave(newInfo);
+ }
+
+}
+
+void CatalogManagerView::buildTree()
+{
+ // in case we were called after settings update
+ disconnect( this, SIGNAL( updateFinished() ), this, SLOT(buildTree() ) );
+
+ emit signalBuildTree(false); // announce start of building
+
+ clear();
+
+ if(isActive())
+ return;
+
+ _updateNesting++;
+
+ _active=true;
+ _stop=false;
+
+
+ CatManListItem* root = new CatManListItem(this, this,_settings.poBaseDir,_settings.potBaseDir);
+ _dirList.insert("/",root);
+ //root->setSelectable(false);
+
+ QFileInfo fileInfo(_settings.poBaseDir);
+ if(!fileInfo.isDir())
+ {
+ KMessageBox::error(this,i18n("You have not specified a valid folder "
+"for the base folder of the PO files:\n%1\n"
+"Please check your settings in the project settings dialog.").arg(_settings.poBaseDir));
+
+ _active=false;
+ _updateNesting--;
+ if( _updateNesting == 0 ) emit updateFinished();
+ return;
+ }
+
+ cvshandler->setPOBaseDir( _settings.poBaseDir );
+ svnhandler->setPOBaseDir( _settings.poBaseDir );
+ mailer->setPOBaseDir(_settings.poBaseDir);
+
+ fileInfo.setFile(_settings.potBaseDir);
+ if(!fileInfo.isDir() && !_settings.potBaseDir.isEmpty())
+ {
+ KMessageBox::error(this,i18n("You have not specified a valid folder "
+"for the base folder of the PO template files:\n%1\n"
+"Please check your settings in the project settings dialog.").arg(_settings.potBaseDir));
+ }
+
+ cvshandler->setPOTBaseDir( _settings.potBaseDir );
+ svnhandler->setPOTBaseDir( _settings.potBaseDir );
+
+ setCursor(KCursor::waitCursor());
+
+ //"/" is the root item
+ buildDir("/",true); // build dir without updating the items...
+
+ if( _stop ) {
+ _active = false;
+ _updateNesting--;
+ if( _updateNesting == 0 ) emit updateFinished();
+ return;
+ }
+
+ _dirWatch->addDir(_settings.poBaseDir);
+ if(!_settings.potBaseDir.isEmpty())
+ _dirWatch->addDir(_settings.potBaseDir);
+
+ emit signalBuildTree(true); // announce beginning of tree building
+
+ unsetCursor();
+
+ if( _stop ) {
+ _active = false;
+ _updateNesting--;
+ if( _updateNesting == 0 ) emit updateFinished();
+ return;
+ }
+
+ updateMarkerList();
+
+ const int files=_fileList.count()+_dirList.count();
+
+ _readInfoCount = 0;
+
+ emit prepareProgressBar(i18n("Reading file information"),files);
+
+ root->setOpen(true);
+
+ if( _stop ) {
+ _active = false;
+ _updateNesting--;
+ if( _updateNesting == 0 ) emit updateFinished();
+ return;
+ }
+
+ // first read information about the files...
+ QDictIterator<CatManListItem> it( _fileList ); // iterator for dict
+
+ int i=0;
+ while ( it.current() && !_stop)
+ {
+ it.current()->checkUpdate(true);
+ ++i;
+ ++it;
+ }
+
+ // ...then update directories
+ QDictIterator<CatManListItem> dit( _dirList ); // iterator for dict
+
+ while ( dit.current() && !_stop)
+ {
+ dit.current()->checkUpdate();
+ ++i;
+ ++dit;
+ }
+
+ emit clearProgressBar();
+
+ _dirWatch->startScan();
+ pause(false);
+
+ _active=false;
+
+ _updateNesting--;
+
+ if( _updateNesting == 0 )
+ {
+ emit updateFinished();
+ }
+}
+
+bool CatalogManagerView::buildDir(QString relDir,bool fast)
+{
+ if( _stop ) return false;
+
+ bool haveTemplateDir=true;
+ QFileInfo fileInfo;
+
+ fileInfo.setFile(_settings.potBaseDir);
+ if(!fileInfo.isDir())
+ {
+ haveTemplateDir=false;
+ }
+
+ bool potHasFiles=false;
+ if(haveTemplateDir)
+ potHasFiles=buildDir(_settings.potBaseDir,relDir,".pot",fast);
+
+ bool poHasFiles=buildDir(_settings.poBaseDir,relDir,".po",fast);
+
+ return (poHasFiles | potHasFiles);
+}
+
+
+bool CatalogManagerView::buildDir(const QString& baseDir,const QString& relDir
+ , const QString extension , bool fast)
+{
+ if( _stop ) return false;
+
+ bool havePoFiles=false;
+
+ CatManListItem* thisItem=_dirList[relDir];
+ if(!thisItem)
+ {
+ kdFatal(KBABEL_CATMAN) << "null pointer to this item" << endl;
+ return false;
+ }
+
+ const QString poBaseDir=_settings.poBaseDir;
+ const QString potBaseDir=_settings.potBaseDir;
+
+ // traverse directory in poBaseDir
+ QDir dir(baseDir+relDir);
+ QStringList entryList=dir.entryList("*"+extension,QDir::Files,QDir::Name);
+
+ QStringList::const_iterator it;
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd() && !_stop ; ++it )
+ {
+ if( _stop ) return false;
+
+ havePoFiles=true;
+
+ QString file=relDir+(*it);
+ file.remove(QRegExp(extension+"$"));
+ CatManListItem* item = _fileList[file];
+ if(!item)
+ {
+ item = new CatManListItem(this,thisItem,poBaseDir+file+".po",potBaseDir+file+".pot",file);
+ _fileList.insert(file,item);
+ _readInfoFileList.prepend(file);
+
+ if(_markerList.contains(file))
+ {
+ item->setMarked(true);
+ }
+
+ if(!fast)
+ {
+ item->checkUpdate();
+ }
+ }
+ }
+
+ entryList=dir.entryList(QDir::Dirs,QDir::Name);
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd() && !_stop ; ++it )
+ {
+ if( _stop ) return false;
+
+ if((*it)=="." || (*it)=="..")
+ {
+ continue;
+ }
+
+ QString subDir=relDir+(*it)+"/";
+ if(!_dirWatch->contains(baseDir+subDir))
+ {
+ _dirWatch->addDir(baseDir+subDir);
+ }
+
+ bool otherHasFiles=true;
+
+ CatManListItem* item = _dirList[subDir];
+ if(!item && !_stop)
+ {
+ item = new CatManListItem(this, thisItem,poBaseDir+subDir,potBaseDir+subDir,subDir);
+ _dirList.insert(subDir,item);
+
+ otherHasFiles=false;
+ }
+
+ if( _stop ) return false;
+
+ // recursive call
+ if(!buildDir(baseDir,subDir,extension,fast) && !otherHasFiles)
+ {
+ kdDebug(KBABEL_CATMAN) << "skipping " << subDir << endl;
+ deleteDirItem(subDir);
+ item=0;
+ }
+ else
+ havePoFiles=true;
+
+ } // end looking up directories in po base dir
+
+ return havePoFiles;
+}
+
+
+void CatalogManagerView::updateDir(QString relDir)
+{
+ if( _stop ) return;
+
+ kdDebug(KBABEL_CATMAN) << "updating dir " << relDir << endl;
+
+ bool havePoFiles=false;
+
+ CatManListItem* thisItem=_dirList[relDir];
+ if(!thisItem)
+ {
+ kdFatal(KBABEL_CATMAN) << "null pointer to this item" << endl;
+ return;
+ }
+
+ QStringList contentList = thisItem->contentsList(true);
+
+ const QString poBaseDir=_settings.poBaseDir;
+ const QString potBaseDir=_settings.potBaseDir;
+
+ // first lookup template directory
+ QDir dir(potBaseDir+relDir);
+ QStringList entryList=dir.entryList("*.pot",QDir::Files,QDir::Name);
+
+ QStringList::const_iterator it;
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it )
+ {
+ if( _stop ) return;
+
+ havePoFiles=true;
+
+ QString file=relDir+(*it);
+ file.remove(QRegExp(".pot$"));
+ CatManListItem* item = _fileList[file];
+ if(!item)
+ {
+ item = new CatManListItem(this, thisItem,poBaseDir+file+".po",potBaseDir+file+".pot",file);
+ _fileList.insert(file,item);
+
+ if(_markerList.contains(file))
+ {
+ item->setMarked(true);
+ }
+
+ item->checkUpdate();
+ }
+ else
+ {
+ item->checkUpdate();
+ }
+
+ contentList.remove(file);
+ }
+
+ entryList=dir.entryList(QDir::Dirs,QDir::Name);
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it )
+ {
+ if( _stop ) return;
+
+ if((*it)=="." || (*it)=="..")
+ {
+ continue;
+ }
+
+ bool newDirAdded=false;
+
+ QString subDir=relDir+(*it)+"/";
+ if(!_dirWatch->contains(potBaseDir+subDir))
+ {
+ _dirWatch->addDir(potBaseDir+subDir);
+
+ newDirAdded=true;
+ }
+
+ CatManListItem* item = _dirList[subDir];
+ if(!item && newDirAdded)
+ {
+ item = new CatManListItem(this, thisItem,poBaseDir+subDir,potBaseDir+subDir,subDir);
+ _dirList.insert(subDir,item);
+
+ if(!buildDir(subDir,false))
+ {
+ kdDebug(KBABEL_CATMAN) << "skipping " << subDir << endl;
+ deleteDirItem(subDir);
+ item=0;
+ }
+ }
+ else if(newDirAdded)
+ {
+ updateDir(subDir);
+ }
+
+
+ // if directory was already here, but no item
+ // -> directory contains no files
+ if(item && !newDirAdded)
+ {
+ havePoFiles=true;
+ }
+
+ } // end looking up directories in template dir
+
+ // now traverse directory in poBaseDir
+ dir.setPath(poBaseDir+relDir);
+ entryList=dir.entryList("*.po",QDir::Files,QDir::Name);
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it )
+ {
+ havePoFiles=true;
+
+ if( _stop ) return;
+
+ QString file=relDir+(*it);
+ file.remove(QRegExp(".po$"));
+ CatManListItem* item = _fileList[file];
+ if(!item)
+ {
+ item = new CatManListItem(this, thisItem,poBaseDir+file+".po",potBaseDir+file+".pot",file);
+ _fileList.insert(file,item);
+
+ if(_markerList.contains(file))
+ {
+ item->setMarked(true);
+ }
+
+ item->checkUpdate();
+ }
+ else
+ {
+ item->checkUpdate();
+ }
+
+ contentList.remove(file);
+ }
+
+ entryList=dir.entryList(QDir::Dirs,QDir::Name);
+
+ for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it )
+ {
+ if( _stop ) return;
+
+ if((*it)=="." || (*it)=="..")
+ {
+ continue;
+ }
+
+ bool newDirAdded=false;
+
+ QString subDir=relDir+(*it)+"/";
+ if(!_dirWatch->contains(poBaseDir+subDir))
+ {
+ _dirWatch->addDir(poBaseDir+subDir);
+ newDirAdded=true;
+ }
+
+ CatManListItem* item = _dirList[subDir];
+
+ bool templateHasFiles=(bool)item;
+
+ if(!item && newDirAdded)
+ {
+ item = new CatManListItem(this, thisItem,poBaseDir+subDir,potBaseDir+subDir,subDir);
+ _dirList.insert(subDir,item);
+
+ if(!buildDir(subDir,false) && !templateHasFiles)
+ {
+ kdDebug(KBABEL_CATMAN) << "skipping " << subDir << endl;
+ deleteDirItem(subDir);
+ item=0;
+ }
+ }
+ else if(newDirAdded)
+ {
+ updateDir(subDir);
+ }
+
+ // if directory was already here, but no item
+ // -> directory contains no files
+ if(item && !newDirAdded)
+ {
+ havePoFiles=true;
+ }
+
+
+ } // end looking up directories in po base dir
+
+
+ // check, if something in the directory has been deleted
+ // but only if we traversed also the template directory
+ if(contentList.count()>0)
+ {
+ QStringList::const_iterator it;
+ for( it = contentList.constBegin(); it != contentList.constEnd(); ++it )
+ {
+ QFileInfo po(poBaseDir+(*it));
+ QFileInfo pot(potBaseDir+(*it));
+
+ if(!po.exists() && !pot.exists())
+ {
+ CatManListItem* item = _fileList[(*it)];
+ if(item)
+ {
+ if(item->marked())
+ _markerList.remove(item->package());
+
+ _fileList.remove((*it));
+ delete item;
+ }
+ }
+ }
+ }
+
+ if(!havePoFiles)
+ {
+ deleteDirItem(relDir);
+
+ // if this directory has to be removed, check, if
+ // the parent directory has to be removed too
+ const int index=relDir.findRev("/",relDir.length()-2);
+ if(index<0)
+ {
+ relDir="/";
+ }
+ relDir=relDir.left(index+1);
+ updateDir(relDir);
+ }
+}
+
+void CatalogManagerView::directoryChanged(const QString& dir)
+{
+ pause(true);
+
+ QString relDir, relDirPo, relDirPot;
+ if(dir.startsWith(_settings.poBaseDir))
+ {
+ relDirPo=dir.mid(_settings.poBaseDir.length());
+ }
+ if(dir.startsWith(_settings.potBaseDir))
+ {
+ relDirPot=dir.mid(_settings.potBaseDir.length());
+ }
+
+ if( relDirPo.isEmpty() )
+ {
+ // use POT
+ relDir = relDirPot;
+ }
+ else if( relDirPot.isEmpty() )
+ {
+ // use PO
+ relDir = relDirPo;
+ }
+ else
+ {
+ // both PO and POT usable, find out the correct one
+ if( relDirPo.left(1) == "/" )
+ {
+ relDir = relDirPo;
+ }
+ else
+ {
+ relDir = relDirPot;
+ }
+ }
+
+ if(relDir.right(1)!="/")
+ {
+ relDir+="/";
+ }
+
+ kdDebug(KBABEL_CATMAN) << "directory changed: " << relDir << endl;
+
+ QFileInfo fileInfo(_settings.potBaseDir);
+
+ CatManListItem* thisItem=_dirList[relDir];
+ if(!thisItem)
+ {
+ // if this item is not in the list search for next existing parent item
+ QString prevRelDir;
+ do
+ {
+ prevRelDir=relDir;
+ const int index=relDir.findRev("/",relDir.length()-2);
+ if(index<0)
+ {
+ relDir="/";
+ }
+ relDir=relDir.left(index+1);
+
+ thisItem=_dirList[relDir];
+ }
+ while(relDir!="/" && !thisItem);
+
+ if(!thisItem)
+ {
+ kdFatal(KBABEL_CATMAN) << "null pointer to this item: " << relDir << endl;
+ return;
+ }
+ else
+ {
+ // if a parent item dir is found, create the needed item in this dir
+ // and build the tree from this item on
+ kdDebug(KBABEL_CATMAN) << "building dir: " << prevRelDir << endl;
+ CatManListItem* item = new CatManListItem(this, thisItem,_settings.poBaseDir+prevRelDir
+ ,_settings.potBaseDir+prevRelDir,prevRelDir);
+ _dirList.insert(prevRelDir,item);
+
+
+ if(!buildDir(prevRelDir,false))
+ {
+ deleteDirItem(prevRelDir);
+ }
+ }
+ }
+ else
+ {
+ updateDir(relDir);
+ }
+
+ pause(false);
+}
+
+
+void CatalogManagerView::directoryDeleted(const QString& dir)
+{
+ pause(true);
+
+ QString relDir, relDirPo, relDirPot;
+ if(dir.startsWith(_settings.poBaseDir))
+ {
+ relDirPo=dir.mid(_settings.poBaseDir.length());
+ }
+ if(dir.startsWith(_settings.potBaseDir))
+ {
+ relDirPot=dir.mid(_settings.potBaseDir.length());
+ }
+
+ if( relDirPo.isEmpty() )
+ {
+ // use POT
+ relDir = relDirPot;
+ }
+ else if( relDirPot.isEmpty() )
+ {
+ // use PO
+ relDir = relDirPo;
+ }
+ else
+ {
+ // both PO and POT usable, find out the correct one
+ if( relDirPo.left(1) == "/" )
+ {
+ relDir = relDirPo;
+ }
+ else
+ {
+ relDir = relDirPot;
+ }
+ }
+
+ if(relDir.right(1)!="/")
+ {
+ relDir+="/";
+ }
+
+ kdDebug(KBABEL_CATMAN) << "directory deleted: " << relDir << endl;
+
+ CatManListItem* thisItem=_dirList[relDir];
+ if(thisItem)
+ {
+ // we have to take care, if one directory still exists
+ const bool poDeleted=!thisItem->hasPo();
+ const bool potDeleted=!thisItem->hasPot();
+
+ // if neither the po- nor the pot-directory exists any more
+ // delete all sub items
+ if(poDeleted && potDeleted)
+ {
+ deleteDirItem(relDir);
+ }
+ else
+ {
+ QStringList childList = thisItem->contentsList();
+
+ CatManListItem* item;
+ QStringList::const_iterator it;
+ for( it = childList.constBegin();it != childList.constEnd(); ++it )
+ {
+ item=_fileList[(*it)];
+ if(item)
+ {
+ if( (poDeleted && !item->hasPot()) ||
+ (potDeleted && !item->hasPo()) )
+ {
+ _fileList.remove((*it));
+ delete item;
+ }
+ else
+ {
+ item->checkUpdate();
+ }
+ }
+ else
+ {
+ item=_dirList[(*it)];
+ if(item)
+ {
+ if( (poDeleted && !item->hasPot()) ||
+ (potDeleted && !item->hasPo()) )
+ {
+ deleteDirItem((*it));
+ }
+ }
+ else
+ {
+ kdDebug(KBABEL_CATMAN) << "directoryDeleted: don't have item "
+ << (*it) << endl;
+ }
+ }
+ }
+ }
+ }
+
+ pause(false);
+}
+
+void CatalogManagerView::fileInfoRead( QString filename )
+{
+ if( _readInfoFileList.find( filename ) != _readInfoFileList.end() ) {
+ emit progress( ++_readInfoCount);
+ _readInfoFileList.remove( filename );
+ }
+
+ if( _readInfoFileList.isEmpty() ) emit clearProgressBar();
+}
+
+void CatalogManagerView::setSettings(CatManSettings newSettings)
+{
+ CatManSettings oldSettings=_settings;
+ _settings=newSettings;
+
+ if(_settings.poBaseDir.right(1)=="/")
+ _settings.poBaseDir.truncate(_settings.poBaseDir.length()-1);
+ if(_settings.potBaseDir.right(1)=="/")
+ _settings.potBaseDir.truncate(_settings.potBaseDir.length()-1);
+
+ _dirCommandsMenu->clear();
+ int counter=0;
+ for ( QStringList::const_iterator it = _settings.dirCommandNames.constBegin()
+ ; it != _settings.dirCommandNames.constEnd(); ++it )
+ {
+ _dirCommandsMenu->insertItem((*it),counter);
+ counter++;
+ }
+ _dirCommandsMenu->insertSeparator();
+ _dirCommandsMenu->insertItem(i18n("Log Window"),this,SLOT(showLog()));
+
+ _fileCommandsMenu->clear();
+ counter=0;
+ for ( QStringList::const_iterator it = _settings.fileCommandNames.constBegin()
+ ; it != _settings.fileCommandNames.constEnd(); ++it )
+ {
+ _fileCommandsMenu->insertItem((*it),counter);
+ counter++;
+ }
+ _fileCommandsMenu->insertSeparator();
+ _fileCommandsMenu->insertItem(i18n("Log Window"),this,SLOT(showLog()));
+
+ const bool pathChanged = (oldSettings.poBaseDir!=_settings.poBaseDir)
+ || (oldSettings.potBaseDir!=_settings.potBaseDir);
+
+ if(pathChanged)
+ {
+ if( !isActive() ) {
+ QTimer::singleShot(100,this,SLOT(buildTree()));
+ } else {
+ stop();
+ connect( this, SIGNAL( updateFinished() ), this, SLOT(buildTree() ) );
+ }
+ }
+
+ toggleColumn( COL_MARKER, _settings.flagColumn );
+ toggleColumn( COL_FUZZY, _settings.fuzzyColumn );
+ toggleColumn( COL_UNTRANS, _settings.untranslatedColumn );
+ toggleColumn( COL_TOTAL, _settings.totalColumn );
+ // FIXME: follow CVS/SVN status
+ toggleColumn( COL_CVS_OR_SVN, _settings.cvsColumn );
+ toggleColumn( COL_REVISION, _settings.revisionColumn );
+ toggleColumn( COL_TRANSLATOR, _settings.translatorColumn );
+}
+
+
+CatManSettings CatalogManagerView::settings() const
+{
+ return _settings;
+}
+
+
+void CatalogManagerView::hideEvent(QHideEvent*)
+{
+ pause(true);
+
+ if(_dirWatch)
+ _dirWatch->stopScan();
+}
+
+void CatalogManagerView::showEvent(QShowEvent*)
+{
+ QTimer::singleShot(1,this,SLOT(checkUpdate()));
+
+ pause(false);
+
+ if(_dirWatch)
+ _dirWatch->startScan(true);
+}
+
+void CatalogManagerView::contentsMousePressEvent(QMouseEvent* event)
+{
+ if(event->button() == LeftButton)
+ _pressPos=event->pos();
+
+ QListView::contentsMousePressEvent( event );
+}
+
+void CatalogManagerView::contentsMouseMoveEvent(QMouseEvent* event)
+{
+ if(event->state() & LeftButton)
+ {
+ const int delay = KGlobalSettings::dndEventDelay();
+ if(QABS( event->pos().x() - _pressPos.x() ) >= delay ||
+ QABS( event->pos().y() - _pressPos.y() ) >= delay)
+ {
+ CatManListItem* item = (CatManListItem*)itemAt(contentsToViewport(_pressPos));
+ if(item && item->isFile())
+ {
+ // always add the po-file and if existing the pot-file to the drag and
+ // let the user decide what to do, when dropping into kbabel
+ QStrList uri;
+ uri.append(QUriDrag::localFileToUri(item->poFile()));
+ if(item->hasPot())
+ uri.append(QUriDrag::localFileToUri(item->potFile()));
+
+ QUriDrag* drag = new QUriDrag(uri,this);
+ QPixmap icon=KGlobal::iconLoader()->loadIcon("txt",KIcon::Desktop);
+ drag->setPixmap(icon,QPoint(icon.width()/2,icon.height()/2));
+ drag->drag();
+ }
+ else
+ {
+ QListView::contentsMouseMoveEvent(event);
+ }
+ }
+ else
+ {
+ QListView::contentsMouseMoveEvent(event);
+ }
+ }
+ else
+ {
+ QListView::contentsMouseMoveEvent(event);
+ }
+}
+
+void CatalogManagerView::readMarker( KConfig* config)
+{
+ KConfigGroupSaver cs(config,"CatalogManager");
+
+ _markerList = config->readListEntry("Marker");
+}
+
+void CatalogManagerView::saveMarker( KConfig* config) const
+{
+ KConfigGroupSaver cs(config,"CatalogManager");
+
+ config->writeEntry("Marker",_markerList);
+ config->sync();
+}
+
+
+void CatalogManagerView::deleteDirItem(QString relDir)
+{
+ CatManListItem* thisItem=_dirList[relDir];
+
+ if(!thisItem)
+ return;
+
+ _dirList.remove(relDir);
+
+ QStringList childList = thisItem->allChildrenList();
+
+ QStringList::const_iterator it;
+ for( it = childList.constBegin();it != childList.constEnd(); ++it )
+ {
+ if(!_fileList.remove((*it)))
+ _dirList.remove((*it));
+ }
+
+
+ // delete the item with all sub item
+ delete thisItem;
+}
+
+
+
+void CatalogManagerView::processEnded(KProcess* proc)
+{
+ _pendingProcesses.removeRef(proc);
+}
+
+
+void CatalogManagerView::showOutput(KProcess*, char *buffer, int buflen)
+{
+ const QCString output(buffer,buflen+1);
+
+ _logView->insert(output);
+}
+
+void CatalogManagerView::columnClicked(QListViewItem * item, const QPoint &, int c)
+{
+ if( item && c == COL_MARKER )
+ {
+ slotToggleMark();
+ }
+}
+
+CatManListItem *CatalogManagerView::itemBelow( CatManListItem *item )
+{
+ if( item->isDir() )
+ {
+ if( item->firstChild() )
+ return static_cast<CatManListItem *>( item->firstChild() );
+ else
+ {
+ while( !static_cast<CatManListItem *>( item->nextSibling() ) )
+ {
+ item = static_cast<CatManListItem *>( item->parent() );
+ if( !item ) return item;
+ }
+ return static_cast<CatManListItem *>( item->nextSibling() );
+ }
+ }
+ else
+ {
+ while( !static_cast<CatManListItem *>( item->nextSibling() ) )
+ {
+ item = static_cast<CatManListItem *>( item->parent());
+ if( !item ) return item;
+ }
+ return static_cast<CatManListItem *>( item->nextSibling() );
+ }
+}
+
+CatManListItem *CatalogManagerView::itemAbove( CatManListItem *item )
+{
+ if( item->isDir() )
+ {
+ if( item->firstChild() )
+ return static_cast<CatManListItem *>( item->lastChild() );
+ else
+ {
+ while( !static_cast<CatManListItem *>( item->previousSibling() ) )
+ {
+ item = static_cast<CatManListItem *>( item->parent() );
+ if( !item ) return item;
+ }
+ return static_cast<CatManListItem *>( item->previousSibling() );
+ }
+ }
+ else
+ {
+ while( !static_cast<CatManListItem *>( item->previousSibling() ) )
+ {
+ item = static_cast<CatManListItem *>( item->parent());
+ if( !item ) return item;
+ }
+ return static_cast<CatManListItem *>( item->previousSibling() );
+ }
+}
+
+void CatalogManagerView::gotoNextUntranslated()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->untranslated() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousUntranslated()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->untranslated() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextFuzzy()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->fuzzy() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousFuzzy()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->fuzzy() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextFuzzyOrUntranslated()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->untranslated() > 0 || i->fuzzy() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousFuzzyOrUntranslated()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->untranslated() > 0 || i->fuzzy() > 0 )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextError()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->hasErrors() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousError()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->hasErrors() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextTemplate()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->hasPot() && !i->hasPo() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousTemplate()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->hasPot() && !i->hasPo() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextPo()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->hasPo() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousPo()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->hasPo() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoNextMarked()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( ( i = itemBelow(current)) )
+ {
+ if( i->marked() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+void CatalogManagerView::gotoPreviousMarked()
+{
+ CatManListItem *i;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ while( (i = itemAbove(current)) )
+ {
+ if( i->marked() )
+ {
+ setCurrentItem(i);
+ ensureItemVisible(i);
+ return;
+ } else current = i;
+ }
+}
+
+QStringList CatalogManagerView::current()
+{
+ QStringList result;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ if( current->isDir() )
+ {
+ QStringList s = current->allChildrenList(true);
+ QStringList::const_iterator it;
+ for( it = s.constBegin() ; it != s.constEnd(); ++it )
+ {
+ CatManListItem *item = _fileList[(*it)];
+ result.append( item->poFile() );
+ }
+ }
+ else
+ {
+ if( current->hasPo() ) result.append( current->poFile() );
+ }
+ return result;
+}
+
+QStringList CatalogManagerView::marked()
+{
+ QStringList result;
+
+ QStringList::const_iterator it;
+ for( it = _markerList.constBegin() ; it != _markerList.constEnd(); ++it )
+ {
+ CatManListItem *item = _fileList[(*it)];
+ result.append( item->poFile() );
+ }
+ return result;
+}
+
+void CatalogManagerView::updateCurrent()
+{
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ if( !current->hasPo() && !current->hasPot() )
+ {
+ if( current->isFile() )
+ {
+ _fileList.remove(current->package());
+ delete current;
+ }
+ else
+ {
+ directoryDeleted(current->package());
+ }
+ }
+ else
+ {
+ if( current->isDir() )
+ {
+ directoryChanged(current->poFile() );
+ }
+
+ // check, if the item didn't get lost by the update in directoryChanged()
+ CatManListItem *new_current = static_cast<CatManListItem *>(currentItem());
+ if (new_current == current)
+ {
+ current->forceUpdate();
+ }
+ }
+}
+
+void CatalogManagerView::updateFiles( const QStringList& files )
+{
+ QStringList::ConstIterator it;
+ for ( it = files.constBegin( ); it != files.constEnd( ); ++it ) {
+ updateFile( *it, true );
+ }
+}
+
+CVSHandler * CatalogManagerView::cvsHandler( )
+{
+ return cvshandler;
+}
+
+SVNHandler * CatalogManagerView::svnHandler( )
+{
+ return svnhandler;
+}
+
+void CatalogManagerView::validateUsingTool( const KDataToolInfo &tool, const QString& command )
+{
+ QStringList result;
+ CatManListItem *current = static_cast<CatManListItem *>(currentItem());
+ if( current->isDir() )
+ {
+ const QStringList s = current->allChildrenList(true);
+ QStringList::const_iterator it;
+ for( it = s.constBegin() ; it != s.constEnd(); ++it )
+ {
+ CatManListItem *item = _fileList[(*it)];
+ if( item && item->hasPo() ) result.append( item->package() );
+ }
+ }
+ else
+ {
+ result.append( current->package() );
+ }
+
+ validate_internal( result, tool, command );
+}
+
+void CatalogManagerView::validateMarkedUsingTool( const KDataToolInfo &tool, const QString& command )
+{
+ validate_internal( _markerList, tool, command );
+}
+
+void CatalogManagerView::validate_internal( const QStringList& files, const KDataToolInfo &tool, const QString& )
+{
+ if( files.isEmpty() ) return;
+
+ KDataTool* t = tool.createTool();
+
+ if( !t )
+ {
+ KMessageBox::error( this, i18n("Cannot instantiate a validation tool.\n"
+ "Please check your installation."), i18n("Validation Tool Error") );
+ return;
+ }
+
+ // setup options
+ if( !_validateOptionsDlg )
+ {
+ _validateOptionsDlg = new KDialogBase( this, "validation options",
+ true, i18n("Validation Options"), KDialogBase::Ok|KDialogBase::Cancel);
+ _validateOptions = new ValidationOptions(_validateOptionsDlg);
+ _validateOptionsDlg->setMainWidget( _validateOptions );
+ _validateOptions->resize( _validateOptions->sizeHint() );
+
+ // setup stored values
+ _validateOptions->markAsFuzzy->setChecked( _markAsFuzzy );
+ _validateOptions->ignoreFuzzy->setChecked( _ignoreFuzzy );
+ }
+
+ if( _validateOptionsDlg->exec() != QDialog::Accepted )
+ {
+ delete t;
+
+ return;
+ }
+
+ if( !_validateDialog )
+ {
+ _validateDialog = new ValidateProgressDialog(_settings.ignoreURL, this);
+ connect( _validateDialog, SIGNAL( errorDoubleClicked(const QString,const int)),
+ this, SLOT(showError( const QString, const int )));
+ }
+
+ _markAsFuzzy = _validateOptions->markAsFuzzy->isChecked();
+ _ignoreFuzzy = _validateOptions->ignoreFuzzy->isChecked();
+
+ _validateDialog->setMarkAsFuzzy(_markAsFuzzy);
+ _validateDialog->setIgnoreFuzzy(_ignoreFuzzy);
+
+ QPtrList<CatManListItem> fileitems;
+
+ for( QValueListConstIterator<QString> it=files.begin() ; it!=files.end() ; ++it )
+ {
+ CatManListItem* item=_fileList[ (*it) ];
+ if( item ) {
+ fileitems.append(item);
+ } else kdDebug(KBABEL_CATMAN) << "Cannot find the file item for " << (*it) << endl;
+ }
+
+ _validateDialog->validate(tool, fileitems);
+
+ delete t;
+}
+
+void CatalogManagerView::showError( const QString package, const int num )
+{
+ CatManListItem* item = _fileList[ package];
+ if( !item )
+ {
+ kdWarning() << "Can not find error package: " << package << endl;
+ return;
+ }
+
+ emit gotoFileEntry( item->poFile(), package, num );
+}
+
+void CatalogManagerView::updateMarkerList()
+{
+ QStringList newMarkers;
+
+ for( QStringList::const_iterator it = _markerList.constBegin(); it != _markerList.constEnd(); ++it ) {
+ if( _fileList[ (*it) ] )
+ newMarkers.append( (*it) );
+ }
+
+ _markerList = newMarkers;
+}
+
+void CatalogManagerView::slotValidPOCVSRepository( bool valid )
+{
+ m_validPOCVSRepository = valid;
+ slotToggleCVSOrSVNColumn(valid);
+ // set initial state for CVS menu entries
+ emit selectedChanged(NEEDS_PO + NEEDS_PO_CVS * m_validPOCVSRepository);
+}
+
+void CatalogManagerView::slotValidPOSVNRepository( bool valid )
+{
+ m_validPOSVNRepository = valid;
+ slotToggleCVSOrSVNColumn(valid);
+ // set initial state for SVN menu entries
+ emit selectedChanged(NEEDS_PO + NEEDS_PO_SVN * m_validPOSVNRepository);
+}
+
+void CatalogManagerView::slotValidPOTCVSRepository( bool valid )
+{
+ m_validPOTCVSRepository = valid;
+ // set initial state for CVS menu entries
+ // ### TODO: something missing here?
+}
+
+void CatalogManagerView::slotValidPOTSVNRepository( bool valid )
+{
+ m_validPOTSVNRepository = valid;
+ // set initial state for SVN menu entries
+ // ### TODO: something missing here?
+}
+
+void CatalogManagerView::slotToggleCVSOrSVNColumn( bool show )
+{
+#if 0
+ toggleColumn( COL_CVS_OR_SVN, show );
+#else
+ // ### HACK
+ toggleColumn( COL_CVS_OR_SVN, m_validPOCVSRepository || m_validPOSVNRepository );
+
+#endif
+}
+
+void CatalogManagerView::toggleColumn( uint column, bool show )
+{
+ if ( show ) {
+ setColumnWidthMode( column, Maximum );
+ setColumnWidth( column, -1 );
+ // ensure that the column heading is always fully visible
+ setColumnText( column, COLTEXT(column));
+ } else {
+ setColumnWidthMode( column, Manual );
+ setColumnWidth( column, 0 );
+ }
+}
+
+#include "catalogmanagerview.moc"
+// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/kbabel/catalogmanager/catalogmanagerview.h b/kbabel/catalogmanager/catalogmanagerview.h
new file mode 100644
index 00000000..e4421973
--- /dev/null
+++ b/kbabel/catalogmanager/catalogmanagerview.h
@@ -0,0 +1,474 @@
+/* ****************************************************************************
+ 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>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+#ifndef CATALOGMANAGERVIEW_H
+#define CATALOGMANAGERVIEW_H
+
+#include <qdict.h>
+#include <qlistview.h>
+#include <qdatetime.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+#include <qguardedptr.h>
+
+#include <kdialogbase.h>
+#include <kdirwatch.h>
+#include <kprocess.h>
+#include <qptrlist.h>
+
+#include "kbproject.h"
+#include "projectsettings.h"
+#include "findoptions.h"
+#include "cvsresources.h"
+#include "svnresources.h"
+
+class CatManListItem;
+class QPixmap;
+class QPopupMenu;
+class KBabelDictBox;
+class CatManPreferences;
+class QTextEdit;
+class KProgress;
+class KConfig;
+class KDataToolInfo;
+class ValidateProgressDialog;
+class CVSHandler;
+class SVNHandler;
+class MarkPatternDialog;
+class ValidationOptions;
+
+namespace KBabel
+{
+ class KBabelMailer;
+ class PoInfo;
+}
+
+class CatalogManagerView : public QListView
+{
+ Q_OBJECT
+public:
+ CatalogManagerView(KBabel::Project::Ptr project, QWidget* parent=0, const char* name=0);
+ virtual ~CatalogManagerView();
+
+ KBabel::CatManSettings settings() const;
+ /** clears the tree */
+ virtual void clear();
+
+ /** pauses the update timer */
+ void pause(bool);
+
+ /** if file fileWithPath exists in the treeview, this is updated */
+ void updateFile(QString fileWithPath, bool force = false);
+
+ void updateAfterSave(QString fileWithPath, KBabel::PoInfo &info);
+
+ bool isActive() const {return _active;}
+ bool isStopped() const {return _stop;}
+
+ void restoreView(KConfig *config);
+ void saveView(KConfig *config) const;
+
+ void setRMBMenuFile( QPopupMenu *m);
+ void setRMBMenuDir( QPopupMenu *m);
+ void setDirCommandsMenu( QPopupMenu *m);
+ void setFileCommandsMenu( QPopupMenu *m);
+
+ CVSHandler * cvsHandler();
+ SVNHandler * svnHandler();
+
+public slots:
+ void setSettings(KBabel::CatManSettings newSettings);
+ void toggleMark();
+ /**
+ * removes all marks in directory of current item (must be a directory)
+ */
+ void slotClearMarksInDir();
+ void clearAllMarks();
+ void toggleAllMarks();
+ void markModifiedFiles();
+ void loadMarks();
+ void saveMarks();
+ void slotMarkPattern( );
+ void slotUnmarkPattern( );
+ /**
+ * traverses all childs in the directory of the current item
+ * (including all subdirectories) and displays some statistics
+ * about the translations. If the item is a file, its
+ * parent directory is used instead.
+ */
+ void statistics();
+ /**
+ * traverses all marked childs in the directory of the current item
+ * (including all subdirectories) and displays some statistics
+ * about the translations. If the item is a file, its
+ * parent directory is used instead.
+ */
+ void markedStatistics();
+ /**
+ * calls @ref Msgfmt::checkSyntax, to check the po-file of
+ * the selected item
+ */
+ void checkSyntax();
+
+ void roughTranslation();
+ void markedRoughTranslation();
+
+ /** Send the selected item as a compressed mail attachment. If the
+ * selected item is a directory send the items contained in the
+ * directory.
+ */
+ void mailFiles();
+ /** Send the marked items as a compressed mail attachment.
+ */
+ void mailMarkedFiles();
+
+ void packageFiles();
+ void packageMarkedFiles();
+
+ void cvsUpdate( );
+ void cvsUpdateMarked( );
+ void cvsCommit( );
+ void cvsCommitMarked( );
+ void cvsStatus( );
+ void cvsStatusMarked( );
+ void cvsUpdateTemplate( );
+ void cvsUpdateMarkedTemplate( );
+ void cvsCommitTemplate( );
+ void cvsCommitMarkedTemplate( );
+ void cvsDiff( );
+
+ void svnUpdate( );
+ void svnUpdateMarked( );
+ void svnCommit( );
+ void svnCommitMarked( );
+ void svnStatusRemote();
+ void svnStatusRemoteMarked();
+ void svnStatusLocal();
+ void svnStatusLocalMarked();
+ void svnUpdateTemplate( );
+ void svnUpdateMarkedTemplate( );
+ void svnCommitTemplate( );
+ void svnCommitMarkedTemplate( );
+ void svnDiff( );
+ void svnInfo();
+ void svnInfoMarked();
+
+ QString find(KBabel::FindOptions &options, QStringList &rest);
+
+ void showLog();
+
+ void stop(bool s = true);
+
+ /**
+ * Stop searching, do not try to proceed to the next file
+ * @ref @find will return clear list of rest to be searched
+ * and @ref QString::null, if search string was not is the last searched file
+ */
+ void stopSearch();
+
+ /**
+ * Information for this file has been read. If the file is in
+ * @ref @_readInfoFileList, it will update progress bar by emitting @ref @progress
+ */
+ void fileInfoRead( QString file );
+
+ void gotoNextUntranslated();
+ void gotoPreviousUntranslated();
+ void gotoNextFuzzy();
+ void gotoPreviousFuzzy();
+ void gotoNextFuzzyOrUntranslated();
+ void gotoPreviousFuzzyOrUntranslated();
+ void gotoNextError();
+ void gotoPreviousError();
+ void gotoNextTemplate();
+ void gotoPreviousTemplate();
+ void gotoNextPo();
+ void gotoPreviousPo();
+ void gotoNextMarked();
+ void gotoPreviousMarked();
+
+ void validateUsingTool( const KDataToolInfo &, const QString& );
+ void validateMarkedUsingTool( const KDataToolInfo &, const QString& );
+
+ void showError( const QString package, const int num);
+
+ void updateCurrent();
+
+ /**
+ * An update for more than one file has become necessary. For instance
+ * after 'cvs commit' or 'svn commit' the file contents have not changed
+ * but the CVS/SVN file status could have changed.
+ */
+ void updateFiles( const QStringList& files );
+
+ /**
+ * Returns the list of all currently selected files. If current selection is dir,
+ * it returns list of all its children.
+ */
+ QStringList current();
+ /**
+ * Returns the list of all currently marked files.
+ */
+ QStringList marked();
+
+signals:
+ void openFile(QString filename,QString package);
+ void openFileInNewWindow(QString filename,QString package);
+ void openTemplate(QString openFilename,QString saveFileName,QString package);
+ void openTemplateInNewWindow(QString openFilename,QString saveFileName,QString package);
+ void gotoFileEntry(QString filename,QString package,int msgid);
+ void prepareProgressBar(QString msg,int max);
+ void progress(int);
+ void clearProgressBar();
+ void prepareFindProgressBar(int max);
+ void signalBuildTree(bool done);
+ void signalSearchedFile(int count);
+
+ void newValidationFile(QString);
+ void newValidationTool(QString);
+ void setValidationProgressBar(int);
+ void advanceValidationFileProgressBar(int);
+ void setMaxValidationProgressBar(int);
+ void setMaxValidationFileProgressBar(int);
+
+ /**
+ * The selected item in the tree view has changed.
+ * This signal emits the corresponding action value for this item.
+ * @param actionValue Action value for the selected item.
+ */
+ void selectedChanged(uint actionValue);
+
+signals:
+ void updateFinished();
+
+protected:
+ /**
+ * builds the tree under dir relDir, but does not update any files
+ * this functions always traverses all subdirs
+ *
+ * @param relDir the relative dir under the po- and pot- base directories
+ * @param fast if true, no files will be updated
+ *
+ * @return true, if the directory contains any po or pot-files
+ * @see CatalogManagerView::buildDir
+ * @see CatalogManagerView::updateDir
+ */
+ bool buildDir(QString relDir,bool fast=true);
+
+ /**
+ * This function is traversing the real directory on the
+ * disc using baseDir as the
+ * base directory and starts at baseDir+relDir
+ * @param extension the extension of the files in this directory
+ * @param fast if true, no file will be updated
+ *
+ * @return true, if the directory contains any po or pot-files
+ * @see CatalogManagerView::buildDir
+ * @see CatalogManagerView::updateDir
+ */
+ bool buildDir(const QString& baseDir,const QString& relDir, const QString extension,bool fast=true);
+
+ /**
+ * updates dir relDir and if any new subdir is added
+ * builds this with @ref buildDir
+ *
+ * This function doesn't enters subdirs except when a new subdir is added.
+ * @see CatalogManagerView::buildDir
+ */
+ void updateDir(QString relDir);
+
+ /**
+ * stops the update timer and the dirwatch
+ * @see KDirWatch::stop
+ * @see QTimer::stop
+ */
+ virtual void hideEvent(QHideEvent*);
+ /**
+ * restarts the update timer and the dirwatch
+ * @see KDirWatch::start
+ * @see QTimer::start
+ */
+ virtual void showEvent(QShowEvent*);
+
+ /** used for dragging */
+ virtual void contentsMousePressEvent(QMouseEvent* e);
+ /** used for dragging */
+ virtual void contentsMouseMoveEvent(QMouseEvent* e);
+
+ void showStatistics( CatManListItem *i, QStringList &packages);
+
+protected slots:
+ /** rebuilds the tree*/
+ void buildTree();
+ /**
+ * recurse all visible files and updates them if necessary
+ * @see CatManListItem::checkUpdate
+ */
+ void checkUpdate();
+
+ /** this is called from KDirWatch when a directory has changed */
+ void directoryChanged(const QString& dir);
+ /** this is called from KDirWatch when a directory has been deleted */
+ void directoryDeleted(const QString& dir);
+
+ void showContentsMenu(QListViewItem *, const QPoint &, int col);
+ /** does the default action on the currently selected item*/
+ void activateItem(QListViewItem *);
+ /** emits the state of the selected item using selectedChanged*/
+ void checkSelected();
+ /** calls @ref activateItem with the selected item as argument*/
+ void slotOpenFile();
+ void slotOpenFileInNewWindow();
+ /** emits signal @ref openTemplate */
+ void slotOpenTemplate();
+ /** deletes the po-file on the disc, that belongs to the selected item */
+ void slotDeleteFile();
+ /** toggles the mark of the selected item */
+ void slotToggleMark();
+ /**
+ * toggles all marks in directory of current item (must be a directory)
+ */
+ void slotToggleMarksInDir();
+ void slotDirCommand(int);
+ void slotFileCommand(int);
+
+private slots:
+ void showOutput(KProcess *proc, char *buffer, int buflen);
+ void processEnded(KProcess *proc);
+ void columnClicked(QListViewItem * item, const QPoint & pnt, int c);
+
+ void slotToggleCVSOrSVNColumn( bool );
+
+ void slotValidPOCVSRepository( bool );
+ void slotValidPOSVNRepository( bool );
+ void slotValidPOTCVSRepository( bool );
+ void slotValidPOTSVNRepository( bool );
+
+private:
+ void toggleColumn( uint id, bool show);
+
+ void readMarker(KConfig *config);
+ void saveMarker(KConfig *config) const;
+ /**
+ * remove marked entries, which are not in the current file list
+ */
+ void updateMarkerList();
+
+ /**
+ * Mark or unmark entries.
+ *
+ * @param mark If true the items are marked, if false the marks are removed.
+ */
+ void setPatternMarks(bool mark);
+
+ /**
+ * deletes item with package name (relative directory) relDir
+ * and makes sure, that all subitems are removed from the lists
+ */
+ void deleteDirItem(QString relDir);
+
+ bool hasMatchingWords( QStringList &itemWords, QStringList &searchWords);
+
+ CatManListItem *itemBelow( CatManListItem *item );
+ CatManListItem *itemAbove( CatManListItem *item );
+
+ void validate_internal( const QStringList&, const KDataToolInfo &, const QString& );
+
+ void doCVSCommand( CVS::Command cmd, bool marked = false, bool templates = false );
+ void doSVNCommand( SVN::Command cmd, bool marked = false, bool templates = false );
+
+private:
+ QDict<CatManListItem> _dirList;
+ QDict<CatManListItem> _fileList;
+
+ KDirWatch *_dirWatch;
+ QTimer *_updateTimer;
+
+ // list of files for which was calculated the progress bar for reading file info
+ QStringList _readInfoFileList;
+ // current count of already read files in @ref @_readInfoFileList.
+ int _readInfoCount;
+
+ KBabel::CatManSettings _settings;
+
+ QStringList _markerList;
+
+ bool _active;
+ // stopping, application quit
+ bool _stop;
+ // stop searching, do not proceed to the next file
+ bool _stopSearch;
+ int _updateNesting;
+
+ QPtrList<KProcess> _pendingProcesses;
+
+ QTextEdit* _logView;
+ KDialogBase* _logWindow;
+ QPopupMenu* _fileContentsMenu;
+ QPopupMenu* _dirContentsMenu;
+ QPopupMenu* _dirCommandsMenu;
+ QPopupMenu* _fileCommandsMenu;
+
+ /** used for starting a drag */
+ QPoint _pressPos;
+
+ KBabelDictBox* _dictBox;
+
+ KBabel::KBabelMailer* mailer;
+
+ CVSHandler* cvshandler;
+ SVNHandler* svnhandler;
+
+ /// Is the PO path a valid CVS repository?
+ bool m_validPOCVSRepository;
+ /// Is the POT path a valid CVS repository?
+ bool m_validPOTCVSRepository;
+ /// Is the PO path a valid SVN repository?
+ bool m_validPOSVNRepository;
+ /// Is the POT path a valid SVN repository?
+ bool m_validPOTSVNRepository;
+
+ MarkPatternDialog * markPatternDialog;
+
+ //validation
+ ValidateProgressDialog* _validateDialog;
+ ValidationOptions* _validateOptions;
+ KDialogBase* _validateOptionsDlg;
+ bool _markAsFuzzy;
+ bool _ignoreFuzzy;
+
+ KBabel::Project::Ptr _project;
+};
+
+#endif // CATALOGMANAGERVIEW_H
diff --git a/kbabel/catalogmanager/catmanlistitem.cpp b/kbabel/catalogmanager/catmanlistitem.cpp
new file mode 100644
index 00000000..249cb053
--- /dev/null
+++ b/kbabel/catalogmanager/catmanlistitem.cpp
@@ -0,0 +1,932 @@
+/* ****************************************************************************
+ 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.
+
+**************************************************************************** */
+
+#include "catmanresource.h"
+#include "catmanlistitem.h"
+#include "catalogmanagerview.h"
+#include "catalog.h"
+
+#include "resources.h"
+
+#include <klocale.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qbitmap.h>
+#include <qlabel.h>
+#include <qpainter.h>
+
+#include <cvshandler.h>
+#include <svnhandler.h>
+
+using namespace KBabel;
+
+CatManListItem::CatManListItem(CatalogManagerView *view, QListViewItem* parent,QString fullPath,QString fullPotPath,QString package)
+ : QListViewItem(parent)
+{
+ _view = view;
+ init(fullPath,fullPotPath,package);
+}
+
+CatManListItem::CatManListItem(CatalogManagerView *view, QListView* parent,QString fullPath,QString fullPotPath)
+ : QListViewItem(parent)
+{
+ _primary=QFileInfo(fullPath);
+ _template=QFileInfo(fullPotPath);
+ _package="/";
+ _type=Dir;
+ _marked=false;
+ _view = view;
+
+ _hasPo=false;
+ _hasPot=false;
+ _hasErrors=false;
+
+ _primary.setCaching(false);
+ _template.setCaching(false);
+
+ setText(COL_NAME,i18n("Message Catalogs"));
+ setPixmap(COL_NAME,ICON_FOLDER_CLOSED_OK);
+}
+
+
+void CatManListItem::init(const QString& fullPath, const QString& fullPotPath, const QString& package)
+{
+ _primary=QFileInfo(fullPath);
+ _template=QFileInfo(fullPotPath);
+ _package=package;
+ _marked=false;
+
+ _hasPo=false;
+ _hasPot=false;
+ _hasErrors=false;
+
+ _primary.setCaching(false);
+ _template.setCaching(false);
+
+ // set
+ _lastUpdated=QDate(1900,1,1);
+
+ _wordList.clear();
+ _wordListUpdated = false;
+
+ update(parent()->isOpen(),false,true);
+
+ if( !isDir() ) setPixmap(COL_MARKER,ICON_NOFLAG);
+}
+
+void CatManListItem::setMarked(bool on)
+{
+ if(on)
+ {
+ setPixmap(COL_MARKER,ICON_FLAG);
+ }
+ else
+ {
+ setPixmap(COL_MARKER,ICON_NOFLAG);
+ }
+
+ _marked=on;
+}
+
+bool CatManListItem::marked() const
+{
+ if( isFile() ) return _marked;
+ else if( isDir() )
+ {
+ CatManListItem * myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ if(myChild->isFile() && myChild->marked() ) return true;
+ else if(myChild->isDir() && myChild->marked() ) return true;
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+
+ }
+ return false;
+}
+
+void CatManListItem::setOpen(bool open)
+{
+ bool needWork = needsWork();
+ QListViewItem::setOpen(open);
+
+ if(open && _type==Dir)
+ {
+ QPixmap icon;
+ icon = needWork ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK;
+
+ if(!_template.exists())
+ {
+ icon=paintExclamation(&icon);
+ }
+
+ setPixmap(COL_NAME,icon);
+
+ CatManListItem * myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ myChild->checkUpdate();
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+ }
+ else
+ {
+ QPixmap icon;
+
+ if(needsWork())
+ icon = ICON_FOLDER_CLOSED_WORK;
+ else
+ icon = ICON_FOLDER_CLOSED_OK;
+
+ if(!_template.exists())
+ {
+ icon=paintExclamation(&icon);
+ }
+
+ setPixmap(COL_NAME,icon);
+ }
+
+}
+
+QStringList CatManListItem::allChildrenList(bool onlyFiles) const
+{
+ QStringList childrenList;
+
+ CatManListItem * myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ QString name=myChild->package();
+
+ if(myChild->isFile())
+ {
+ childrenList.append(name);
+ }
+ else if(myChild->isDir())
+ {
+ if(!onlyFiles)
+ childrenList.append(name);
+
+ childrenList+=myChild->allChildrenList(onlyFiles);
+ }
+
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+
+ return childrenList;
+}
+
+
+QStringList CatManListItem::allChildrenFileList(bool onlyFiles, bool emptyDirs, bool onlyModified) const
+{
+ QStringList childrenList;
+
+ CatManListItem * myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ if(myChild->isFile() && myChild->hasPo() &&
+ !(!myChild->isModified() && onlyModified))
+ {
+ childrenList.append(myChild->poFile());
+ }
+ else if(myChild->isDir())
+ {
+ if(!onlyFiles && (emptyDirs || myChild->_primary.exists() ))
+ {
+ childrenList.append(myChild->poFile());
+ }
+
+ childrenList+=myChild->allChildrenFileList(onlyFiles,false,onlyModified);
+ }
+
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+
+ return childrenList;
+}
+
+
+QStringList CatManListItem::contentsList(bool onlyFiles) const
+{
+ QStringList childList;
+
+ CatManListItem * myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ QString name=myChild->package();
+
+ if(onlyFiles)
+ {
+ if(myChild->isFile())
+ {
+ childList.append(name);
+ }
+ }
+ else
+ {
+ childList.append(name);
+ }
+
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+
+ return childList;
+}
+
+
+void CatManListItem::forceUpdate()
+{
+ update(true,true,false);
+}
+
+void CatManListItem::checkUpdate(bool noParents)
+{
+ // if a file has disappeared or is new
+ if(_hasPo != hasPo() || _hasPot != hasPot())
+ {
+ update(true,false,noParents);
+ }
+ else if(!isFile())
+ {
+ update(true,false,noParents);
+ }
+ else if(_hasPo && _lastUpdated < _primary.lastModified())
+ {
+ update(true,false,noParents);
+ }
+ else if(_hasPot && _lastUpdated < _template.lastModified())
+ {
+ update(true,false,noParents);
+ }
+}
+
+QString CatManListItem::key(int col, bool) const
+{
+ // show directories first
+ QString key=text(col);
+
+ if(col==COL_NAME)
+ {
+ if(_type==Dir)
+ {
+ key="a"+key;
+ }
+ else
+ {
+ key="b"+key;
+ }
+ }
+ // fuzzy, untranslated, total
+ else if(col==COL_FUZZY || col ==COL_TOTAL || col==COL_UNTRANS)
+ {
+ key=key.rightJustify(10,'0');
+ }
+ // marked po's
+ else if(col==COL_MARKER)
+ {
+ if(_marked)
+ {
+ key="1";
+ }
+ else
+ {
+ key="0";
+ }
+ }
+
+ return key;
+}
+
+void CatManListItem::update(bool showPoInfo,bool includeChildren
+ , bool noParents)
+{
+ if( _view->isStopped() ) return; // if parent view is stopped, we should stop as well
+
+ bool updateWordList = _view->settings().indexWords;
+
+ // flag, if something has changed and parent has to be updated
+ bool updateParent=false;
+
+ // update flags for files...
+ const bool hadPo=_hasPo;
+ _hasPo = hasPo();
+ const bool hadPot = _hasPot;
+ _hasPot = hasPot();
+
+ // and check if something changed
+ if(hadPo != _hasPo || hadPot != _hasPot)
+ updateParent=true;
+
+
+ if(_package!="/") // don't update root item
+ {
+ if(_primary.exists())
+ {
+ if(_primary.isDir())
+ {
+ QDir dir=_primary.dir();
+ setText(COL_NAME,dir.dirName());
+
+ // count the childen numbers
+ int fuzzy = 0;
+ int untrans = 0;
+ int total = 0;
+
+ CatManListItem* ch = static_cast<CatManListItem*>(firstChild ());
+
+ while (ch)
+ {
+ fuzzy += ch->fuzzy ();
+ untrans += ch->untranslated ();
+ total += ch->total ();
+ ch = static_cast<CatManListItem*>(ch->nextSibling());
+ }
+
+ setText(COL_FUZZY,QString::number(fuzzy));
+ setText(COL_UNTRANS,QString::number(untrans));
+ setText(COL_TOTAL,QString::number(total));
+
+ //setSelectable(false);
+ _type=Dir;
+
+ bool needWork = needsWork();
+ QPixmap icon;
+ if(!isOpen())
+ {
+ if( needWork )
+ icon = ICON_FOLDER_CLOSED_WORK;
+ else
+ icon = ICON_FOLDER_CLOSED_OK;
+ }
+ else
+ {
+ icon = needWork ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK;
+ }
+
+ // check if the same directory exists also in the
+ // template directory
+ if(_template.isDir())
+ {
+ setPixmap( COL_NAME, icon );
+ }
+ else
+ {
+ QPixmap folder = icon;
+ icon=paintExclamation(&folder);
+
+ setPixmap(COL_NAME,folder);
+ }
+ }
+ else // primary is file
+ {
+ _type=File;
+ QString name=_primary.fileName();
+ setText(COL_NAME,name.left(name.length()-3));
+
+ if(showPoInfo)
+ {
+ _lastUpdated=QDateTime::currentDateTime();
+
+ bool neededWork=needsWork();
+ bool needWork=false;
+
+ PoInfo poInfo;
+ QPixmap icon = ICON_UPDATING;
+ setPixmap(COL_NAME,icon);
+ if ( PoInfo::info( _primary.absFilePath(), poInfo, _wordList, updateWordList, true, true ) == OK )
+ {
+ if( _view->isStopped() ) return;
+ if( updateWordList) _wordListUpdated = true;
+
+ _hasErrors=false;
+
+ const CVSHandler* cvsHandler = _view->cvsHandler();
+ const SVNHandler* svnHandler = _view->svnHandler();
+
+ const CVSHandler::FileStatus cvsFileStatus = cvsHandler->fstatus( poFile() );
+ const SVNHandler::FileStatus svnFileStatus = svnHandler->fstatus( poFile() );
+
+ _isModified = cvsHandler->isConsideredModified( cvsFileStatus )
+ || svnHandler->isConsideredModified( svnFileStatus );
+
+ QString versionControl;
+ if ( cvsFileStatus != CVSHandler::NO_REPOSITORY )
+ versionControl = cvsHandler->fileStatus( cvsFileStatus );
+ else if ( svnFileStatus != SVNHandler::NO_REPOSITORY )
+ versionControl = svnHandler->fileStatus( svnFileStatus );
+ else
+ versionControl = i18n("No version control");
+
+ setText(COL_FUZZY,QString::number(poInfo.fuzzy));
+ setText(COL_UNTRANS,QString::number(poInfo.untranslated));
+ setText(COL_TOTAL,QString::number(poInfo.total));
+ setText( COL_CVS_OR_SVN, versionControl );
+ setText(COL_REVISION,poInfo.revision);
+ setText(COL_TRANSLATOR,poInfo.lastTranslator);
+
+ if(needsWork())
+ {
+ icon=ICON_NEEDWORK;
+ needWork = true;
+ }
+ else
+ {
+ icon = ICON_OK;
+ needWork=false;
+ }
+ }
+ else
+ {
+ kdDebug(KBABEL_CATMAN) << "This file is broken" << endl;
+ if( _view->isStopped() ) return;
+ _hasErrors=true;
+ icon = ICON_BROKEN;
+ needWork=true;
+ }
+
+ if(!_template.exists())
+ {
+ icon=paintExclamation(&icon);
+ }
+
+ setPixmap(COL_NAME,icon);
+
+ updateParent=true;
+ }
+ }
+ }
+ // only the template exists
+ else if(_template.exists())
+ {
+ if(_template.isDir())
+ {
+ QDir dir=_template.dir();
+ setText(COL_NAME,dir.dirName());
+ //setSelectable(false);
+ _type=Dir;
+
+ // count the childen numbers
+ int total = 0;
+
+ CatManListItem* ch = static_cast<CatManListItem*>(firstChild ());
+
+ while (ch)
+ {
+ total += ch->total ();
+ ch = static_cast<CatManListItem*>(ch->nextSibling());
+ }
+
+ setText(COL_TOTAL,QString::number(total));
+
+
+ QPixmap icon;
+ if(!isOpen())
+ {
+ icon = ICON_FOLDER_CLOSED_WORK;
+ }
+ else
+ {
+ icon = needsWork() ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK;
+ }
+
+ setPixmap(COL_NAME, icon );
+ }
+ // item is file
+ else
+ {
+ _type=File;
+ QString name=_primary.fileName();
+ setText(COL_NAME,name.left(name.length()-3));
+
+ if(showPoInfo)
+ {
+ _lastUpdated=QDateTime::currentDateTime();
+
+ // clean previous state information
+ setText(COL_FUZZY,QString::null);
+ setText(COL_UNTRANS,QString::null);
+ setText(COL_TOTAL,QString::null);
+ setText(COL_CVS_OR_SVN, QString::null);
+ setText(COL_REVISION, QString::null);
+ setText(COL_TRANSLATOR, QString::null);
+
+ setPixmap(COL_NAME,ICON_UPDATING);
+
+ PoInfo poInfo;
+ if ( PoInfo::info( _template.absFilePath(), poInfo, _wordList, false, true, true ) == OK )
+ {
+ if( _view->isStopped() ) return;
+ setText(COL_TOTAL,QString::number(poInfo.total));
+ }
+ if( _view->isStopped() ) return;
+ }
+ setPixmap(COL_NAME,ICON_MISSING);
+
+ updateParent = true;
+ }
+ }
+ else
+ {
+ kdWarning(KBABEL_CATMAN) << "whether po nor pot exists: " << _package << endl;
+ }
+ }
+
+ _view->fileInfoRead( package() );
+
+ if( _view->isStopped() ) return;
+
+ if(updateParent && !noParents)
+ {
+ updateParents();
+ }
+
+ if( _view->isStopped() ) return;
+
+ if(includeChildren)
+ {
+ CatManListItem *myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ myChild->update(showPoInfo,includeChildren);
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+ }
+
+ // HACK to get the signal emitted
+ if (isSelected( )) {
+ listView( )->setSelected(this, false);
+ listView( )->setSelected(this, true);
+ }
+}
+
+// we know that this item was saved and PoInfo contains new information
+// about this item, the item is file
+// however, is can be saved template or translation!!! - only translation is handled???
+void CatManListItem::updateAfterSave( PoInfo &poInfo )
+{
+ // flag, if something has changed and parent has to be updated
+ bool updateParent=false;
+
+ // update flags for files...
+ const bool hadPo=_hasPo;
+ _hasPo = hasPo();
+ const bool hadPot = _hasPot;
+ _hasPot = hasPot();
+
+ // and check if something changed
+ if(hadPo != _hasPo || hadPot != _hasPot)
+ updateParent=true;
+
+ if(_primary.exists())
+ {
+ // primary is existent file
+
+ _type=File;
+ QString name=_primary.fileName();
+ setText(COL_NAME,name.left(name.length()-3));
+
+ _lastUpdated=QDateTime::currentDateTime();
+
+ bool neededWork=needsWork();
+ bool needWork=false;
+
+ QPixmap icon;
+ _hasErrors=false;
+
+ const CVSHandler::FileStatus cvsFileStatus = _view->cvsHandler()->fstatus(poFile());
+ const SVNHandler::FileStatus svnFileStatus = _view->svnHandler()->fstatus(poFile());
+
+ QString versionControl;
+ if ( cvsFileStatus != CVSHandler::NO_REPOSITORY )
+ versionControl = _view->cvsHandler()->fileStatus( cvsFileStatus );
+ else if ( svnFileStatus != SVNHandler::NO_REPOSITORY )
+ versionControl = _view->svnHandler()->fileStatus( svnFileStatus );
+ else
+ versionControl = i18n("No version control");
+
+ setText(COL_FUZZY,QString::number(poInfo.fuzzy));
+ setText(COL_UNTRANS,QString::number(poInfo.untranslated));
+ setText(COL_TOTAL,QString::number(poInfo.total));
+ setText( COL_CVS_OR_SVN, versionControl );
+ setText(COL_REVISION,poInfo.revision);
+ setText(COL_TRANSLATOR,poInfo.lastTranslator);
+
+ if(needsWork())
+ {
+ icon=ICON_NEEDWORK;
+ needWork = true;
+ }
+ else
+ {
+ icon = ICON_OK;
+ needWork=false;
+ }
+
+ if(!_template.exists())
+ {
+ icon=paintExclamation(&icon);
+ }
+
+ setPixmap(COL_NAME,icon);
+
+ // if the status changed, update the parent item
+ if(needWork != neededWork)
+ {
+ updateParent=true;
+ }
+ }
+
+ if(updateParent)
+ {
+ updateParents();
+ }
+}
+
+
+void CatManListItem::updateParents()
+{
+ CatManListItem *item = (CatManListItem*)parent();
+ while( item && !_view->isStopped())
+ {
+ item->update(false,false);
+ item = (CatManListItem*)item->parent();
+ }
+}
+
+bool CatManListItem::hasPo() const
+{
+ return _primary.exists();
+}
+
+bool CatManListItem::hasPot() const
+{
+ return _template.exists();
+}
+
+bool CatManListItem::isModified() const
+{
+ return _isModified;
+}
+
+int CatManListItem::fuzzy() const
+{
+ bool success;
+ int number=text(COL_FUZZY).toInt(&success);
+ if(!success)
+ number=0;
+
+ return number;
+}
+
+int CatManListItem::untranslated() const
+{
+ bool success;
+ int number;
+ if( !hasPo() )
+ {
+ number=total();
+ }
+ else
+ {
+ number=text(COL_UNTRANS).toInt(&success);
+ if(!success)
+ number=0;
+ }
+
+ return number;
+}
+
+int CatManListItem::total() const
+{
+ bool success;
+ int number=text(COL_TOTAL).toInt(&success);
+ if(!success)
+ number=0;
+
+ return number;
+}
+
+bool CatManListItem::needsWork() const
+{
+ bool flag=false;
+
+ if(isFile())
+ {
+ if(!hasPo() || fuzzy() > 0 || untranslated() > 0 || _hasErrors)
+ flag=true;
+ }
+ else
+ {
+ CatManListItem *myChild = (CatManListItem*)firstChild();
+ while( myChild )
+ {
+ if( myChild->needsWork() )
+ {
+ flag=true;
+ myChild=0;
+ }
+ else
+ {
+ myChild = (CatManListItem*)myChild->nextSibling();
+ }
+ }
+ }
+
+ return flag;
+}
+
+bool CatManListItem::isDir() const
+{
+ return type()==Dir;
+}
+
+bool CatManListItem::isFile() const
+{
+ return type()==File;
+}
+
+QString CatManListItem::poFile() const
+{
+ return _primary.absFilePath();
+}
+
+QString CatManListItem::potFile() const
+{
+ return _template.absFilePath();
+}
+
+QString CatManListItem::package(bool rootSlash) const
+{
+ if(rootSlash)
+ return _package;
+ else
+ {
+ return _package.right(_package.length()-1);
+ }
+}
+
+QString CatManListItem::packageDir( ) const
+{
+ return ( _type == Dir ? _package : QString::null );
+}
+
+QString CatManListItem::name() const
+{
+ int index = _package.findRev("/");
+ return _package.right(_package.length()-index-1);
+}
+
+QPixmap CatManListItem::paintExclamation(QPixmap* pixmap)
+{
+ if(!pixmap || pixmap->isNull())
+ return QPixmap(0,0);
+
+ if(_package=="/" && _template.filePath().isEmpty())
+ return *pixmap;
+
+ if(isDir() && _package == _template.filePath())
+ return *pixmap;
+
+ if(isFile() && _package+".pot" == _template.filePath())
+ return *pixmap;
+
+ int width=pixmap->width();
+ int height=pixmap->height();
+
+ int diameter=QMIN(width,height);
+
+ QBitmap mask=pixmap->createHeuristicMask();
+
+ QPainter mp(&mask);
+ mp.setPen(QPen(Qt::color1,1));
+ mp.drawEllipse(width-diameter,height-diameter,diameter,diameter);
+
+ QPixmap result(width,height);
+
+ QPainter p(&result);
+ p.drawPixmap(0,0,*pixmap);
+ p.setPen( QPen(red,1) );
+ p.drawEllipse(width-diameter,height-diameter,diameter,diameter);
+
+ result.setMask(mask);
+
+ return result;
+}
+
+QListViewItem *CatManListItem::previousSibling()
+{
+ QListViewItem * i = parent();
+ if( !i ) return i;
+ i = i->firstChild();
+ if( !i ) return i;
+ if( i == this ) return 0;
+ while( i->nextSibling()!=this ) i = i->nextSibling();
+ return i;
+}
+
+QListViewItem *CatManListItem::lastChild()
+{
+ QListViewItem * i = firstChild();
+ if( !i ) return i;
+ while( i->nextSibling() ) i = i->nextSibling();
+ return i;
+}
+
+void CatManListItem::checkErrors(KDataTool* tool, QObject* progressSignalHandler, bool ignoreFuzzy, bool markAsFuzzy)
+{
+ bool hasError=false;
+ _errors.clear();
+ Catalog* cat = new Catalog();
+
+ QObject::connect( cat, SIGNAL( signalProgress(int) ), progressSignalHandler, SIGNAL( setValidationProgressBar(int)));
+ QObject::connect( cat, SIGNAL( signalResetProgressBar(QString, int) ), progressSignalHandler, SLOT( setupFileProgressBar(QString, int)));
+
+ if( cat->openURL(KURL( poFile() )) == OK )
+ {
+ kdDebug(KBABEL_CATMAN) << "File opened succesfully" << endl;
+ if( !cat->checkUsingTool(tool,true) )
+ {
+ hasError = true;
+ } else forceUpdate(); // no error, find out the new state
+ } else {
+ kdDebug(KBABEL_CATMAN) << "File not opened !!!!!" << endl;
+ hasError=true;
+ }
+
+ if( hasError )
+ {
+ QString errortext;
+ _hasErrors = true;
+
+ DocPosition dummy;
+ IgnoreItem i;
+ i.fileURL = poFile();
+
+ if( cat->hasError(0,dummy) && (!ignoreFuzzy || !cat->isFuzzy(0)))
+ {
+ i.msgid = cat->msgid(0);
+ i.msgstr = cat->msgstr(0);
+ i.index = 0;
+ _errors.append( i );
+
+ if( markAsFuzzy ) cat->setFuzzy(0, true);
+ }
+
+ int index=0;
+ do
+ {
+ index=cat->nextError(index,dummy);
+ if( index != -1 && (!ignoreFuzzy || !cat->isFuzzy(index) ) )
+ {
+ i.msgid = cat->msgid(index);
+ i.msgstr = cat->msgstr(index);
+ i.index = index;
+ _errors.append( i );
+ if( markAsFuzzy ) cat->setFuzzy(index, true);
+ }
+ } while(index>=0);
+
+ // change icon only if there were non-ignored errors
+ if( !_errors.isEmpty() )
+ {
+ setPixmap(COL_NAME, ICON_ERROR);
+ }
+
+ // if we changed fuzzy flags, save the result
+ if( cat->isModified() ) cat->saveFile();
+ }
+
+ delete cat;
+}
diff --git a/kbabel/catalogmanager/catmanlistitem.h b/kbabel/catalogmanager/catmanlistitem.h
new file mode 100644
index 00000000..a5f41e2f
--- /dev/null
+++ b/kbabel/catalogmanager/catmanlistitem.h
@@ -0,0 +1,238 @@
+/* ****************************************************************************
+ 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 CATMANLISTITEM_H
+#define CATMANLISTITEM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qstringlist.h>
+#include <qlistview.h>
+#include <qdatetime.h>
+#include <qfileinfo.h>
+
+#include "validateprogress.h"
+
+class CatalogManagerView;
+class QPixmap;
+class KDataTool;
+
+namespace KBabel
+{
+ class PoInfo;
+}
+
+class CatManListItem : public QListViewItem
+{
+public:
+ /** the type of this item */
+ enum Type{File,Dir};
+
+ CatManListItem(CatalogManagerView *view, QListViewItem* parent,QString fullPath
+ ,QString fullPotPath,QString package);
+
+ /** creates the toplevel root item with package name "/" */
+ CatManListItem(CatalogManagerView *view, QListView* parent,QString fullPath, QString fullPotPath);
+
+ /**
+ * returns the package names (including relative path) of the
+ * children of this item
+ */
+ QStringList contentsList(bool onlyFiles=false) const;
+ /**
+ * returns the package names of all children of this item
+ * (including all subdirectries)
+ * @param onlyFiles flag, if only the names of files should be returned
+ * @see CatManListItem::contentsList
+ */
+ QStringList allChildrenList(bool onlyFiles=false) const;
+
+ /**
+ * returns the relative file names of all children of this item
+ * (including all subdirectries)
+ * @param onlyFiles flag, if only the names of files should be returned
+ * @param emptyDirs flag, if the empty dirs (dirs without PO files in them) should be returned
+ * @param onlyModified, if only modified files should be returned
+ * @see CatManListItem::contentsList
+ */
+ QStringList allChildrenFileList(bool onlyFiles=false, bool emptyDirs=false, bool onlyModified=false) const;
+
+ void setMarked(bool on);
+ bool marked() const;
+ /**
+ * checks if the file on the disc has changed,
+ * reads information about the file and displays it
+ * @param noParents flag, if the update has to include the parent
+ * of the item, if the status has changed. Since at the first build of
+ * the tree, the status of every item changes, this is not useful then.
+ */
+ void checkUpdate(bool noParents=false);
+ void forceUpdate();
+
+ /**
+ * checks the corresponding PO file using validation tool. On
+ * errors it fills the list of errors, which can be accessed
+ * using @see errors().
+ * @param validator instance of KDataTool to be used for checking
+ * @param progressSignalHangler widget, to which the checks should send progress signals
+ * @param ignoreFuzzy flag, whether fuzzy messages in the file should be not checked
+ * @param markAsFuzzy flag, whether the error messages should be marked as fuzzy (this alters the PO file)
+ */
+ void checkErrors(KDataTool* validator, QObject* progressSignalHandler, bool ignoreFuzzy, bool markAsFuzzy);
+
+ /** return the absolute filename of the po-File */
+ QString poFile() const;
+ /** return the absolute filename of the pot-File */
+ QString potFile() const;
+ /** returns the package name (inlcuding relative path to base-directory) */
+ QString package(bool rootSlash=true) const;
+
+ /** returns the relative path of a dir or QString::null if not a dir. */
+ QString packageDir( ) const;
+
+ /** returns the package name (without path) */
+ QString name() const;
+
+ /**
+ * returns the type of this item
+ * @see CatManListItem::Type
+ */
+ Type type() const{return _type;}
+ bool isDir() const;
+ bool isFile() const;
+ /** returns true, if the po-file exists*/
+ bool hasPo() const;
+ /** returns true, if the pot-file exists*/
+ bool hasPot() const;
+ bool isModified() const;
+ /**
+ * @return the number of fuzzy messages in the po-file,
+ * 0 if no po-file exists
+ */
+ int fuzzy() const;
+ /**
+ * @return the number of untranslated messages in the po-file,
+ * @ref total if no po-file exists
+ */
+ int untranslated() const;
+ /** @return number of messages in the po- or pot-file */
+ int total() const;
+ /**
+ * @return true, if there are untranslated or fuzzy items.
+ * If this item is a directory, it returns true, if a subitem
+ * contains untranslated or fuzzy items
+ */
+ bool needsWork() const;
+ /**
+ * @return true, if there were errors while parsing the file
+ */
+ bool hasErrors() const {return _hasErrors;}
+ QValueList<IgnoreItem> errors() const {return _errors;}
+
+ virtual QString key(int col,bool) const;
+ virtual void setOpen(bool);
+
+ /** paints the marking, if this package has no template */
+ QPixmap paintExclamation(QPixmap*);
+
+ void updateAfterSave( KBabel::PoInfo &po);
+
+ QStringList &wordList() { return _wordList; }
+ bool wordsUpdated() { return _wordListUpdated; }
+
+ /** These are not in Qt, so we need to implement it ourselves*/
+ QListViewItem *previousSibling();
+ QListViewItem *lastChild();
+
+private:
+ void init(const QString& fullPath, const QString& fullPotPath,const QString& package);
+ /**
+ * updates the item
+ * @param showPoInfo if true, reads information about the
+ * file using @ref Catalog::info
+ * ( slow for big files )
+ * @param includeChildren flag, if possible children should be updated,too
+ * @param noParents flag, if parents should be updated, when state
+ * of the item has changed
+ */
+ void update(bool showPoInfo=true,bool includeChildren=false
+ , bool noParents=false );
+ void updateParents();
+
+private:
+ /**
+ * holds the date and the time this item was
+ * last updated. This is used to check, if the file
+ * on the disc has changed since last update.
+ */
+ QDateTime _lastUpdated;
+
+ /** the po-file */
+ QFileInfo _primary;
+ /** the pot-file */
+ QFileInfo _template;
+ /**
+ * The package name, includes the relative path beginning
+ * at the base directory.
+ * The package name begins with "/" and if this is a directory it end with "/"
+ * The root item has the package name "/"
+ * @see CatManListItem::CatManListItem
+ */
+ QString _package;
+ Type _type;
+ bool _marked;
+
+ /** flag, to detect if file has been deleted or is new */
+ bool _hasPo;
+ /** flag, to detect if file has been deleted or is new */
+ bool _hasPot;
+
+ bool _isModified;
+ /** flag, to detect if file has been modified or new */
+
+ /** flag, if the PO-file has a syntax error */
+ bool _hasErrors;
+ /** a list of errors found by validation tool*/
+ QValueList<IgnoreItem> _errors;
+
+ /** parent view for this item, used for stopping the activity */
+ CatalogManagerView *_view;
+
+ /** index of words, but it does not contain any useful information as values */
+ QStringList _wordList;
+ bool _wordListUpdated;
+};
+
+#endif // CATMANLISTITEM_H
diff --git a/kbabel/catalogmanager/catmanresource.h b/kbabel/catalogmanager/catmanresource.h
new file mode 100644
index 00000000..06b3ac33
--- /dev/null
+++ b/kbabel/catalogmanager/catmanresource.h
@@ -0,0 +1,73 @@
+/* ****************************************************************************
+ 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 CATMANRESOURCE_H
+#define CATMANRESOURCE_H
+
+#include <kiconloader.h>
+
+#define COL_NAME 0
+#define COL_MARKER 1
+#define COL_FUZZY 2
+#define COL_UNTRANS 3
+#define COL_TOTAL 4
+#define COL_CVS_OR_SVN 5
+#define COL_REVISION 6
+#define COL_TRANSLATOR 7
+
+#define ICON_OK UserIcon("ok",KIcon::DefaultState)
+#define ICON_MISSING UserIcon("missing",KIcon::DefaultState)
+#define ICON_NEEDWORK UserIcon("needwork",KIcon::DefaultState)
+#define ICON_BROKEN UserIcon("broken",KIcon::DefaultState)
+#define ICON_UPDATING SmallIcon("reload")
+#define ICON_FLAG SmallIcon("flag")
+#define ICON_FOLDER_CLOSED_OK SmallIcon("folder_green")
+#define ICON_FOLDER_CLOSED_WORK SmallIcon("folder_red")
+#define ICON_FOLDER_OPEN_OK SmallIcon("folder_green_open")
+#define ICON_FOLDER_OPEN_WORK SmallIcon("folder_red_open")
+#define ICON_ERROR UserIcon("error",KIcon::DefaultState)
+#define ICON_NOFLAG UserIcon("noflag",KIcon::DefaultState)
+
+// Needed for determining which actions should be enabled and which not.
+#define NEEDS_PO 1
+#define NEEDS_POT 2
+#define NEEDS_MARK 4
+#define NEEDS_DIR 8
+#define NEEDS_PO_CVS 16
+#define NEEDS_POT_CVS 32
+#define NEEDS_PO_SVN 64
+#define NEEDS_POT_SVN 128
+
+#endif
diff --git a/kbabel/catalogmanager/findinfilesdialog.cpp b/kbabel/catalogmanager/findinfilesdialog.cpp
new file mode 100644
index 00000000..b11a20d8
--- /dev/null
+++ b/kbabel/catalogmanager/findinfilesdialog.cpp
@@ -0,0 +1,229 @@
+/* ****************************************************************************
+ 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 "findinfilesdialog.h"
+
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KBabel;
+
+FindInFilesDialog::FindInFilesDialog(bool forReplace, QWidget* parent)
+ :FindDialog(forReplace, parent)
+{
+ QGroupBox* box = new QGroupBox(2, Qt::Horizontal, i18n("File Options"), mainWidget());
+ mainWidget()->layout()->add(box);
+
+ _inAllFiles = new QCheckBox(i18n("&In all files"),box);
+ _inMarked = new QCheckBox(i18n("&Marked files"),box);
+ _inTemplates = new QCheckBox(i18n("In &templates"),box);
+ _askForNextFile = new QCheckBox(i18n("Ask before ne&xt file"),box);
+ _askForSave = new QCheckBox(i18n("Save &without asking"),box);
+
+ QWhatsThis::add(box,i18n("<qt><p><b>File Options</b></p>"
+ "<p>Here you can finetune where to find:"
+ "<ul><li><b>In all files</b>: search in all files, otherwise searched "
+ "is the selected file or files in the selected folder</li>"
+ "<li><b>Ask before next file</b>: show a dialog asking to proceed to the next file</li>"
+ "</ul></qt>"));
+
+ readSettings();
+}
+
+FindInFilesDialog::~FindInFilesDialog()
+{
+ saveSettings();
+}
+
+int FindInFilesDialog::show(QString initialStr)
+{
+
+ FindDialog::show(initialStr);
+
+ int r = result();
+
+ if( r == QDialog::Accepted ) {
+ if( isReplaceDialog() ) {
+ ReplaceOptions options = replaceOpts();
+ options.inAllFiles = _inAllFiles->isChecked();
+ options.inMarkedFiles = _inMarked->isChecked();
+ options.inTemplates = _inTemplates->isChecked();
+ options.askForNextFile = _askForNextFile->isChecked();
+ options.askForSave = !_askForSave->isChecked();
+ FindDialog::setReplaceOpts(options);
+ }
+ else {
+ FindOptions options = findOpts();
+ options.inAllFiles = _inAllFiles->isChecked();
+ options.inMarkedFiles = _inMarked->isChecked();
+ options.inTemplates = _inTemplates->isChecked();
+ options.askForNextFile = _askForNextFile->isChecked();
+ options.askForSave = !_askForSave->isChecked();
+ FindDialog::setFindOpts( options );
+ }
+ }
+
+ return r;
+}
+
+int FindInFilesDialog::exec(QString initialStr)
+{
+ FindDialog::exec(initialStr);
+
+ int r = result();
+
+ if( r == QDialog::Accepted ) {
+ if(isReplaceDialog()) {
+ ReplaceOptions options = replaceOpts();
+ options.inAllFiles = _inAllFiles->isChecked();
+ options.inMarkedFiles = _inMarked->isChecked();
+ options.inTemplates = _inTemplates->isChecked();
+ options.askForNextFile = _askForNextFile->isChecked();
+ options.askForSave = !_askForSave->isChecked();
+ FindDialog::setReplaceOpts(options);
+ }
+ else {
+ FindOptions options = findOpts();
+ options.inAllFiles = _inAllFiles->isChecked();
+ options.inMarkedFiles = _inMarked->isChecked();
+ options.inTemplates = _inTemplates->isChecked();
+ options.askForNextFile = _askForNextFile->isChecked();
+ options.askForSave = !_askForSave->isChecked();
+ FindDialog::setFindOpts( options );
+ }
+ }
+
+ return r;
+}
+
+void FindInFilesDialog::setFindOpts(FindOptions options)
+{
+ FindDialog::setFindOpts(options);
+
+ _inAllFiles->setChecked(options.inAllFiles);
+ _inTemplates->setChecked(options.inTemplates);
+ _inMarked->setChecked(options.inMarkedFiles);
+ _askForNextFile->setChecked(options.askForNextFile);
+ _askForSave->setChecked(!options.askForSave);
+}
+
+void FindInFilesDialog::setReplaceOpts(ReplaceOptions options)
+{
+ FindDialog::setReplaceOpts(options);
+
+ _inAllFiles->setChecked(options.inAllFiles);
+ _inTemplates->setChecked(options.inTemplates);
+ _inMarked->setChecked(options.inMarkedFiles);
+ _askForNextFile->setChecked(options.askForNextFile);
+ _askForSave->setChecked(!options.askForSave);
+}
+
+void FindInFilesDialog::readSettings()
+{
+ KConfig* config = KGlobal::config();
+
+ if(isReplaceDialog()) {
+ KConfigGroupSaver cgs(config,"ReplaceDialog");
+
+ ReplaceOptions options = replaceOpts();
+
+ options.inAllFiles = config->readBoolEntry("AllFiles", false);
+ options.inTemplates = config->readBoolEntry("InTemplates", false);
+ options.inMarkedFiles = config->readBoolEntry("InMarked", false);
+ options.askForNextFile = config->readBoolEntry("AskForNextFile", true);
+ options.askForSave = config->readBoolEntry("AskForSave", true);
+
+ _inAllFiles->setChecked(options.inAllFiles);
+ _inTemplates->setChecked(options.inTemplates);
+ _inMarked->setChecked(options.inMarkedFiles);
+ _askForNextFile->setChecked(options.askForNextFile);
+ _askForSave->setChecked(!options.askForSave);
+
+ FindDialog::setReplaceOpts(options);
+ }
+ else {
+ KConfigGroupSaver cgs(config,"FindDialog");
+
+ FindOptions options = findOpts();
+
+ options.inAllFiles = config->readBoolEntry("AllFiles", false);
+ options.inTemplates = config->readBoolEntry("InTemplates", false);
+ options.inMarkedFiles = config->readBoolEntry("InMarked", false);
+ options.askForNextFile = config->readBoolEntry("AskForNextFile", true);
+ options.askForSave = config->readBoolEntry("AskForSave", true);
+
+ _inAllFiles->setChecked(options.inAllFiles);
+ _inTemplates->setChecked(options.inTemplates);
+ _inMarked->setChecked(options.inMarkedFiles);
+ _askForNextFile->setChecked(options.askForNextFile);
+ _askForSave->setChecked(!options.askForSave);
+
+ FindDialog::setFindOpts(options);
+ }
+
+}
+
+void FindInFilesDialog::saveSettings()
+{
+ KConfig* config = KGlobal::config();
+
+ if(isReplaceDialog()) {
+ KConfigGroupSaver cgs(config,"ReplaceDialog");
+ ReplaceOptions options = replaceOpts();
+
+ config->writeEntry("AllFiles", options.inAllFiles);
+ config->writeEntry("InMarked", options.inMarkedFiles);
+ config->writeEntry("InTemplates", options.inTemplates);
+ config->writeEntry("AskForNextFile",options.askForNextFile);
+ config->writeEntry("AskForSave",options.askForSave);
+ }
+ else {
+ KConfigGroupSaver cgs(config,"FindDialog");
+
+ FindOptions options = findOpts();
+
+ config->writeEntry("AllFiles", options.inAllFiles);
+ config->writeEntry("InMarked", options.inMarkedFiles);
+ config->writeEntry("InTemplates", options.inTemplates);
+ config->writeEntry("AskForNextFile",options.askForNextFile);
+ config->writeEntry("AskForSave",options.askForSave);
+ }
+}
+
+#include "findinfilesdialog.moc"
diff --git a/kbabel/catalogmanager/findinfilesdialog.h b/kbabel/catalogmanager/findinfilesdialog.h
new file mode 100644
index 00000000..fd25f845
--- /dev/null
+++ b/kbabel/catalogmanager/findinfilesdialog.h
@@ -0,0 +1,85 @@
+/* ****************************************************************************
+ 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 FINDINFILESDIALOG_H
+#define FINDINFILESDIALOG_H
+
+#include "findoptions.h"
+#include "finddialog.h"
+
+class QCheckBox;
+
+class FindInFilesDialog : public FindDialog
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructor
+ * @param replaceDlg flag, if this is a replace dialog
+ */
+ FindInFilesDialog(bool replaceDlg, QWidget* parent);
+ ~FindInFilesDialog();
+
+ /**
+ * shows the dialog
+ * @param initialStr string to display in find field.
+ * If empty, the last used string is used.
+ *
+ * @return the result code of the dialog
+ */
+ int show(QString initialStr);
+
+ /**
+ * executes the dialog as modal
+ * @param initialStr string to display in find field.
+ * If empty, the last used string is used.
+ *
+ * @return the result code of the dialog
+ */
+ int exec(QString initialStr);
+
+ void setFindOpts(KBabel::FindOptions options);
+ void setReplaceOpts(KBabel::ReplaceOptions options);
+
+protected:
+ void readSettings();
+ void saveSettings();
+
+private:
+ QCheckBox *_inAllFiles;
+ QCheckBox *_inTemplates;
+ QCheckBox *_inMarked;
+ QCheckBox *_askForNextFile;
+ QCheckBox *_askForSave;
+};
+
+#endif // FINDDIALOG_H
diff --git a/kbabel/catalogmanager/future.cpp b/kbabel/catalogmanager/future.cpp
new file mode 100644
index 00000000..4c9c8a90
--- /dev/null
+++ b/kbabel/catalogmanager/future.cpp
@@ -0,0 +1,17 @@
+// This files holds a few user-visible messages that will be needed by the SVN support
+
+// Misc. messages already existing in the kbabel-svn branch
+i18n("SVN");
+i18n( "CVS/SVN Status" );
+
+// Messages for further SVN functions
+i18n( "Resolved" );
+i18n( "Resolved for Marked" );
+i18n( "Revert" );
+i18n( "Revert for Marked" );
+i18n( "Cleanup" );
+i18n( "Cleanup for Marked" );
+
+// Messages that will probably not be needed
+i18n( "No repository" );
+
diff --git a/kbabel/catalogmanager/hi16-app-catalogmanager.png b/kbabel/catalogmanager/hi16-app-catalogmanager.png
new file mode 100644
index 00000000..c2a3ef67
--- /dev/null
+++ b/kbabel/catalogmanager/hi16-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/hi22-app-catalogmanager.png b/kbabel/catalogmanager/hi22-app-catalogmanager.png
new file mode 100644
index 00000000..3b9dfecc
--- /dev/null
+++ b/kbabel/catalogmanager/hi22-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/hi32-app-catalogmanager.png b/kbabel/catalogmanager/hi32-app-catalogmanager.png
new file mode 100644
index 00000000..3601807e
--- /dev/null
+++ b/kbabel/catalogmanager/hi32-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/hi48-app-catalogmanager.png b/kbabel/catalogmanager/hi48-app-catalogmanager.png
new file mode 100644
index 00000000..8d5090ea
--- /dev/null
+++ b/kbabel/catalogmanager/hi48-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/Makefile.am b/kbabel/catalogmanager/icons/Makefile.am
new file mode 100644
index 00000000..f6ca354f
--- /dev/null
+++ b/kbabel/catalogmanager/icons/Makefile.am
@@ -0,0 +1,5 @@
+# Add all of your pixmaps here
+icons_ICON = AUTO
+
+# This is where it will all be installed
+iconsdir = $(kde_datadir)/kbabel/icons
diff --git a/kbabel/catalogmanager/icons/hi16-action-nextmarked.png b/kbabel/catalogmanager/icons/hi16-action-nextmarked.png
new file mode 100644
index 00000000..1e71607f
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-nextmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-nextpo.png b/kbabel/catalogmanager/icons/hi16-action-nextpo.png
new file mode 100644
index 00000000..650ec8e9
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-nextpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-nexttemplate.png b/kbabel/catalogmanager/icons/hi16-action-nexttemplate.png
new file mode 100644
index 00000000..8422a3c6
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-nexttemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-prevmarked.png b/kbabel/catalogmanager/icons/hi16-action-prevmarked.png
new file mode 100644
index 00000000..880e694d
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-prevmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-prevpo.png b/kbabel/catalogmanager/icons/hi16-action-prevpo.png
new file mode 100644
index 00000000..f5e668c4
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-prevpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-prevtemplate.png b/kbabel/catalogmanager/icons/hi16-action-prevtemplate.png
new file mode 100644
index 00000000..4b799896
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-prevtemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-statistics.png b/kbabel/catalogmanager/icons/hi16-action-statistics.png
new file mode 100644
index 00000000..456be360
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi16-action-syntax.png b/kbabel/catalogmanager/icons/hi16-action-syntax.png
new file mode 100644
index 00000000..221c3b87
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi16-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-nextmarked.png b/kbabel/catalogmanager/icons/hi22-action-nextmarked.png
new file mode 100644
index 00000000..020ead66
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-nextmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-nextpo.png b/kbabel/catalogmanager/icons/hi22-action-nextpo.png
new file mode 100644
index 00000000..8579fefd
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-nextpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-nexttemplate.png b/kbabel/catalogmanager/icons/hi22-action-nexttemplate.png
new file mode 100644
index 00000000..064ab5bd
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-nexttemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-prevmarked.png b/kbabel/catalogmanager/icons/hi22-action-prevmarked.png
new file mode 100644
index 00000000..38113a73
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-prevmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-prevpo.png b/kbabel/catalogmanager/icons/hi22-action-prevpo.png
new file mode 100644
index 00000000..883ca21a
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-prevpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-prevtemplate.png b/kbabel/catalogmanager/icons/hi22-action-prevtemplate.png
new file mode 100644
index 00000000..0def2356
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-prevtemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-statistics.png b/kbabel/catalogmanager/icons/hi22-action-statistics.png
new file mode 100644
index 00000000..aff3294f
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi22-action-syntax.png b/kbabel/catalogmanager/icons/hi22-action-syntax.png
new file mode 100644
index 00000000..d0c7decc
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi22-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-nextmarked.png b/kbabel/catalogmanager/icons/hi32-action-nextmarked.png
new file mode 100644
index 00000000..32cd2f48
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-nextmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-nextpo.png b/kbabel/catalogmanager/icons/hi32-action-nextpo.png
new file mode 100644
index 00000000..2320ecf8
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-nextpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-nexttemplate.png b/kbabel/catalogmanager/icons/hi32-action-nexttemplate.png
new file mode 100644
index 00000000..be6e8c04
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-nexttemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-prevmarked.png b/kbabel/catalogmanager/icons/hi32-action-prevmarked.png
new file mode 100644
index 00000000..b9c85a05
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-prevmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-prevpo.png b/kbabel/catalogmanager/icons/hi32-action-prevpo.png
new file mode 100644
index 00000000..28d31e80
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-prevpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-prevtemplate.png b/kbabel/catalogmanager/icons/hi32-action-prevtemplate.png
new file mode 100644
index 00000000..0f9e9c0c
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-prevtemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-statistics.png b/kbabel/catalogmanager/icons/hi32-action-statistics.png
new file mode 100644
index 00000000..5f428a65
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/hi32-action-syntax.png b/kbabel/catalogmanager/icons/hi32-action-syntax.png
new file mode 100644
index 00000000..0be5c2db
--- /dev/null
+++ b/kbabel/catalogmanager/icons/hi32-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-nextmarked.png b/kbabel/catalogmanager/icons/lo16-action-nextmarked.png
new file mode 100644
index 00000000..fdbb9664
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-nextmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-nextpo.png b/kbabel/catalogmanager/icons/lo16-action-nextpo.png
new file mode 100644
index 00000000..b9d0ce11
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-nextpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-nexttemplate.png b/kbabel/catalogmanager/icons/lo16-action-nexttemplate.png
new file mode 100644
index 00000000..979ba277
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-nexttemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-prevmarked.png b/kbabel/catalogmanager/icons/lo16-action-prevmarked.png
new file mode 100644
index 00000000..b712b63c
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-prevmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-prevpo.png b/kbabel/catalogmanager/icons/lo16-action-prevpo.png
new file mode 100644
index 00000000..3736c141
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-prevpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-prevtemplate.png b/kbabel/catalogmanager/icons/lo16-action-prevtemplate.png
new file mode 100644
index 00000000..62b3746d
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-prevtemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-statistics.png b/kbabel/catalogmanager/icons/lo16-action-statistics.png
new file mode 100644
index 00000000..1c298a5b
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo16-action-syntax.png b/kbabel/catalogmanager/icons/lo16-action-syntax.png
new file mode 100644
index 00000000..79fea79a
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo16-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo22-action-statistics.png b/kbabel/catalogmanager/icons/lo22-action-statistics.png
new file mode 100644
index 00000000..00ee1475
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo22-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo22-action-syntax.png b/kbabel/catalogmanager/icons/lo22-action-syntax.png
new file mode 100644
index 00000000..801b8cc4
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo22-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-nextmarked.png b/kbabel/catalogmanager/icons/lo32-action-nextmarked.png
new file mode 100644
index 00000000..ded540c2
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-nextmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-nextpo.png b/kbabel/catalogmanager/icons/lo32-action-nextpo.png
new file mode 100644
index 00000000..e0fcc825
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-nextpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-nexttemplate.png b/kbabel/catalogmanager/icons/lo32-action-nexttemplate.png
new file mode 100644
index 00000000..da024779
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-nexttemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-prevmarked.png b/kbabel/catalogmanager/icons/lo32-action-prevmarked.png
new file mode 100644
index 00000000..942587eb
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-prevmarked.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-prevpo.png b/kbabel/catalogmanager/icons/lo32-action-prevpo.png
new file mode 100644
index 00000000..55cb73a3
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-prevpo.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-prevtemplate.png b/kbabel/catalogmanager/icons/lo32-action-prevtemplate.png
new file mode 100644
index 00000000..eb485afc
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-prevtemplate.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-statistics.png b/kbabel/catalogmanager/icons/lo32-action-statistics.png
new file mode 100644
index 00000000..298e4577
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-statistics.png
Binary files differ
diff --git a/kbabel/catalogmanager/icons/lo32-action-syntax.png b/kbabel/catalogmanager/icons/lo32-action-syntax.png
new file mode 100644
index 00000000..4292ffaf
--- /dev/null
+++ b/kbabel/catalogmanager/icons/lo32-action-syntax.png
Binary files differ
diff --git a/kbabel/catalogmanager/libcvs/Makefile.am b/kbabel/catalogmanager/libcvs/Makefile.am
new file mode 100644
index 00000000..e3e4f9ac
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libcatalogmanagercvs.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I.. -I../../common $(all_includes)
+
+libcatalogmanagercvs_la_SOURCES = cvshandler.cpp cvsdialog.cpp
+
+noinst_HEADERS = cvshandler.h cvsdialog.h cvsresources.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
diff --git a/kbabel/catalogmanager/libcvs/cvsdialog.cpp b/kbabel/catalogmanager/libcvs/cvsdialog.cpp
new file mode 100644
index 00000000..af76d9d0
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/cvsdialog.cpp
@@ -0,0 +1,423 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+// Qt include files
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qfileinfo.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtextedit.h>
+#include <qtextcodec.h>
+// KDE include files
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <ktempfile.h>
+#include <kmessagebox.h>
+#include <kstringhandler.h>
+#include <kcombobox.h>
+#include <kcharsets.h>
+// Project specific include files
+#include "cvsdialog.h"
+
+
+CVSDialog::CVSDialog( CVS::Command cmd, QWidget * parent, KSharedConfig* config )
+ : KDialog( parent, "CVSDIALOG", true ), m_config( config )
+{
+ _cmd = cmd;
+ p=0L;
+ setCaption( i18n( "CVS Dialog" ) );
+
+ QString temp;
+
+ QVBoxLayout * layout = new QVBoxLayout( this, 6, 6, "MAIN LAYOUT" );
+
+ // Set the label's text depending on the CVS command.
+ switch ( cmd ) {
+ case CVS::Update:
+ temp = i18n( "Update the following files:" );
+ break;
+ case CVS::Commit:
+ temp = i18n( "Commit the following files:" );
+ break;
+ case CVS::Status:
+ temp = i18n( "Get status for the following files:" );
+ break;
+ case CVS::Diff:
+ temp = i18n( "Get diff for the following files:" );
+ break;
+ }
+ layout->addWidget( new QLabel( temp, this ) );
+
+ // Widget for showing the list of files.
+ filebox = new QListBox( this );
+ layout->addWidget( filebox );
+
+ // Add special widgets for 'cvs commit'.
+ if ( cmd == CVS::Commit ) {
+ QLabel * label;
+
+ // Combobox for displaying old log messages.
+ label = new QLabel( i18n( "&Old messages:" ), this );
+ oldMessages = new QComboBox( this );
+ oldMessages->setDuplicatesEnabled( false );
+ label->setBuddy( oldMessages );
+ layout->addWidget( label );
+ layout->addWidget( oldMessages );
+
+ // Textfield for entering a log message.
+ label = new QLabel( i18n( "&Log message:" ), this );
+ logedit = new QTextEdit( this );
+ label->setBuddy( logedit );
+ layout->addWidget( label );
+ layout->addWidget( logedit );
+
+ label = new QLabel( i18n( "E&ncoding:" ), this );
+ m_encodingComboBox = new KComboBox( this );
+ label->setBuddy( m_encodingComboBox );
+ layout->addWidget( label );
+ layout->addWidget( m_encodingComboBox );
+ QStringList encodingList;
+ // The last encoding will be added at the top of the list, when the seetings will be read.
+ encodingList << i18n( "Descriptive encoding name", "Recommended ( %1 )" ).arg( "UTF-8" );
+ encodingList << i18n( "Descriptive encoding name", "Locale ( %1 )" ).arg( QTextCodec::codecForLocale()->mimeName() );
+ encodingList += KGlobal::charsets()->descriptiveEncodingNames();
+ m_encodingComboBox->insertStringList( encodingList );
+
+ connect( oldMessages, SIGNAL( activated( int ) ),
+ this, SLOT( slotComboActivated( int ) ) );
+ }
+
+ QHBoxLayout * buttons = new QHBoxLayout( 0, 0, 6, "BUTTON LAYOUT" );
+ // Add special buttons for 'cvs commit'.
+ if ( cmd == CVS::Commit ) {
+ autoAddBox = new QCheckBox( i18n( "Auto&matically add files if necessary" ), this );
+ buttons->addWidget( autoAddBox );
+ }
+ buttons->addItem( new QSpacerItem( 1, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+
+ // Set the main button's text depending on the CVS comand.
+ switch ( cmd ) {
+ case CVS::Update:
+ temp = i18n( "&Update" );
+ break;
+ case CVS::Commit:
+ temp = i18n( "&Commit" );
+ break;
+ case CVS::Status:
+ temp = i18n( "&Get Status" );
+ break;
+ case CVS::Diff:
+ temp = i18n( "&Get Diff" );
+ break;
+ }
+ mainBtn = new QPushButton( temp, this );
+ mainBtn->setDefault( true );
+ buttons->addWidget( mainBtn );
+
+ cancelBtn = new QPushButton( i18n( "C&ancel" ), this );
+ buttons->addWidget( cancelBtn );
+ layout->addLayout( buttons );
+
+ QFrame * line = new QFrame( this );
+ line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget( line );
+
+ layout->addWidget( new QLabel( i18n( "Command output:" ), this ) );
+
+ output = new QTextEdit( this );
+ output->setReadOnly( true );
+ layout->addWidget( output );
+
+ resize( QSize( 600, 450 ).expandedTo( minimumSizeHint( ) ) );
+
+ if ( cmd == CVS::Commit )
+ logedit->setFocus( );
+
+ readSettings( );
+
+ connect( mainBtn, SIGNAL( clicked( ) ), this, SLOT( slotExecuteCommand( ) ) );
+ connect( cancelBtn, SIGNAL( clicked( ) ), this, SLOT( reject( ) ) );
+}
+
+void CVSDialog::slotComboActivated( int index )
+{
+ if ( index < 0 || index >= m_logMessages.count() )
+ return;
+ logedit->setText( m_logMessages[index] );
+}
+
+CVSDialog::~CVSDialog()
+{
+ delete p;
+}
+
+void CVSDialog::accept( )
+{
+ saveSettings( );
+ KDialog::accept( );
+}
+
+void CVSDialog::setFiles( const QStringList& files )
+{
+ filebox->insertStringList( files );
+}
+
+void CVSDialog::setCommandLine( const QString& command )
+{
+ _commandLine = command;
+}
+
+void CVSDialog::setAddCommand( const QString& command )
+{
+ _addCommand = command;
+}
+
+void CVSDialog::slotExecuteCommand( )
+{
+ // Nothing to do here.
+ if ( _commandLine.isEmpty( ) ) return;
+
+ kdDebug() << "Preparing KProcess" << endl;
+
+ // Create a new shell process
+ p = new KProcess;
+ p->setUseShell( true, "/bin/sh" );
+
+ if ( _cmd == CVS::Commit ) {
+ // Include command for 'cvs add'.
+ if ( autoAddBox->isChecked( ) && !_addCommand.isEmpty( ) )
+ _commandLine.prepend( _addCommand );
+
+ const QString msg( logedit->text() );
+
+ if ( msg.isEmpty() )
+ {
+ // A good commit should never have an empty comment, so ask the user if he really wants it.
+ const int res = KMessageBox::warningContinueCancel( this,
+ i18n( "The commit log message is empty. Do you want to continue?" ) );
+ if ( res != KMessageBox::Continue )
+ return;
+ }
+
+ m_encoding = KGlobal::charsets()->encodingForName( m_encodingComboBox->currentText() );
+ QTextCodec* codec = QTextCodec::codecForName( m_encoding.utf8() );
+
+ if ( !codec )
+ {
+ KMessageBox::error( this, i18n( "Cannot find encoding: %1" ).arg( m_encoding ) );
+ return;
+ }
+ else if ( !codec->canEncode( msg ) )
+ {
+ const int res = KMessageBox::warningContinueCancel( this,
+ i18n( "The commit log message cannot be encoded in the selected encoding: %1.\n"
+ "Do you want to continue?" ).arg( m_encoding ) );
+ if ( res != KMessageBox::Continue )
+ return;
+ }
+
+ // Write the commit log message from the input field to a temporary file
+ m_tempFile = new KTempFile;
+ m_tempFile->setAutoDelete( true );
+ QTextStream* stream = m_tempFile->textStream();
+ if ( !stream )
+ {
+ kdError() << "Could not create QTextStream for file " << m_tempFile->name();
+ delete m_tempFile;
+ m_tempFile = 0;
+ KMessageBox::error( this, i18n( "Cannot open temporary file for writing. Aborting.") );
+ return;
+ }
+ stream->setCodec( codec );
+ *stream << msg;
+ m_tempFile->close();
+
+ if ( m_tempFile->status() )
+ {
+ kdError() << "Could not write to file " << m_tempFile->name();
+ delete m_tempFile;
+ m_tempFile = 0;
+ KMessageBox::error( this, i18n( "Cannot write to temporary file. Aborting.") );
+ return;
+ }
+
+ // Change the command line to have the real name of the temporary file
+ _commandLine.replace( "@LOG@FILE@", KProcess::quote( m_tempFile->name() ) );
+
+ // Update the list of log messages
+ if ( !msg.isEmpty() ) {
+ const QString shortLog = KStringHandler::csqueeze( msg, 80 );
+
+
+ // Remove the message from the list if it already exists
+ m_logMessages.remove( msg );
+ // Prepend the current message to the list
+ m_logMessages.prepend( msg );
+
+ // At this time of the process, we do not need the combobox anymore, so we do not squeeze the changed strings.
+ }
+ }
+
+ // Set the KProcess' command line.
+ *p << _commandLine;
+
+ connect( p, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
+ this, SLOT ( slotProcessStdout( KProcess*, char*, int ) ) );
+ connect( p, SIGNAL( receivedStderr( KProcess*, char*, int ) ),
+ this, SLOT ( slotProcessStderr( KProcess*, char*, int ) ) );
+ connect( p, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited( KProcess* ) ) );
+
+ output->append( i18n( "[ Starting command ]" ) );
+
+ if ( p->start( KProcess::NotifyOnExit, KProcess::Communication( KProcess::AllOutput ) ) ) {
+ // Disable the main button (and the log edit if in commit mode) to
+ // indicate activity.
+ mainBtn->setEnabled( false );
+ if ( _cmd == CVS::Commit )
+ logedit->setEnabled( false );
+ } else
+ {
+ kdError() << "Process could not be started." << endl;
+ KMessageBox::error( this, i18n( "The process could not be started." ) );
+ }
+}
+
+void CVSDialog::slotProcessStdout( KProcess*, char * buffer, int len )
+{
+ output->append( QString::fromLocal8Bit( buffer, len ) );
+ // Set the cursor's position at the end of the output.
+ output->setCursorPosition( output->lines( ), 0 );
+
+ // If the command is 'cvs status' or 'cvs diff' collect the output of stdout.
+ if ( (_cmd == CVS::Status) || (_cmd == CVS::Diff) )
+ _statusOutput += QString::fromLocal8Bit( buffer, len );
+}
+
+void CVSDialog::slotProcessStderr( KProcess*, char * buffer, int len )
+{
+ // If an error occurs while executing the command display stderr in
+ // another color.
+ QColor oldColor( output->color( ) );
+ output->setColor( Qt::red );
+ output->append( QString::fromLocal8Bit( buffer, len ) );
+ output->setColor( oldColor );
+ output->setCursorPosition( output->lines( ), 0 );
+}
+
+void CVSDialog::slotProcessExited( KProcess * p )
+{
+ if ( p->exitStatus( ) )
+ output->append( i18n( "[ Exited with status %1 ]" ).arg( p->exitStatus( ) ) );
+ else
+ output->append( i18n( "[ Finished ]" ) );
+
+ // The command is finished. Now we can reconnect the main button.
+ disconnect( mainBtn, 0, 0, 0 );
+ if ( _cmd == CVS::Diff )
+ mainBtn->setText( i18n( "&Show Diff" ) );
+ else
+ mainBtn->setText( i18n( "&Close" ) );
+ connect( mainBtn, SIGNAL( clicked( ) ), this, SLOT( accept( ) ) );
+
+ // Reenable the button and the log edit now that the process is finished.
+ mainBtn->setEnabled( true );
+ if ( _cmd == CVS::Commit )
+ logedit->setEnabled( true );
+}
+
+QString CVSDialog::statusOutput( )
+{
+ return _statusOutput;
+}
+
+void CVSDialog::readSettings( )
+{
+ KSharedConfig * config = m_config;
+ config->setGroup( "CVSSupport" );
+
+ if ( _cmd == CVS::Commit ) {
+ autoAddBox->setChecked( config->readBoolEntry( "AutoAddFiles", true ) );
+
+ // Fill the combobox with old messages.
+ m_logMessages.clear();
+ m_squeezedLogMessages.clear();
+ for ( int cnt = 0; cnt < 10; cnt++ )
+ if ( config->hasKey( QString( "CommitLogMessage%1" ).arg( cnt ) ) )
+ {
+ const QString logMessage = config->readEntry( QString( "CommitLogMessage%1" ).arg( cnt ) );
+ if ( !logMessage.isEmpty() )
+ {
+ // If the message is too long, cut it to 80 characters (or the combo box becomes too wide)
+ // ### FIXME: if the string matches the squeezed 80 chars, it might overwrite another entry
+ const QString shortLog = KStringHandler::csqueeze( logMessage );
+ m_logMessages.append( logMessage );
+ m_squeezedLogMessages.append( shortLog );
+ oldMessages->insertItem( shortLog );
+ }
+ }
+
+ m_encoding = config->readEntry( "CVSEncoding", "UTF-8" );
+ m_encodingComboBox->insertItem( i18n( "Descriptive encoding name", "Last choice ( %1 )" ).arg( m_encoding ), 0);
+ }
+}
+
+void CVSDialog::saveSettings( )
+{
+ KSharedConfig * config = m_config;
+ config->setGroup( "CVSSupport" );
+ if ( _cmd == CVS::Commit ) {
+ config->writeEntry( "AutoAddFiles", autoAddBox->isChecked( ) );
+
+ // Write the log messages to the config file.
+ int cnt = 0;
+ QStringList::const_iterator it;
+ for ( it = m_logMessages.constBegin( ); it != m_logMessages.constEnd( ) && cnt < 10 ; ++it, ++cnt )
+ config->writeEntry( QString( "CommitLogMessage%1" ).arg( cnt ), *it );
+
+ config->writeEntry( "CVSEncoding", m_encoding );
+ }
+ m_config->sync();
+}
+
+#include "cvsdialog.moc"
diff --git a/kbabel/catalogmanager/libcvs/cvsdialog.h b/kbabel/catalogmanager/libcvs/cvsdialog.h
new file mode 100644
index 00000000..658e9883
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/cvsdialog.h
@@ -0,0 +1,158 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+#ifndef CVSDIALOG_H
+#define CVSDIALOG_H
+
+// KDE include files
+#include <kdialog.h>
+// Project specific include files
+#include "cvsresources.h"
+// Forwarding Qt classes
+class QCheckBox;
+class QComboBox;
+class QListBox;
+class QPushButton;
+class QString;
+class QStringList;
+class QTextEdit;
+// Forwarding KDE classes
+class KProcess;
+class KTempFile;
+class KComboBox;
+
+/**
+ * This class represents the dialog which is used for executing CVS commands
+ * in KBabel's Catalog Manager. The dialog shows the list of files to be
+ * processed as well as the output from the command.
+ *
+ * In Commit mode there is also an option for automatically executing
+ * 'cvs add' if necessary.
+ *
+ * @short Dialog for CVS support in Catalog Manager
+ * @author Marco Wegner <mail@marcowegner.de>
+ */
+class CVSDialog : public KDialog
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor for creating the dialog.
+ * @param cmd The type of command to be executed.
+ */
+ CVSDialog( CVS::Command cmd, QWidget * parent, KSharedConfig* config );
+ ~CVSDialog();
+ /**
+ * Set the list of files which will be used for the CVS command.
+ * @param files The list of files.
+ */
+ void setFiles( const QStringList& files );
+ /**
+ * Set the command line for the execution of the CVS command.
+ * @param command The command line.
+ */
+ void setCommandLine( const QString& command );
+ /**
+ * Set the command line for adding files to the CVS repository.
+ * This method is only used together with a 'cvs commit' for automatically
+ * adding files which are not yet in the repository.
+ * @param command The command line.
+ */
+ void setAddCommand( const QString& command );
+ /**
+ * Return the output of a 'cvs status' command.
+ * @returns The complete output.
+ */
+ QString statusOutput( );
+
+ protected:
+ /**
+ * This method is overwritten so that the settings can be saved after
+ * pressing the 'Close' button.
+ */
+ virtual void accept( );
+ /** Read the dialog's settings. */
+ void readSettings( );
+ /** Save the dialog's settings. */
+ void saveSettings( );
+
+ protected slots:
+ /** Slot for executing the CVS Command. */
+ void slotExecuteCommand( );
+ /** Slot for processing the stdout of the CVS Command. */
+ void slotProcessStdout( KProcess*, char * buffer, int len );
+ /** Slot for processing the stderr of the CVS Command. */
+ void slotProcessStderr( KProcess*, char * buffer, int len );
+ /** Slot for post-processing after the CVS command is fninished. */
+ void slotProcessExited( KProcess * p );
+ /// Slot for combox having been activated
+ void slotComboActivated( int );
+
+ private:
+ CVS::Command _cmd;
+
+ QPushButton * mainBtn;
+ QPushButton * cancelBtn;
+ QListBox * filebox;
+ QComboBox * oldMessages;
+ QTextEdit * logedit;
+ QTextEdit * output;
+ QCheckBox * autoAddBox;
+
+ KProcess * p;
+
+ QString _commandLine;
+ QString _addCommand;
+ QString _statusOutput;
+
+ /// Log messages (long version)
+ QStringList m_logMessages;
+ /// Log messages (short version)
+ QStringList m_squeezedLogMessages;
+
+ /// Temporary file (for commits)
+ KTempFile* m_tempFile;
+
+ /// Encoding for the commit log message
+ QString m_encoding;
+
+ /// Combo box for the encoding
+ KComboBox* m_encodingComboBox;
+
+ /// Configuration data (of the KBabel project)
+ KSharedConfig* m_config;
+};
+
+#endif // CVSDIALOG_H
diff --git a/kbabel/catalogmanager/libcvs/cvshandler.cpp b/kbabel/catalogmanager/libcvs/cvshandler.cpp
new file mode 100644
index 00000000..d3f2ae18
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/cvshandler.cpp
@@ -0,0 +1,398 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+// System include files
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+// Qt include files
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qstringlist.h>
+// KDE include files
+#include <kapplication.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+// project specific include files
+#include "cvshandler.h"
+
+
+CVSHandler::CVSHandler( const QString& poBaseDir, const QString& potBaseDir )
+{
+ setPOBaseDir( poBaseDir );
+ setPOTBaseDir( potBaseDir );
+ _autoUpdateTemplates = false;
+}
+
+void CVSHandler::setPOBaseDir( const QString& dir )
+{
+ // check if 'CVS/Entries' exists in the PO base directory
+ if ( QFileInfo( dir + "/CVS/Entries" ).exists( ) ) {
+ _isPORepository = true;
+ _poBaseDir = dir;
+ } else
+ _isPORepository = false;
+ emit signalIsPORepository( _isPORepository );
+}
+
+void CVSHandler::setPOTBaseDir( const QString& dir )
+{
+ // check if 'CVS/Entries' exists in the POT base directory
+ if ( QFileInfo( dir + "/CVS/Entries" ).exists( ) ) {
+ _isPOTRepository = true;
+ _potBaseDir = dir;
+ } else
+ _isPOTRepository = false;
+ emit signalIsPOTRepository( _isPOTRepository );
+}
+
+QString CVSHandler::fileStatus( const FileStatus status ) const
+{
+ switch ( status ) {
+ case NO_REPOSITORY:
+ return i18n( "No CVS repository" );
+ break;
+ case NOT_IN_CVS:
+ return i18n( "Not in CVS" );
+ break;
+ case LOCALLY_ADDED:
+ return i18n( "Locally added" );
+ break;
+ case LOCALLY_REMOVED:
+ return i18n( "Locally removed" );
+ break;
+ case LOCALLY_MODIFIED:
+ return i18n( "Locally modified" );
+ break;
+ case UP_TO_DATE:
+ return i18n( "Up-to-date" );
+ break;
+ case CONFLICT:
+ return i18n( "Conflict" );
+ break;
+ default:
+ return i18n( "Unknown" );
+ break;
+ }
+}
+
+CVSHandler::FileStatus CVSHandler::fstatus( const QString& filename ) const
+{
+ // no valid repository
+ if ( !_isPORepository )
+ return NO_REPOSITORY;
+
+ QString fn( filename );
+ fn = fn.remove( QRegExp( "/$" ) );
+
+ QFileInfo info( fn );
+
+ // check if 'CVS/Entries' exists and can be read
+ QFile entries( info.dir( true ).path( ) + "/CVS/Entries" );
+ if ( !entries.open( IO_ReadOnly ) )
+ return NOT_IN_CVS; // we already know that it's a repository
+
+ // ### FIXME: it does not take care of CVS/Entries.Log
+ // a line in CVS/Entries has the following format:
+ // [D]/NAME/REVISION/[CONFLICT+]TIMESTAMP/OPTIONS/TAGDATE
+ QRegExp rx( QString( "^D?/%1/" ).arg( info.fileName( ) ) );
+
+ QString temp;
+ QTextStream stream( &entries );
+
+ bool isInRepository = false;
+ while ( !stream.atEnd() ) {
+ temp = stream.readLine( );
+ if ( temp.find( rx ) == 0 ) {
+ isInRepository = true;
+ break;
+ }
+ }
+ entries.close( );
+
+ // no entry found
+ if ( !isInRepository )
+ return NOT_IN_CVS;
+
+ const QStringList fields = QStringList::split( '/', temp, true );
+ // bool isDir = ( fields[0] == "D" );
+ const QString cvsname( fields[1] );
+ const QString revision( fields[2] );
+ const QString timestamp( fields[3] );
+ // ignore the other fields for now
+
+ if ( revision == "0" && timestamp == "dummy timestamp" )
+ return LOCALLY_ADDED;
+ if ( revision.startsWith( "-" ) && timestamp == "dummy timestamp" )
+ return LOCALLY_REMOVED;
+
+ // check for conflicts
+ if ( timestamp.find( '+' ) >= 0 )
+ return CONFLICT;
+
+ // calculate the UTC time from the file's last modified date
+ struct stat st;
+ lstat( QFile::encodeName(fn), &st );
+ struct tm * tm_p = gmtime( &st.st_mtime );
+ QString ftime = QString( asctime( tm_p ) );
+ ftime.truncate( ftime.length( ) - 1 );
+ if ( ftime != timestamp )
+ return LOCALLY_MODIFIED;
+
+ return UP_TO_DATE;
+}
+
+QString CVSHandler::cvsStatus( const QString& filename ) const
+{
+ return map[filename];
+}
+
+void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates, KSharedConfig* config )
+{
+ if ( !_isPORepository ) {
+ // This message box should never be visible but who knows... ;-)
+ KMessageBox::sorry( parent, i18n( "This is not a valid CVS repository. "
+ "The CVS commands cannot be executed." ) );
+ return;
+ }
+
+ QFileInfo info( filename );
+ if ( !info.isDir( ) ) {
+ execCVSCommand( parent, cmd, QStringList( filename ), templates, config );
+ return;
+ }
+
+ // ### FIXME: instead of making a QString, use KProcess directly, so that it cares about quoting.
+ // ### FIXME: use KProcess::setWorkingDirectory instead of using "cd" (therefore allowing to use KProcess without a shell.)
+ // it's a dir
+ QString command( "cd " + filename + " && cvs " );
+ switch ( cmd ) {
+ case CVS::Update:
+ command += "update -dP";
+ break;
+ case CVS::Commit:
+ // The cvs client does not care about the encoding, so we cannot set anything here
+ command += "commit -F @LOG@FILE@";
+ checkToAdd( QStringList( filename ) );
+ break;
+ case CVS::Status:
+ command += "status";
+ break;
+ case CVS::Diff:
+ command += "diff";
+ break;
+ }
+
+ showDialog( parent, cmd, QStringList( filename ), command, config );
+}
+
+void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates, KSharedConfig* config )
+{
+ if ( !_isPORepository ) {
+ // This message box should never be visible but who knows... ;-)
+ KMessageBox::sorry( parent, i18n( "This is not a valid CVS repository. "
+ "The CVS commands cannot be executed." ) );
+ return;
+ }
+
+ // ### FIXME: instead of making a QString, use KProcess directly, so that it cares about quoting.
+ // ### FIXME: use KProcess::setWorkingDirectory instead of using "cd" (therefore allowing to use KProcess without a shell.)
+ QString command("cd " + (templates ? _potBaseDir : _poBaseDir) + " && cvs ");
+ switch ( cmd ) {
+ case CVS::Update:
+ command += "update -dP";
+ break;
+ case CVS::Commit:
+ command += "commit -F @LOG@FILE@";
+ checkToAdd( files );
+ break;
+ case CVS::Status:
+ command += "status";
+ break;
+ case CVS::Diff:
+ command += "diff";
+ break;
+ }
+
+ QRegExp rx;
+ if (templates)
+ rx.setPattern(_potBaseDir + "/?");
+ else
+ rx.setPattern(_poBaseDir + "/?");
+
+ QStringList::ConstIterator it;
+ for ( it = files.begin( ); it != files.end( ); ++it ) {
+ QString temp = *it;
+ temp.remove(rx);
+ command += " \'" + temp + "\'";
+ }
+
+ showDialog( parent, cmd, files, command, config );
+}
+
+void CVSHandler::setAutoUpdateTemplates( bool update )
+{
+ _autoUpdateTemplates = update;
+}
+
+void CVSHandler::showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config )
+{
+ CVSDialog * dia = new CVSDialog( cmd, parent, config );
+ dia->setFiles( files );
+ dia->setCommandLine( commandLine );
+ if ( cmd == CVS::Commit ) {
+ dia->setAddCommand( _addCommand );
+ }
+
+ if ( dia->exec( ) == KDialog::Accepted ) {
+ if ( cmd == CVS::Status )
+ processStatusOutput( dia->statusOutput( ) );
+ if ( cmd == CVS::Diff )
+ processDiff( dia->statusOutput( ) );
+ }
+
+ delete dia;
+
+ // file status display update necessary in Catalog Manager
+ if ( cmd == CVS::Commit )
+ emit signalFilesCommitted( files );
+}
+
+void CVSHandler::checkToAdd( const QStringList& files )
+{
+ if ( files.isEmpty( ) )
+ return;
+
+ QStringList toBeAdded;
+
+ QStringList::ConstIterator it;
+ for ( it = files.begin( ); it != files.end( ); ++it ) {
+ // check for every entry if it needs to be added
+ if ( fstatus( *it ) == NOT_IN_CVS ) {
+ QFileInfo info( *it );
+ QString temp; // will hold the dir path
+ if ( info.isDir( ) ) {
+ toBeAdded << *it;
+ temp = *it;
+ } else {
+ toBeAdded << *it;
+ temp = QFileInfo( *it ).dirPath( true );
+ }
+ // check recursivlely if parent dirs have to be added as well
+ while ( fstatus( temp ) == NOT_IN_CVS && toBeAdded.findIndex( temp ) == -1 ) {
+ toBeAdded << temp;
+ temp = QFileInfo( temp ).dirPath( true );
+ }
+ }
+ }
+
+ // remove an old command
+ _addCommand.setLength( 0 );
+
+ // make sure the diectories are added before the files
+ toBeAdded.sort( );
+
+ // create a command line for adding the files and dirs
+ for ( it = toBeAdded.begin( ); it != toBeAdded.end( ); ++it ) {
+ QFileInfo info( *it );
+ _addCommand += "cd " + info.dirPath( true ) + " && cvs add " + info.fileName( ) + "; ";
+ }
+}
+
+void CVSHandler::processStatusOutput( const QString& status )
+{
+ if ( !_isPORepository )
+ return;
+
+ // at first we need to extract the name of the base directory on the server
+ QFile f( _poBaseDir + "/CVS/Root" );
+ if ( !f.open( IO_ReadOnly ) )
+ return;
+
+ QTextStream stream( &f );
+ // extract the string after the last colon in the first line
+ QString basedir = stream.readLine( ).section( ':', -1 );
+
+ f.close( );
+
+ // divide the complete status output in little chunks for every file
+ QStringList entries = QStringList::split( QRegExp( "={67,67}" ), status );
+ QStringList::Iterator it;
+ for ( it = entries.begin( ); it != entries.end( ); ++it ) {
+ QString entr = *it;
+ // translate the filename from repository to local
+ QRegExp rx( basedir + ".*,v" );
+ int pos = entr.find( rx );
+ QString file = _poBaseDir + entr.mid( pos + basedir.length( ),
+ rx.matchedLength( ) - basedir.length( ) - 2 );
+
+ entr = "<qt>" + entr + "</qt>";
+
+ // TODO: do some markup
+
+ map.replace( file, entr );
+ }
+}
+
+void CVSHandler::processDiff( QString output )
+{
+ output.remove( QRegExp( "\\[ .* \\]$" ));
+ output.remove( QRegExp( "^" + i18n("[ Starting command ]" ).replace("[","\\[").replace("]","\\]")));
+
+ KTempFile tmpFile;
+ *(tmpFile.textStream()) << output;
+ tmpFile.close();
+
+ QString error;
+ if ( KApplication::startServiceByName( "Kompare", tmpFile.name(), &error ) )
+ KMessageBox::error( 0, error );
+}
+
+bool CVSHandler::isConsideredModified( const FileStatus status ) const
+{
+ /*
+ * A file is modified if it is either:
+ * - locally modified for CVS
+ * - directory under CVS control but not the file
+ */
+ return status == LOCALLY_MODIFIED || status == NOT_IN_CVS;
+}
+
+
+
+#include "cvshandler.moc"
diff --git a/kbabel/catalogmanager/libcvs/cvshandler.h b/kbabel/catalogmanager/libcvs/cvshandler.h
new file mode 100644
index 00000000..44777aa3
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/cvshandler.h
@@ -0,0 +1,114 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+#ifndef CVSHANDLER_H
+#define CVSHANDLER_H
+
+// Qt include files
+#include <qmap.h>
+#include <qobject.h>
+// Project specific include files
+#include "cvsdialog.h"
+#include "cvsresources.h"
+// Forwarding Qt classes
+class QString;
+class QStringList;
+class QWidget;
+
+class KSharedConfig;
+
+/**
+ * This class is the backend for CVS support in Catalog Manager.
+ *
+ * @short Backend for CVS support in Catalog Manager
+ * @author Marco Wegner <mail@marcowegner.de>
+ */
+class CVSHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum FileStatus {
+ NO_REPOSITORY,
+ NOT_IN_CVS,
+ LOCALLY_ADDED,
+ LOCALLY_REMOVED,
+ LOCALLY_MODIFIED,
+ CONFLICT,
+ UP_TO_DATE
+ };
+
+ CVSHandler( const QString& poBaseDir = QString::null, const QString& potBaseDir = QString::null );
+
+ void setPOBaseDir( const QString& dir );
+ void setPOTBaseDir( const QString& dir );
+
+ FileStatus fstatus( const QString& filename ) const;
+ QString fileStatus( const FileStatus status ) const;
+ QString cvsStatus( const QString& filename ) const;
+
+ void execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates, KSharedConfig* config );
+ void execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates, KSharedConfig* config );
+
+ void setAutoUpdateTemplates( bool update );
+
+ /**
+ * True if the file was modified or has another status considered as a modification
+ */
+ bool isConsideredModified( const FileStatus status ) const;
+
+ signals:
+ void signalIsPORepository( bool );
+ void signalIsPOTRepository( bool );
+ void signalFilesCommitted( const QStringList& );
+
+ private:
+ void showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config );
+ void checkToAdd( const QStringList& files );
+ void processStatusOutput( const QString& status );
+ void processDiff( QString output );
+
+ private:
+ QString _poBaseDir;
+ QString _potBaseDir;
+ bool _isPORepository;
+ bool _isPOTRepository;
+ bool _autoUpdateTemplates;
+ QString _addCommand;
+
+ /** Mapping the output of 'cvs status' against the filename. */
+ QMap<QString,QString> map;
+};
+
+#endif // CVSHANDLER_H
diff --git a/kbabel/catalogmanager/libcvs/cvsresources.h b/kbabel/catalogmanager/libcvs/cvsresources.h
new file mode 100644
index 00000000..627802f7
--- /dev/null
+++ b/kbabel/catalogmanager/libcvs/cvsresources.h
@@ -0,0 +1,41 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 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 CVSRESOURCES_H
+#define CVSRESOURCES_H
+
+namespace CVS {
+ enum Command { Update, Commit, Status, Diff };
+}
+
+#endif // CVSRESOURCES_H
diff --git a/kbabel/catalogmanager/libsvn/Makefile.am b/kbabel/catalogmanager/libsvn/Makefile.am
new file mode 100644
index 00000000..7c340974
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libcatalogmanagersvn.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I.. -I../../common $(all_includes)
+
+libcatalogmanagersvn_la_SOURCES = svnhandler.cpp svndialog.cpp
+
+noinst_HEADERS = svnhandler.h svndialog.h svnresources.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
diff --git a/kbabel/catalogmanager/libsvn/svndialog.cpp b/kbabel/catalogmanager/libsvn/svndialog.cpp
new file mode 100644
index 00000000..69653591
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/svndialog.cpp
@@ -0,0 +1,400 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+// Qt include files
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qfileinfo.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtextedit.h>
+// KDE include files
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <ktempfile.h>
+#include <kmessagebox.h>
+#include <kstringhandler.h>
+// Project specific include files
+#include "svndialog.h"
+
+
+SVNDialog::SVNDialog( SVN::Command cmd, QWidget * parent, KSharedConfig* config )
+ : KDialog( parent, "SVN DIALOG", true ), m_tempFile( 0 ), m_config( config )
+{
+ _cmd = cmd;
+ p=0L;
+ setCaption( i18n( "SVN Dialog" ) );
+
+ QString temp;
+
+ QVBoxLayout * layout = new QVBoxLayout( this, 6, 6, "MAIN LAYOUT" );
+
+ // Set the label's text depending on the SVN command.
+ switch ( cmd ) {
+ case SVN::Update:
+ temp = i18n( "Update the following files:" );
+ break;
+ case SVN::Commit:
+ temp = i18n( "Commit the following files:" );
+ break;
+ case SVN::StatusRemote:
+ temp = i18n( "Get remote status for the following files:" );
+ break;
+ case SVN::StatusLocal:
+ temp = i18n( "Get local status for the following files:" );
+ break;
+ case SVN::Diff:
+ temp = i18n( "Get diff for the following files:" );
+ break;
+ case SVN::Info:
+ temp = i18n( "Get information for the following files:" );
+ break;
+ }
+ layout->addWidget( new QLabel( temp, this ) );
+
+ // Widget for showing the list of files.
+ filebox = new QListBox( this );
+ layout->addWidget( filebox );
+
+ // Add special widgets for 'svn commit'.
+ if ( cmd == SVN::Commit ) {
+ QLabel * label;
+
+ // Combobox for displaying old log messages.
+ label = new QLabel( i18n( "&Old messages:" ), this );
+ oldMessages = new QComboBox( this );
+ oldMessages->setDuplicatesEnabled( false );
+ label->setBuddy( oldMessages );
+ layout->addWidget( label );
+ layout->addWidget( oldMessages );
+
+ // Textfield for entering a log message.
+ label = new QLabel( i18n( "&Log message:" ), this );
+ logedit = new QTextEdit( this );
+ label->setBuddy( logedit );
+ layout->addWidget( label );
+ layout->addWidget( logedit );
+
+ connect( oldMessages, SIGNAL( activated( int ) ),
+ this, SLOT( slotComboActivated( int ) ) );
+ }
+
+ QHBoxLayout * buttons = new QHBoxLayout( 0, 0, 6, "BUTTON LAYOUT" );
+ // Add special buttons for 'svn commit'.
+ if ( cmd == SVN::Commit ) {
+ autoAddBox = new QCheckBox( i18n( "Auto&matically add files if necessary" ), this );
+ buttons->addWidget( autoAddBox );
+ }
+ buttons->addItem( new QSpacerItem( 1, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+
+ // Set the main button's text depending on the SVN comand.
+ switch ( cmd ) {
+ case SVN::Update:
+ temp = i18n( "&Update" );
+ break;
+ case SVN::Commit:
+ temp = i18n( "&Commit" );
+ break;
+ case SVN::StatusRemote:
+ case SVN::StatusLocal:
+ temp = i18n( "&Get Status" );
+ break;
+ case SVN::Diff:
+ temp = i18n( "&Get Diff" );
+ break;
+ case SVN::Info:
+ temp = i18n( "&Get Information" );
+ break;
+ }
+ mainBtn = new QPushButton( temp, this );
+ mainBtn->setDefault( true );
+ buttons->addWidget( mainBtn );
+
+ cancelBtn = new QPushButton( i18n( "C&ancel" ), this );
+ buttons->addWidget( cancelBtn );
+ layout->addLayout( buttons );
+
+ QFrame * line = new QFrame( this );
+ line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget( line );
+
+ layout->addWidget( new QLabel( i18n( "Command output:" ), this ) );
+
+ output = new QTextEdit( this );
+ output->setReadOnly( true );
+ layout->addWidget( output );
+
+ resize( QSize( 600, 450 ).expandedTo( minimumSizeHint( ) ) );
+
+ if ( cmd == SVN::Commit )
+ logedit->setFocus( );
+
+ readSettings( );
+
+ connect( mainBtn, SIGNAL( clicked( ) ), this, SLOT( slotExecuteCommand( ) ) );
+ connect( cancelBtn, SIGNAL( clicked( ) ), this, SLOT( reject( ) ) );
+}
+
+void SVNDialog::slotComboActivated( int index )
+{
+ if ( index < 0 || index >= m_logMessages.count() )
+ return;
+ logedit->setText( m_logMessages[index] );
+}
+
+SVNDialog::~SVNDialog()
+{
+ delete m_tempFile;
+ delete p;
+}
+
+void SVNDialog::accept( )
+{
+ saveSettings( );
+ KDialog::accept( );
+}
+
+void SVNDialog::setFiles( const QStringList& files )
+{
+ filebox->insertStringList( files );
+}
+
+void SVNDialog::setCommandLine( const QString& command )
+{
+ _commandLine = command;
+}
+
+void SVNDialog::setAddCommand( const QString& command )
+{
+ _addCommand = command;
+}
+
+void SVNDialog::slotExecuteCommand( )
+{
+ // Nothing to do here.
+ if ( _commandLine.isEmpty( ) ) return;
+
+ kdDebug() << "Preparing KProcess" << endl;
+
+ // Create a new shell process
+ p = new KProcess;
+ p->setUseShell( true, "/bin/sh" );
+
+ if ( _cmd == SVN::Commit ) {
+ // Include command for 'svn add'.
+ if ( autoAddBox->isChecked( ) && !_addCommand.isEmpty( ) )
+ _commandLine.prepend( _addCommand );
+
+ const QString msg( logedit->text() );
+
+ if ( msg.isEmpty() )
+ {
+ // A good commit should never have an empty comment, so ask the user if he really wants it.
+ const int res = KMessageBox::warningContinueCancel( this,
+ i18n( "The commit log message is empty. Do you want to continue?" ) );
+ if ( res != KMessageBox::Continue )
+ return;
+ }
+
+ // Write the commit log message from the input field to a temporary file
+ m_tempFile = new KTempFile;
+ m_tempFile->setAutoDelete( true );
+ QTextStream* stream = m_tempFile->textStream();
+ if ( !stream )
+ {
+ kdError() << "Could not create QTextStream for file " << m_tempFile->name();
+ delete m_tempFile;
+ m_tempFile = 0;
+ KMessageBox::error( this, i18n( "Cannot open temporary file for writing. Aborting.") );
+ return;
+ }
+ stream->setEncoding( QTextStream::UnicodeUTF8 );
+ *stream << msg;
+ m_tempFile->close();
+
+ if ( m_tempFile->status() )
+ {
+ kdError() << "Could not write to file " << m_tempFile->name();
+ delete m_tempFile;
+ m_tempFile = 0;
+ KMessageBox::error( this, i18n( "Cannot write to temporary file. Aborting.") );
+ return;
+ }
+
+ // Change the command line to have the real name of the temporary file
+ _commandLine.replace( "@LOG@FILE@", KProcess::quote( m_tempFile->name() ) );
+
+ // Update the list of log messages
+ if ( !msg.isEmpty() ) {
+ const QString shortLog = KStringHandler::csqueeze( msg, 80 );
+
+
+ // Remove the message from the list if it already exists
+ m_logMessages.remove( msg );
+ // Prepend the current message to the list
+ m_logMessages.prepend( msg );
+
+ // At this time of the process, we do not need the combobox anymore, so we do not squeeze the changed strings.
+ }
+ }
+
+ // Set the KProcess' command line.
+ *p << _commandLine;
+
+ connect( p, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
+ this, SLOT ( slotProcessStdout( KProcess*, char*, int ) ) );
+ connect( p, SIGNAL( receivedStderr( KProcess*, char*, int ) ),
+ this, SLOT ( slotProcessStderr( KProcess*, char*, int ) ) );
+ connect( p, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited( KProcess* ) ) );
+
+ output->append( i18n( "[ Starting command ]" ) );
+
+ if ( p->start( KProcess::NotifyOnExit, KProcess::Communication( KProcess::AllOutput ) ) ) {
+ // Disable the main button (and the log edit if in commit mode) to
+ // indicate activity.
+ mainBtn->setEnabled( false );
+ if ( _cmd == SVN::Commit )
+ logedit->setEnabled( false );
+ } else
+ {
+ kdError() << "Process could not be started." << endl;
+ KMessageBox::error( this, i18n( "The process could not be started." ) );
+ }
+}
+
+void SVNDialog::slotProcessStdout( KProcess*, char * buffer, int len )
+{
+ output->append( QString::fromLocal8Bit( buffer, len ) );
+ // Set the cursor's position at the end of the output.
+ output->setCursorPosition( output->lines( ), 0 );
+
+ // If the command is 'svn status' or 'svn diff' collect the output of stdout.
+ if ( ( _cmd == SVN::StatusLocal ) || ( _cmd == SVN::StatusRemote ) || ( _cmd == SVN::Diff ) )
+ _statusOutput += QString::fromLocal8Bit( buffer, len );
+}
+
+void SVNDialog::slotProcessStderr( KProcess*, char * buffer, int len )
+{
+ // If an error occurs while executing the command display stderr in
+ // another color.
+ QColor oldColor( output->color( ) );
+ output->setColor( Qt::red );
+ output->append( QString::fromLocal8Bit( buffer, len ) );
+ output->setColor( oldColor );
+ output->setCursorPosition( output->lines( ), 0 );
+}
+
+void SVNDialog::slotProcessExited( KProcess * p )
+{
+ if ( p->exitStatus( ) )
+ output->append( i18n( "[ Exited with status %1 ]" ).arg( p->exitStatus( ) ) );
+ else
+ output->append( i18n( "[ Finished ]" ) );
+
+ // The command is finished. Now we can reconnect the main button.
+ disconnect( mainBtn, 0, 0, 0 );
+ if ( _cmd == SVN::Diff )
+ mainBtn->setText( i18n( "&Show Diff" ) );
+ else
+ mainBtn->setText( i18n( "&Close" ) );
+ connect( mainBtn, SIGNAL( clicked( ) ), this, SLOT( accept( ) ) );
+
+ // Reenable the button and the log edit now that the process is finished.
+ mainBtn->setEnabled( true );
+ if ( _cmd == SVN::Commit )
+ logedit->setEnabled( true );
+}
+
+QString SVNDialog::statusOutput( )
+{
+ return _statusOutput;
+}
+
+void SVNDialog::readSettings( )
+{
+ KSharedConfig * config = m_config;
+ config->setGroup( "SVNSupport" );
+
+ if ( _cmd == SVN::Commit ) {
+ autoAddBox->setChecked( config->readBoolEntry( "AutoAddFiles", true ) );
+
+ // Fill the combobox with old messages.
+ m_logMessages.clear();
+ m_squeezedLogMessages.clear();
+ for ( int cnt = 0; cnt < 10; cnt++ )
+ if ( config->hasKey( QString( "CommitLogMessage%1" ).arg( cnt ) ) )
+ {
+ const QString logMessage = config->readEntry( QString( "CommitLogMessage%1" ).arg( cnt ) );
+ if ( !logMessage.isEmpty() )
+ {
+ // If the message is too long, cut it to 80 characters (or the combo box becomes too wide)
+ // ### FIXME: if the string matches the squeezed 80 chars, it might overwrite another entry
+ const QString shortLog = KStringHandler::csqueeze( logMessage );
+ m_logMessages.append( logMessage );
+ m_squeezedLogMessages.append( shortLog );
+ oldMessages->insertItem( shortLog );
+ }
+ }
+
+ }
+}
+
+void SVNDialog::saveSettings( )
+{
+ KSharedConfig * config = m_config;
+ config->setGroup( "SVNSupport" );
+ if ( _cmd == SVN::Commit ) {
+ config->writeEntry( "AutoAddFiles", autoAddBox->isChecked( ) );
+
+ // Write the log messages to the config file.
+ int cnt = 0;
+ QStringList::const_iterator it;
+ for ( it = m_logMessages.constBegin( ); it != m_logMessages.constEnd( ) && cnt < 10 ; ++it, ++cnt )
+ config->writeEntry( QString( "CommitLogMessage%1" ).arg( cnt ), *it );
+ }
+ m_config->sync();
+}
+
+#include "svndialog.moc"
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kbabel/catalogmanager/libsvn/svndialog.h b/kbabel/catalogmanager/libsvn/svndialog.h
new file mode 100644
index 00000000..0c824fa8
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/svndialog.h
@@ -0,0 +1,151 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+#ifndef SVNDIALOG_H
+#define SVNDIALOG_H
+
+// KDE include files
+#include <kdialog.h>
+// Project specific include files
+#include "svnresources.h"
+// Forwarding Qt classes
+class QCheckBox;
+class QComboBox;
+class QListBox;
+class QPushButton;
+class QString;
+class QStringList;
+class QTextEdit;
+// Forwarding KDE classes
+class KProcess;
+class KTempFile;
+class KSharedConfig;
+
+/**
+ * This class represents the dialog which is used for executing SVN commands
+ * in KBabel's Catalog Manager. The dialog shows the list of files to be
+ * processed as well as the output from the command.
+ *
+ * In Commit mode there is also an option for automatically executing
+ * 'svn add' if necessary.
+ *
+ * @short Dialog for SVN support in Catalog Manager
+ */
+class SVNDialog : public KDialog
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor for creating the dialog.
+ * @param cmd The type of command to be executed.
+ */
+ SVNDialog( SVN::Command cmd, QWidget * parent, KSharedConfig* config );
+ ~SVNDialog();
+ /**
+ * Set the list of files which will be used for the SVN command.
+ * @param files The list of files.
+ */
+ void setFiles( const QStringList& files );
+ /**
+ * Set the command line for the execution of the SVN command.
+ * @param command The command line.
+ */
+ void setCommandLine( const QString& command );
+ /**
+ * Set the command line for adding files to the SVN repository.
+ * This method is only used together with a 'svn commit' for automatically
+ * adding files which are not yet in the repository.
+ * @param command The command line.
+ */
+ void setAddCommand( const QString& command );
+ /**
+ * Return the output of a 'svn status' command.
+ * @returns The complete output.
+ */
+ QString statusOutput( );
+
+ protected:
+ /**
+ * This method is overwritten so that the settings can be saved after
+ * pressing the 'Close' button.
+ */
+ virtual void accept( );
+ /** Read the dialog's settings. */
+ void readSettings( );
+ /** Save the dialog's settings. */
+ void saveSettings( );
+
+ protected slots:
+ /** Slot for executing the SVN Command. */
+ void slotExecuteCommand( );
+ /** Slot for processing the stdout of the SVN Command. */
+ void slotProcessStdout( KProcess*, char * buffer, int len );
+ /** Slot for processing the stderr of the SVN Command. */
+ void slotProcessStderr( KProcess*, char * buffer, int len );
+ /** Slot for post-processing after the SVN command is fninished. */
+ void slotProcessExited( KProcess * p );
+ /// Slot for combox having been activated
+ void slotComboActivated( int );
+
+ private:
+ SVN::Command _cmd;
+
+ QPushButton * mainBtn;
+ QPushButton * cancelBtn;
+ QListBox * filebox;
+ QComboBox * oldMessages;
+ QTextEdit * logedit;
+ QTextEdit * output;
+ QCheckBox * autoAddBox;
+
+ KProcess * p;
+
+ QString _commandLine;
+ QString _addCommand;
+ QString _statusOutput;
+
+ /// Log messages (long version)
+ QStringList m_logMessages;
+ /// Log messages (short version)
+ QStringList m_squeezedLogMessages;
+
+ /// Temporary file (for commits)
+ KTempFile* m_tempFile;
+
+ /// Configuration data (of the KBabel project)
+ KSharedConfig* m_config;
+};
+
+#endif // SVNDIALOG_H
diff --git a/kbabel/catalogmanager/libsvn/svnhandler.cpp b/kbabel/catalogmanager/libsvn/svnhandler.cpp
new file mode 100644
index 00000000..8117fe62
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/svnhandler.cpp
@@ -0,0 +1,544 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+// System include files
+#include <unistd.h>
+#include <sys/stat.h>
+#include <time.h>
+// Qt include files
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qdom.h>
+// KDE include files
+#include <kapplication.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kprocess.h>
+// project specific include files
+#include "svnhandler.h"
+
+SVNHandler::SVNHandler( const QString& poBaseDir, const QString& potBaseDir )
+{
+ setPOBaseDir( poBaseDir );
+ setPOTBaseDir( potBaseDir );
+ _autoUpdateTemplates = false;
+}
+
+void SVNHandler::setPOBaseDir( const QString& dir )
+{
+ // check if '.svn/entries' exists in the PO base directory
+ if ( QFileInfo( dir + "/.svn/entries" ).exists( ) ) {
+ _isPORepository = true;
+ _poBaseDir = dir;
+ } else
+ _isPORepository = false;
+ emit signalIsPORepository( _isPORepository );
+}
+
+void SVNHandler::setPOTBaseDir( const QString& dir )
+{
+ // check if '.svn/entries' exists in the POT base directory
+ if ( QFileInfo( dir + "/.svn/entries" ).exists( ) ) {
+ _isPOTRepository = true;
+ _potBaseDir = dir;
+ } else
+ _isPOTRepository = false;
+ emit signalIsPOTRepository( _isPOTRepository );
+}
+
+QString SVNHandler::fileStatus( const FileStatus status ) const
+{
+ switch ( status ) {
+ case NO_REPOSITORY:
+ return i18n( "No SVN repository" );
+ break;
+ case NOT_IN_SVN:
+ return i18n( "Not in SVN" );
+ break;
+ case LOCALLY_ADDED:
+ return i18n( "Locally added" );
+ break;
+ case LOCALLY_REMOVED:
+ return i18n( "Locally removed" );
+ break;
+ case LOCALLY_MODIFIED:
+ return i18n( "Locally modified" );
+ break;
+ case UP_TO_DATE:
+ return i18n( "Up-to-date" );
+ break;
+ case CONFLICT:
+ return i18n( "Conflict" );
+ break;
+ case ERROR_IN_WC:
+ return i18n( "Error in Working Copy" );
+ default:
+ return i18n( "Unknown" );
+ break;
+ }
+}
+
+SVNHandler::FileStatus SVNHandler::fstatus( const QString& filename ) const
+{
+ // no valid repository
+ if ( !_isPORepository )
+ return NO_REPOSITORY;
+
+ QString fn( filename );
+ fn = fn.remove( QRegExp( "/$" ) );
+
+ QFileInfo info( fn );
+
+ // check if '.svn/entries' exists.
+ QFile entries( info.dir( true ).path( ) + "/.svn/entries" );
+
+ if ( !entries.exists() )
+ return NOT_IN_SVN;
+
+ KProcess proc;
+ SVNOutputCollector out( &proc );
+
+ proc << "svn" << "status" << "-v" << "--xml" << info.absFilePath();
+
+ if( !proc.start( KProcess::Block, KProcess::Stdout ) )
+ return ERROR_IN_WC;
+
+ QDomDocument doc;
+ QString errorMsg;
+ int errorLine, errorCol;
+ QDomNodeList nodelist;
+ QDomNode node;
+ QDomElement entry, wcStatus;
+
+ // Parse the output.
+ if ( !doc.setContent( out.getOutput(), &errorMsg, &errorLine, &errorCol ) ) {
+ kdDebug(8109) << "Cannot parse \"svn status -v --xml\" output for"
+ << filename << endl << "Line: " << errorLine << " Column: "
+ << errorCol << " Error: " << errorMsg << endl;
+ goto no_status_xml;
+ }
+
+ // There should be only one "entry" element. If it doesn't exist, path
+ // isn't repo path at all.
+ nodelist = doc.elementsByTagName("entry");
+ if (nodelist.count() < 1)
+ return NOT_IN_SVN;
+
+ entry = nodelist.item(0).toElement();
+
+ // Shouldn't fail, but just in case there is some weird error.
+ if ( entry.attributeNode("path").value() != info.absFilePath() )
+ return ERROR_IN_WC;
+
+ for ( node = entry.firstChild(); !node.isNull(); node = node.nextSibling() ) {
+ if ( !node.isElement() )
+ continue;
+ if (node.toElement().tagName() == "wc-status")
+ break;
+ }
+
+ if ( node.isNull() )
+ return ERROR_IN_WC;
+
+ wcStatus = node.toElement();
+
+ if ( wcStatus.attributeNode("item").value() == "normal" )
+ return UP_TO_DATE;
+ if ( wcStatus.attributeNode("item").value() == "modified" )
+ return LOCALLY_MODIFIED;
+ if ( wcStatus.attributeNode("item").value() == "conflicted" )
+ return CONFLICT;
+ if ( wcStatus.attributeNode("item").value() == "unversioned" )
+ return NOT_IN_SVN;
+ // TODO Ignored entry should have separate return value probably.
+ if ( wcStatus.attributeNode("item").value() == "ignored" )
+ return NOT_IN_SVN;
+ if ( wcStatus.attributeNode("item").value() == "added" )
+ return LOCALLY_ADDED;
+ if ( wcStatus.attributeNode("item").value() == "deleted" )
+ return LOCALLY_REMOVED;
+ // TODO What to do with "missing", "incomplete", "replaced", "merged",
+ // "obstructed", "external"? Can these appear at all in our case?
+
+ return ERROR_IN_WC;
+
+no_status_xml:
+ if ( !entries.open( IO_ReadOnly ) )
+ return ERROR_IN_WC; // we already know that it is a repository
+
+ // Parse the entries file
+ if ( !doc.setContent( &entries, &errorMsg, &errorLine, &errorCol ) ) {
+ kdDebug() << "Cannot parse .svn/entries file for " << filename << endl
+ << "Line: " << errorLine << " Column: " << errorCol << " Error: " << errorMsg << endl;
+ return ERROR_IN_WC;
+ }
+ entries.close();
+
+ QDomElement element;
+ // File name that we are searching
+ const QString findName = info.fileName();
+ // The entries are <entry> elements, so we have to check them
+ QDomNode child = doc.documentElement().firstChild();
+ for ( ; !child.isNull() ; child = child.nextSibling() )
+ {
+ if ( !child.isElement() )
+ continue;
+ element = child.toElement();
+ if ( element.tagName() != "entry" ) {
+ // We have another kind of element, so skip it
+ // Should not happend with svn 1.1.x
+ continue;
+ }
+ const QString name = element.attribute("name");
+ if ( name == findName )
+ break;
+ }
+
+ if ( child.isNull() ) {
+ // We have not found an entry for the file
+ return NOT_IN_SVN;
+ }
+
+ // ### TODO: should we check the attribute kind to be file and not dir?
+
+ // ### TODO: what do copy and move add here?
+ const QString onSchedule = element.attribute( "schedule" );
+ if ( onSchedule == "delete" )
+ return LOCALLY_REMOVED;
+ else if ( onSchedule == "added" )
+ return LOCALLY_ADDED;
+
+ if ( element.hasAttribute( "conflict-new" ) || element.hasAttribute( "conflict-old" ) || element.hasAttribute( "conflict-wrk" ) ) {
+ return CONFLICT;
+ }
+
+ // Note: we do not check the property time stamp
+ const QString textTimeStamp( element.attribute( "text-time" ) );
+
+ // calculate the UTC time from the file's last modified date
+ struct stat st;
+ lstat( QFile::encodeName(fn), &st );
+ struct tm * tm_p = gmtime( &st.st_mtime );
+ const int year = tm_p->tm_year + 1900;
+ const int month = tm_p->tm_mon + 1;
+ QString fileTime;
+ fileTime.sprintf( "%04i-%02i-%02iT%02i:%02i:%02i.000000Z",
+ year, month, tm_p->tm_mday, tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec );
+ //kdDebug() << "File: " << filename << " SVN time: " << textTimeStamp << " File time: " << fileTime << endl;
+ if ( fileTime > textTimeStamp ) // ISO 8601 dates/times can be compared as strings if they have the exact same format.
+ return LOCALLY_MODIFIED;
+
+ return UP_TO_DATE;
+
+}
+
+QString SVNHandler::svnStatus( const QString& filename ) const
+{
+ return map[filename];
+}
+
+void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates, KSharedConfig* config)
+{
+ // Unlike cvs, svn works also from outside the repository(as long as the path is in a repository of course!)
+ // ### FIXME: wrong, svn commit cannot work if the current directory is not a SVN one
+ execSVNCommand( parent, cmd, QStringList( filename ), templates, config );
+}
+
+void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates, KSharedConfig* config )
+{
+ if ( !_isPORepository ) {
+ // This message box should never be visible but who knows... ;-)
+ KMessageBox::sorry( parent, i18n( "This is not a valid SVN repository. "
+ "The SVN commands cannot be executed." ) );
+ return;
+ }
+
+ // ### TODO: instead of making a QString, use KProcess directly, so that it cares about quoting.
+ // ### TODO: use KProcess::setWorkingDirectory instead of using "cd" (therefore allowing to use KProcess without a shell.)
+ QString command("cd " + (templates ? _potBaseDir : _poBaseDir) + " && svn ");
+ switch ( cmd ) {
+ case SVN::Update:
+ command += "update --non-interactive";
+ break;
+ case SVN::Commit:
+ // The svn client allows to choose the encoding, so we select UTF-8
+ command += "commit -F @LOG@FILE@ --encoding UTF-8 --non-interactive";
+ checkToAdd( files );
+ break;
+ case SVN::StatusRemote:
+ command += "status -u --non-interactive";
+ break;
+ case SVN::StatusLocal:
+ command += "status --non-interactive";
+ break;
+ case SVN::Diff:
+ command += "diff --non-interactive";
+ break;
+ case SVN::Info:
+ command += "info"; // Does not allow --non-interactive (at least svn 1.1.4).
+ }
+
+ QRegExp rx;
+ if (templates)
+ rx.setPattern(_potBaseDir + "/?");
+ else
+ rx.setPattern(_poBaseDir + "/?");
+
+ QStringList::ConstIterator it;
+ for ( it = files.begin( ); it != files.end( ); ++it ) {
+ QString temp = *it;
+ temp.remove(rx);
+ command += " \'" + temp + "\'";
+ }
+
+ showDialog( parent, cmd, files, command, config );
+}
+
+void SVNHandler::setAutoUpdateTemplates( bool update )
+{
+ _autoUpdateTemplates = update;
+}
+
+void SVNHandler::showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config )
+{
+ SVNDialog * dia = new SVNDialog( cmd, parent, config );
+ dia->setFiles( files );
+ dia->setCommandLine( commandLine );
+ if ( cmd == SVN::Commit ) {
+ dia->setAddCommand( _addCommand );
+ }
+
+ if ( dia->exec( ) == KDialog::Accepted ) {
+ if ( cmd == SVN::StatusLocal || cmd == SVN::StatusRemote )
+ processStatusOutput( dia->statusOutput( ) );
+ if ( cmd == SVN::Diff )
+ processDiff( dia->statusOutput( ) );
+ }
+
+ delete dia;
+
+ // file status display update necessary in Catalog Manager
+ if ( cmd == SVN::Commit )
+ emit signalFilesCommitted( files );
+}
+
+bool SVNHandler::isInSvn( const QString& path )
+{
+ if ( path.isEmpty() )
+ return false;
+
+ /*
+ * We need to check if a file is in a SVN repository.
+ *
+ * But as we want to do it quickly (because this function will be called for a few files in a row)
+ * we should avoid to parse the .svn/entries files
+ *
+ * Therefore we only check for the SVN auxilary files that are typical for a file controlled by SVN:
+ * - for a directory: checks if the directory has a .svn/entries file
+ * - for a file: check if there is a corresponding file in .svn/text-base/
+ */
+
+ const QFileInfo info( path );
+ if ( info.isDir() ) {
+ // It is a directory, so find a .svn/entries file
+ QDir dir( path );
+ return dir.exists( ".svn/entries", true );
+ }
+ else {
+ // It is a file, so find the corresponding file in .svn/text-base
+ QDir dir( info.dirPath() );
+ if ( ! dir.cd( ".svn/text-base" ) ) {
+ // There is not even a .svn/text-base directory, so the file is not under control
+ return false;
+ }
+ const QString textBaseFilename( info.fileName() + ".svn-base" );
+ return dir.exists( textBaseFilename, true );
+ }
+}
+
+void SVNHandler::checkToAdd( const QStringList& files )
+{
+ if ( files.isEmpty( ) )
+ return;
+
+ QStringList toBeAdded;
+
+ QStringList::ConstIterator it;
+ for ( it = files.begin( ); it != files.end( ); ++it ) {
+ // check for every entry if it needs to be added
+ if ( ! isInSvn( *it ) ) {
+ QFileInfo info( *it );
+ QString temp; // will hold the dir path
+ if ( info.isDir( ) ) {
+ toBeAdded << *it;
+ temp = *it;
+ } else {
+ toBeAdded << *it;
+ temp = QFileInfo( *it ).dirPath( true );
+ }
+
+ // ### TODO: does SVN really needs this or does it do it automatically?
+ // check recursivlely if parent dirs have to be added as well
+ while ( ! isInSvn( temp ) && toBeAdded.findIndex( temp ) == -1 ) {
+ toBeAdded << temp;
+ temp = QFileInfo( temp ).dirPath( true );
+ }
+
+ }
+ }
+
+ // remove an old command
+ _addCommand = QString();
+
+ // ### TODO: does SVN really need this?
+ // make sure the directories are added before the files
+ toBeAdded.sort( );
+
+ // ### TODO: try to make this better
+ // create a command line for adding the files and dirs
+ for ( it = toBeAdded.begin( ); it != toBeAdded.end( ); ++it ) {
+ QFileInfo info( *it );
+ _addCommand += "cd " + info.dirPath( true ) + " && svn add " + info.fileName( ) + "; ";
+ }
+}
+
+// ### TODO: convert to SVN
+void SVNHandler::processStatusOutput( const QString& status )
+{
+ if ( !_isPORepository )
+ return;
+
+#if 0
+ // at first we need to extract the name of the base directory on the server
+ QFile f( _poBaseDir + "/SVN/Root" ); // ### FIXME
+ if ( !f.open( IO_ReadOnly ) )
+ return;
+
+ QTextStream stream( &f );
+ // extract the string after the last colon in the first line
+ QString basedir = stream.readLine( ).section( ':', -1 );
+
+ f.close( );
+
+ // divide the complete status output in little chunks for every file
+ QStringList entries = QStringList::split( QRegExp( "={67,67}" ), status );
+ QStringList::Iterator it;
+ for ( it = entries.begin( ); it != entries.end( ); ++it ) {
+ QString entr = *it;
+ // translate the filename from repository to local
+ QRegExp rx( basedir + ".*,v" );
+ int pos = entr.find( rx );
+ QString file = _poBaseDir + entr.mid( pos + basedir.length( ),
+ rx.matchedLength( ) - basedir.length( ) - 2 );
+
+ entr = "<qt>" + entr + "</qt>";
+
+ // TODO: do some markup
+
+ map.replace( file, entr );
+ }
+#endif
+}
+
+void SVNHandler::processDiff( QString output )
+{
+ output.remove( QRegExp( "\\[ .* \\]$" ));
+ output.remove( QRegExp( "^" + i18n("[ Starting command ]" ).replace("[","\\[").replace("]","\\]")));
+
+ KTempFile tmpFile;
+ *(tmpFile.textStream()) << output;
+ tmpFile.close();
+
+ QString error;
+ if ( KApplication::startServiceByName( "Kompare", tmpFile.name(), &error ) )
+ KMessageBox::error( 0, error );
+}
+
+bool SVNHandler::isConsideredModified( const FileStatus status ) const
+{
+ /*
+ * A file is modified if it is either:
+ * - locally modified for SVN
+ * - directory under SVN control but not the file
+ */
+
+ // ### TODO: what about moved and copied?
+ return status == LOCALLY_MODIFIED || status == NOT_IN_SVN;
+}
+
+SVNOutputCollector::SVNOutputCollector( KProcess* p )
+ : m_process(0)
+{
+ setProcess( p );
+}
+
+void SVNOutputCollector::setProcess( KProcess* p )
+{
+ if( m_process )
+ m_process->disconnect( this );
+
+ m_process = p;
+ if( p ) {
+ connect( p, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotGatherStdout(KProcess*, char*, int)) );
+ connect( p, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotGatherStderr(KProcess*, char*, int)) );
+ }
+
+ m_gatheredOutput.truncate( 0 );
+ m_stderrOutput.truncate( 0 );
+ m_stdoutOutput.truncate( 0 );
+}
+
+void SVNOutputCollector::slotGatherStderr( KProcess*, char* data, int len )
+{
+ m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) );
+ m_stderrOutput.append( QString::fromLocal8Bit( data, len ) );
+}
+
+void SVNOutputCollector::slotGatherStdout( KProcess*, char* data, int len )
+{
+ m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) );
+ m_stdoutOutput.append( QString::fromLocal8Bit( data, len ) );
+}
+
+#include "svnhandler.moc"
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kbabel/catalogmanager/libsvn/svnhandler.h b/kbabel/catalogmanager/libsvn/svnhandler.h
new file mode 100644
index 00000000..67c86d73
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/svnhandler.h
@@ -0,0 +1,138 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005, 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.
+
+**************************************************************************** */
+
+
+#ifndef SVNHANDLER_H
+#define SVNHANDLER_H
+
+// Qt include files
+#include <qmap.h>
+#include <qobject.h>
+// Project specific include files
+#include "svndialog.h"
+#include "svnresources.h"
+// Forwarding Qt classes
+class QString;
+class QStringList;
+
+class KSharedConfig;
+
+/**
+ * This class is the backend for SVN support in Catalog Manager.
+ *
+ * @short Backend for SVN support in Catalog Manager
+ */
+class SVNHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum FileStatus {
+ NO_REPOSITORY,
+ NOT_IN_SVN,
+ LOCALLY_ADDED,
+ LOCALLY_REMOVED,
+ LOCALLY_MODIFIED,
+ CONFLICT,
+ UP_TO_DATE,
+ ERROR_IN_WC ///< The working copy has data that cannot be handled
+ };
+
+ SVNHandler( const QString& poBaseDir = QString::null, const QString& potBaseDir = QString::null );
+
+ void setPOBaseDir( const QString& dir );
+ void setPOTBaseDir( const QString& dir );
+
+ FileStatus fstatus( const QString& filename ) const;
+ QString fileStatus( const FileStatus status ) const;
+ QString svnStatus( const QString& filename ) const;
+
+ void execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates, KSharedConfig* config );
+ void execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates, KSharedConfig* config );
+
+ void setAutoUpdateTemplates( bool update );
+
+ /**
+ * True if the file was modified or has another status considered as a modification
+ */
+ bool isConsideredModified( const FileStatus status ) const;
+
+ signals:
+ void signalIsPORepository( bool );
+ void signalIsPOTRepository( bool );
+ void signalFilesCommitted( const QStringList& );
+
+ private:
+ void showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config );
+ /// Check quickly if the file is part of a SVN repository
+ bool isInSvn( const QString& path );
+ void checkToAdd( const QStringList& files );
+ void processStatusOutput( const QString& status );
+ void processDiff( QString output );
+
+ private:
+ QString _poBaseDir;
+ QString _potBaseDir;
+ bool _isPORepository;
+ bool _isPOTRepository;
+ bool _autoUpdateTemplates;
+ QString _addCommand;
+
+ /** Mapping the output of 'svn status' against the filename. */
+ QMap<QString,QString> map;
+};
+
+class SVNOutputCollector: public QObject
+{
+ Q_OBJECT
+
+ public:
+ SVNOutputCollector( KProcess* );
+ void setProcess( KProcess* );
+
+ const QString& getOutput() const { return m_gatheredOutput; }
+ const QString& getStderr() const { return m_stderrOutput; }
+ const QString& getStdout() const { return m_stdoutOutput; }
+
+ private slots:
+ void slotGatherStderr( KProcess*, char*, int );
+ void slotGatherStdout( KProcess*, char*, int );
+
+ private:
+ QString m_gatheredOutput;
+ QString m_stderrOutput;
+ QString m_stdoutOutput;
+ KProcess* m_process;
+};
+
+#endif // SVNHANDLER_H
diff --git a/kbabel/catalogmanager/libsvn/svnresources.h b/kbabel/catalogmanager/libsvn/svnresources.h
new file mode 100644
index 00000000..d9032a4f
--- /dev/null
+++ b/kbabel/catalogmanager/libsvn/svnresources.h
@@ -0,0 +1,50 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-2003 by Marco Wegner <mail@marcowegner.de>
+ Copyright (C) 2005 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.
+
+**************************************************************************** */
+
+
+#ifndef SVNRESOURCES_H
+#define SVNRESOURCES_H
+
+namespace SVN {
+ enum Command
+ {
+ Update, ///< svn update
+ Commit, ///< svn commit
+ StatusLocal, ///< svn status
+ StatusRemote, ///< svn status -u
+ Diff, ///< svn diff
+ Info ///< svn info
+ };
+}
+
+#endif // SVNRESOURCES_H
diff --git a/kbabel/catalogmanager/lo16-app-catalogmanager.png b/kbabel/catalogmanager/lo16-app-catalogmanager.png
new file mode 100644
index 00000000..27a7f453
--- /dev/null
+++ b/kbabel/catalogmanager/lo16-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/lo32-app-catalogmanager.png b/kbabel/catalogmanager/lo32-app-catalogmanager.png
new file mode 100644
index 00000000..eef514b4
--- /dev/null
+++ b/kbabel/catalogmanager/lo32-app-catalogmanager.png
Binary files differ
diff --git a/kbabel/catalogmanager/main.cpp b/kbabel/catalogmanager/main.cpp
new file mode 100644
index 00000000..868df92a
--- /dev/null
+++ b/kbabel/catalogmanager/main.cpp
@@ -0,0 +1,232 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2001-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 "kbprojectmanager.h"
+#include "catalogmanager.h"
+#include "catalogmanageriface.h"
+#include "catalog.h"
+#include "catalogmanagerapp.h"
+#include "poinfo.h"
+
+#include "version.h"
+#include "resources.h"
+
+#include <dcopclient.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kwin.h>
+#include <kmainwindow.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+CatalogManager *CatalogManagerApp::_view = 0;
+
+CatalogManagerApp::CatalogManagerApp()
+ : KApplication()
+{
+ kbInterface = new CatalogManagerInterface;
+ _view = 0;
+ _preferredWindow = 0;
+}
+
+CatalogManagerApp::~CatalogManagerApp()
+{
+ delete kbInterface;
+ KBabel::PoInfo::cacheWrite();
+}
+
+void CatalogManagerApp::setPreferredWindow(WId id)
+{
+ _preferredWindow = id;
+ if( _view )
+ {
+ _view->raise();
+ KWin::activateWindow(_view->winId());
+ }
+}
+
+void CatalogManagerApp::updatedFile(QCString url)
+{
+ if( _view )
+ _view->updateFile(url);
+}
+
+QCString CatalogManagerApp::findNextFile()
+{
+ QString reply = "";
+ if( !CatalogManager::_foundFilesList.isEmpty() )
+ {
+ reply = CatalogManager::_foundFilesList.first();
+ CatalogManager::_foundFilesList.pop_front();
+ if( _view ) _view->decreaseNumberOfFound();
+ } else
+ {
+ if( !CatalogManager::_toBeSearched.isEmpty() )
+ reply = QString(""); // nothing found yet
+ else
+ return QCString(); // not found definitely
+ }
+
+ return reply.utf8();
+}
+
+int CatalogManagerApp::newInstance()
+{
+ if( isRestored() )
+ {
+ int n = 1;
+ while (KMainWindow::canBeRestored(n)){
+ CatalogManager* cm = new CatalogManager();
+ cm->restore(n);
+ n++;
+
+ // this view will be used as DCOP dispatcher
+ if( !_view )
+ _view = cm;
+ }
+ }
+ else
+ {
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ QString configfile = args->getOption("project");
+
+ if( !configfile.isEmpty() )
+ {
+ QFileInfo fi( configfile );
+ configfile = fi.absFilePath();
+ }
+ else
+ {
+ configfile = KBabel::ProjectManager::defaultProjectName();
+ }
+
+ _view=new CatalogManager(configfile);
+
+ _view->setPreferredWindow( _preferredWindow );
+ _view->show();
+ _view->raise();
+ KWin::activateWindow(_view->winId());
+
+ args->clear();
+ }
+
+ return 0;
+}
+
+CatalogManagerInterface::CatalogManagerInterface()
+ : DCOPObject("CatalogManagerIFace")
+{
+}
+
+void CatalogManagerInterface::setPreferredWindow( WId id )
+{
+ CatalogManagerApp::setPreferredWindow(id);
+}
+
+QCString CatalogManagerInterface::findNextFile()
+{
+ return CatalogManagerApp::findNextFile();
+}
+
+void CatalogManagerInterface::updatedFile( QCString url )
+{
+ CatalogManagerApp::updatedFile(url);
+}
+
+static KCmdLineOptions options[] =
+{
+ {"project <configfile>",I18N_NOOP("File to load configuration from"),0},
+ KCmdLineLastOption
+};
+
+
+int main(int argc, char **argv)
+{
+ KLocale::setMainCatalogue("kbabel");
+ KAboutData about("catalogmanager",I18N_NOOP("KBabel - Catalog Manager"),VERSION,
+ I18N_NOOP("An advanced catalog manager for KBabel"),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("Stanislav Visnovsky",I18N_NOOP("Current maintainer, porting to KDE3/Qt3.")
+ ,"visnovsky@kde.org");
+ 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@kde.org");
+ 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("Wolfram Diestel"
+ ,I18N_NOOP("Wrote diff algorithm, fixed KSpell and gave a lot "
+ "of useful hints."),"wolfram@steloj.de");
+ 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("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("Bram Schoenmakers",I18N_NOOP("Support for making diffs and some minor "
+ "improvements."),"bramschoenmakers@kde.nl");
+
+ about.addCredit("Trolltech", I18N_NOOP("KBabel contains code from Qt"), 0, "http://www.trolltech.com");
+
+ about.addCredit("GNU gettext", I18N_NOOP("KBabel contains code from GNU gettext"), 0, "http://www.gnu.org/software/gettext/");
+
+ // Initialize command line args
+ KCmdLineArgs::init(argc, argv, &about);
+
+ // Tell which options are supported
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ // Add options from other components
+ KApplication::addCmdLineOptions();
+
+ CatalogManagerApp app;
+
+ app.newInstance();
+
+ return app.exec();
+}
diff --git a/kbabel/catalogmanager/markpatterndialog.cpp b/kbabel/catalogmanager/markpatterndialog.cpp
new file mode 100644
index 00000000..efe893a2
--- /dev/null
+++ b/kbabel/catalogmanager/markpatterndialog.cpp
@@ -0,0 +1,172 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2003 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 <qcheckbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+
+#include <kcombobox.h>
+#include <kcompletion.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kparts/componentfactory.h>
+#include <kregexpeditorinterface.h>
+
+#include "markpatterndialog.h"
+#include "markpatternwidget.h"
+
+MarkPatternDialog::MarkPatternDialog(QWidget * parent, const char * name)
+ : KDialogBase(parent, name, true, 0, Ok|Cancel, Ok)
+{
+ actionButton(Ok)->setEnabled(false);
+
+ mainWidget = new MarkPatternWidget(this);
+
+ connect (mainWidget->combo, SIGNAL(textChanged(const QString&)),
+ this, SLOT(slotComboTextChanged(const QString&)));
+
+ comboCompletion = mainWidget->combo->completionObject( );
+
+ regexpEditDialog = 0;
+ if (!KTrader::self( )->query("KRegExpEditor/KRegExpEditor").isEmpty( )) {
+ connect(mainWidget->regexpButton, SIGNAL(clicked( )), this, SLOT(slotRegexpButtonClicked( )));
+ } else {
+ disconnect(mainWidget->useRegExp, 0, mainWidget->regexpButton, 0);
+ delete mainWidget->regexpButton;
+ mainWidget->regexpButton = 0;
+ }
+
+ restoreSettings( );
+
+ actionButton(Ok)->setEnabled(!mainWidget->combo->currentText( ).isEmpty( ));
+ mainWidget->combo->setFocus( );
+ setMainWidget( mainWidget);
+}
+
+void MarkPatternDialog::accept( )
+{
+ // Update the list of patterns.
+ patternList.remove(mainWidget->combo->currentText( ));
+ patternList.prepend(mainWidget->combo->currentText( ));
+ while (patternList.count( ) > 10)
+ patternList.remove(patternList.last( ));
+
+ saveSettings( );
+ KDialogBase::accept( );
+}
+
+QString MarkPatternDialog::pattern( )
+{
+ return mainWidget->combo->currentText( );
+}
+
+bool MarkPatternDialog::isCaseSensitive( )
+{
+ return mainWidget->caseSensitive->isChecked( );
+}
+
+bool MarkPatternDialog::includeTemplates( )
+{
+ return mainWidget->inclTemplates->isChecked( );
+}
+
+bool MarkPatternDialog::useRegExp( )
+{
+ return mainWidget->useRegExp->isChecked( );
+}
+
+void MarkPatternDialog::setMode(bool markMode)
+{
+ if (markMode) {
+ mainWidget->mainLabel->setText(i18n("Ma&rk files which match the following pattern:"));
+ setButtonOKText(i18n("&Mark Files"));
+ } else {
+ mainWidget->mainLabel->setText(i18n("Unma&rk files which match the following pattern:"));
+ setButtonOKText(i18n("Un&mark Files"));
+ }
+}
+
+void MarkPatternDialog::slotComboTextChanged(const QString& text)
+{
+ actionButton(Ok)->setEnabled(!text.isEmpty( ));
+}
+
+void MarkPatternDialog::slotRegexpButtonClicked( )
+{
+ if (!regexpEditDialog)
+ regexpEditDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>(
+ "KRegExpEditor/KRegExpEditor", QString::null, this);
+
+ KRegExpEditorInterface * iface = dynamic_cast<KRegExpEditorInterface *>(regexpEditDialog);
+
+ if (iface) {
+ iface->setRegExp(mainWidget->combo->currentText( ));
+ if (regexpEditDialog->exec( ) == QDialog::Accepted)
+ mainWidget->combo->setCurrentText(iface->regExp( ));
+ }
+}
+
+void MarkPatternDialog::restoreSettings( )
+{
+ KConfig * config = KGlobal::config( );
+ config->setGroup("MarkPatternDialog");
+
+ patternList = config->readListEntry("Patterns");
+ mainWidget->combo->insertStringList(patternList);
+ comboCompletion->insertItems(patternList);
+ mainWidget->caseSensitive->setChecked(config->readBoolEntry("CaseSensitive", false));
+ mainWidget->inclTemplates->setChecked(config->readBoolEntry("IncludeTemplates", false));
+
+ bool rx = config->readBoolEntry("UseRegExp", false);
+ if (rx)
+ mainWidget->useRegExp->setChecked(true);
+ else
+ mainWidget->useWildcards->setChecked(true);
+ if (mainWidget->regexpButton)
+ mainWidget->regexpButton->setEnabled(mainWidget->useRegExp->isChecked( ));
+}
+
+void MarkPatternDialog::saveSettings( )
+{
+ KConfig * config = KGlobal::config( );
+ config->setGroup("MarkPatternDialog");
+
+ config->writeEntry("Patterns", patternList);
+ config->writeEntry("CaseSensitive", mainWidget->caseSensitive->isChecked( ));
+ config->writeEntry("IncludeTemplates", mainWidget->inclTemplates->isChecked( ));
+ config->writeEntry("UseRegExp", mainWidget->useRegExp->isChecked( ));
+}
+
+#include "markpatterndialog.moc"
diff --git a/kbabel/catalogmanager/markpatterndialog.h b/kbabel/catalogmanager/markpatterndialog.h
new file mode 100644
index 00000000..c8ec1218
--- /dev/null
+++ b/kbabel/catalogmanager/markpatterndialog.h
@@ -0,0 +1,75 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2003 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 MARKPATTERNDIALOG_H
+#define MARKPATTERNDIALOG_H
+
+#include <kdialogbase.h>
+
+class KCompletion;
+
+class MarkPatternWidget;
+
+class MarkPatternDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ MarkPatternDialog(QWidget * parent, const char * name = 0);
+
+ QString pattern( );
+ bool isCaseSensitive( );
+ bool useRegExp( );
+ bool includeTemplates( );
+
+ void setMode(bool markMode);
+
+ protected:
+ virtual void accept( );
+ void restoreSettings( );
+ void saveSettings( );
+
+ protected slots:
+ void slotComboTextChanged(const QString& text);
+ void slotRegexpButtonClicked( );
+
+ private:
+ MarkPatternWidget * mainWidget;
+ QDialog * regexpEditDialog;
+
+ QStringList patternList;
+
+ KCompletion * comboCompletion;
+};
+
+#endif // MARKPATTERNDIALOG_H
diff --git a/kbabel/catalogmanager/markpatternwidget.ui b/kbabel/catalogmanager/markpatternwidget.ui
new file mode 100644
index 00000000..b4b8745e
--- /dev/null
+++ b/kbabel/catalogmanager/markpatternwidget.ui
@@ -0,0 +1,127 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>MarkPatternWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MarkPatternWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>374</width>
+ <height>276</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>mainLabel</cstring>
+ </property>
+ <property name="text">
+ <string>To be set dynamically:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>combo</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>combo</cstring>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>caseSensitive</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ase sensitive</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>inclTemplates</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Include templates</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>useWildcards</cstring>
+ </property>
+ <property name="text">
+ <string>Use &amp;wildcards</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>regexpButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Edit</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="4" column="0">
+ <property name="name">
+ <cstring>useRegExp</cstring>
+ </property>
+ <property name="text">
+ <string>Use regu&amp;lar expression</string>
+ </property>
+ </widget>
+ <widget class="Line" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>useRegExp</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>regexpButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in implementation">kcombobox.h</include>
+</includes>
+<forwards>
+ <forward>class KComboBox;</forward>
+</forwards>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/catalogmanager/multiroughtransdlg.cpp b/kbabel/catalogmanager/multiroughtransdlg.cpp
new file mode 100644
index 00000000..874b9c3e
--- /dev/null
+++ b/kbabel/catalogmanager/multiroughtransdlg.cpp
@@ -0,0 +1,148 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 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 "catalog.h"
+#include "catmanlistitem.h"
+#include "multiroughtransdlg.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprogress.h>
+#include <kurl.h>
+
+using namespace KBabel;
+
+MultiRoughTransDlg::MultiRoughTransDlg(KBabelDictBox *dict, QPtrList<CatManListItem> files
+ , QWidget *parent,const char *name)
+ : RoughTransDlg(dict, new Catalog(), parent, name )
+ ,_fileList(files)
+{
+ QWidget* bars = static_cast<QWidget*>(progressbar->parent());
+ QLabel* label = new QLabel( i18n("Files:"), bars );
+ filesProgressbar = new KProgress(bars,"files progressbar");
+ filesProgressbar->setTextEnabled(true);
+ filesProgressbar->setFormat("%v/%m (%p%)");
+ filesProgressbar->setTotalSteps(files.count());
+ QHBoxLayout* mylayout= new QHBoxLayout(bars->layout());
+ mylayout->add(label);
+ mylayout->add(filesProgressbar);
+
+ msgButtonClicked(0);
+}
+
+void MultiRoughTransDlg::msgButtonClicked(int id)
+{
+ RoughTransDlg::msgButtonClicked(id);
+
+ enableButton(User1,true);
+}
+
+void MultiRoughTransDlg::translate()
+{
+ for ( CatManListItem* it = _fileList.first(); it ; it = _fileList.next() )
+ {
+ if( it->hasPo() )
+ {
+ KURL url( it->poFile() );
+ if( catalog->openURL( url ) != OK )
+ {
+ KMessageBox::error(this, i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid PO file.").arg(url.prettyURL()));
+ filesProgressbar->advance(1);
+ continue;
+ }
+ } else
+ if( it->hasPot() )
+ {
+ KURL url( it->poFile() );
+ KURL poturl( it->potFile() );
+ if( catalog->openURL( poturl, url ) != OK )
+ {
+ KMessageBox::error(this, i18n("Error while trying to read file:\n %1\n"
+ "Maybe it is not a valid PO file.").arg(poturl.prettyURL()));
+ filesProgressbar->advance(1);
+ continue;
+ }
+ }
+
+ RoughTransDlg::translate();
+
+ if( stop || cancel ) break;
+
+ if( catalog->isModified() ) catalog->saveFile();
+
+ it->forceUpdate();
+ filesProgressbar->advance(1);
+ }
+
+ filesProgressbar->setValue(_fileList.count());
+
+ showAllStatistics();
+}
+
+void MultiRoughTransDlg::showAllStatistics()
+{
+ int tt, ptc, etc;
+
+ statistics( tt, ptc, etc);
+
+ // sanity check
+ if( tt == 0 ) tt = 1;
+
+ int nothing=tt-ptc-etc;
+ KLocale *locale = KGlobal::locale();
+ QString statMsg = i18n("Result of the translation:\n"
+ "Edited entries: %1\n"
+ "Exact translations: %2 (%3%)\n"
+ "Approximate translations: %4 (%5%)\n"
+ "Nothing found: %6 (%7%)")
+ .arg( locale->formatNumber(tt,0) )
+ .arg( locale->formatNumber(etc,0) )
+ .arg( locale->formatNumber( ((double)(10000*etc/tt))/100) )
+ .arg( locale->formatNumber(ptc,0) )
+ .arg( locale->formatNumber(((double)(10000*ptc/tt))/100) )
+ .arg( locale->formatNumber(nothing,0) )
+ .arg( locale->formatNumber(((double)(10000*nothing/tt)/100) ) );
+
+ KMessageBox::information(this, statMsg
+ , i18n("Rough Translation Statistics"));
+
+ accept();
+}
+
+#include "multiroughtransdlg.moc"
diff --git a/kbabel/catalogmanager/multiroughtransdlg.h b/kbabel/catalogmanager/multiroughtransdlg.h
new file mode 100644
index 00000000..8bda58e2
--- /dev/null
+++ b/kbabel/catalogmanager/multiroughtransdlg.h
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ 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 MULTIROUGHTRANSDLG_H
+#define MULTIROUGHTRANSDLG_H
+
+#include <roughtransdlg.h>
+
+class CatManListItem;
+
+class MultiRoughTransDlg : public RoughTransDlg
+{
+ Q_OBJECT
+
+public:
+ MultiRoughTransDlg(KBabelDictBox* dictBox, QPtrList<CatManListItem> list, QWidget *parent
+ , const char *name=0);
+
+protected slots:
+ virtual void translate();
+ // we show statistics at different point
+ virtual void showStatistics() {}
+ virtual void showAllStatistics();
+
+ // we need to enable Start button at different conditions
+ virtual void msgButtonClicked(int);
+
+private:
+
+ QPtrList<CatManListItem> _fileList;
+ KProgress *filesProgressbar;
+};
+
+#endif // ROUGHTRANSDLG_H
diff --git a/kbabel/catalogmanager/validateprogress.cpp b/kbabel/catalogmanager/validateprogress.cpp
new file mode 100644
index 00000000..9075f24e
--- /dev/null
+++ b/kbabel/catalogmanager/validateprogress.cpp
@@ -0,0 +1,313 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 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 "validateprogress.h"
+#include "validateprogresswidget.h"
+#include "catmanlistitem.h"
+#include "catmanresource.h"
+
+#include <kdebug.h>
+#include <kdatatool.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kprogress.h>
+#include <ksqueezedtextlabel.h>
+
+#include <qlistbox.h>
+#include <qtimer.h>
+
+#define ID_ERROR_OPEN 1
+#define ID_ERROR_IGNORE 2
+
+// version identification for validation ignores
+#define IGNOREFILE_VERSION 0x00
+
+ValidateProgressDialog::ValidateProgressDialog(const QString& ignoreURL, QWidget *parent,const char *name)
+ : KDialogBase(parent,name,true,i18n("Caption of dialog","Validation")
+ , Close, Close)
+ , _ignoreURL(ignoreURL), _tool(0), _stopped(false)
+ , _ignoreFuzzy(false), _setAsFuzzy(false)
+
+{
+ _mainWidget = new ValidateProgressWidget(this);
+ setMainWidget(_mainWidget);
+ setInitialSize( QSize(400, 300) );
+
+ _errors.clear();
+ _ignores.clear();
+
+ readIgnores();
+
+ _errorMenu = new KPopupMenu(this);
+ _errorMenu->insertItem(i18n("&Open"),ID_ERROR_OPEN);
+ _errorMenu->insertItem(i18n("&Ignore"),ID_ERROR_IGNORE);
+
+ connect( this, SIGNAL(closeClicked()), this, SLOT(stop()));
+ connect( _mainWidget->_errorList, SIGNAL( doubleClicked(QListBoxItem *)),
+ this, SLOT( errorItemDoubleClicked(QListBoxItem *)));
+
+ connect( _mainWidget->_errorList, SIGNAL( contextMenuRequested(QListBoxItem *, const QPoint &)),
+ this, SLOT( showContextMenu(QListBoxItem *, const QPoint &)));
+}
+
+ValidateProgressDialog::~ValidateProgressDialog()
+{
+ writeIgnores();
+}
+
+void ValidateProgressDialog::validate( const KDataToolInfo &tool, const QPtrList<CatManListItem> files )
+{
+ if( files.isEmpty() ) return;
+
+ _errors.clear();
+
+ KDataTool* t = tool.createTool();
+
+ if( !t )
+ {
+ KMessageBox::error( this, i18n("Cannot instantiate a validation tool.\n"
+ "Please check your installation."), i18n("Validation Tool Error") );
+ return;
+ }
+
+ _tool = t;
+ _toolID = tool.service()->library();
+ _files = files;
+
+ _mainWidget->_errorList->clear();
+ _mainWidget->_currentTool->setText(*(tool.userCommands().at(0)));
+ _mainWidget->_overallProgress->setTotalSteps(files.count());
+ _mainWidget->_overallProgress->setValue(0);
+
+ _stopped = false;
+
+ QTimer::singleShot( 0, this, SLOT(validate_internal()) );
+
+ exec();
+
+ _stopped = true;
+}
+
+void ValidateProgressDialog::validate_internal()
+{
+ uint checked=0;
+ uint errors=0;
+ uint ignorederrors=0;
+
+ for( CatManListItem* it=_files.first() ; it && !_stopped ; it = _files.next() )
+ {
+ _mainWidget->_currentFile->setText( it->poFile() );
+
+ checked++;
+
+ _mainWidget->_currentFileProgress->setTotalSteps(100);
+ _mainWidget->_currentFileProgress->setValue(0);
+
+ it->checkErrors(_tool,_mainWidget, _ignoreFuzzy, _setAsFuzzy);
+
+ bool noHeader = true;
+
+ if( it->hasErrors() )
+ {
+ QValueList<IgnoreItem> err = it->errors();
+
+ for( QValueList<IgnoreItem>::Iterator errit = err.begin(); errit!=err.end() ; ++errit )
+ {
+ IgnoreItem item = (*errit);
+
+ QValueList<IgnoreItem>::Iterator ig;
+ for( ig = _ignores.begin() ; ig != _ignores.end() ; ++ig )
+ {
+ if( (*ig).validationTool == _toolID &&
+ (*ig).msgid == item.msgid &&
+ (*ig).msgstr == item.msgstr &&
+ (*ig).fileURL == item.fileURL ) break;
+ }
+
+ if( ig != _ignores.end() )
+ {
+ ++ignorederrors;
+ continue;
+ } ++errors;
+
+ if( noHeader )
+ {
+ _mainWidget->_errorList->insertItem( ICON_ERROR, it->package() );
+ _errors.insert( it->package(), err.first() );
+ noHeader = false;
+ }
+
+ QString errortext=QString::number(item.index+1)+": " + item.msgid.first().left(50);
+ errortext.replace("\n"," ");
+ if( item.msgid.first().length() > 50 ) errortext+="...";
+ _mainWidget->_errorList->insertItem( errortext);
+
+ _errors.insert( errortext, item );
+ }
+ }
+
+ _mainWidget->_currentFileProgress->setValue(100);
+
+ _mainWidget->_overallProgress->advance(1);
+ }
+
+ if( !_stopped )
+ {
+ KMessageBox::information(this, i18n("Validation done.\n"
+ "\n"
+ "Checked files: %1\n"
+ "Number of errors: %2\n"
+ "Number of ignored errors: %3").arg(checked).arg(errors).arg(ignorederrors),i18n("Validation Done"));
+ }
+
+ delete _tool;
+ _tool = 0;
+ _files.clear();
+}
+
+void ValidateProgressDialog::stop()
+{
+ _stopped = true;
+}
+
+void ValidateProgressDialog::errorItemDoubleClicked(QListBoxItem * item)
+{
+ QString it = item->text();
+
+ bool ok =false;
+ int offset = it.find(":");
+
+ int num;
+ if( offset < -1 ) num = 0;
+ else
+ {
+ num = it.left(offset).toInt(&ok);
+ if( !ok ) num = 0;
+ }
+
+ QListBoxItem* package=item;
+
+ while( package && !package->text().startsWith("/") ) package=package->prev();
+
+ if( !package )
+ {
+ kdWarning() << "Unable to find the package for the error" << endl;
+ return;
+ }
+
+ emit errorDoubleClicked(package->text(), num-1 );
+}
+
+void ValidateProgressDialog::showContextMenu(QListBoxItem * item, const QPoint & pos)
+{
+ // disable ignore for whole package
+ _errorMenu->setItemEnabled(ID_ERROR_IGNORE, item->pixmap()==0 );
+ int result = _errorMenu->exec(pos);
+ switch( result )
+ {
+ case ID_ERROR_OPEN:
+ errorItemDoubleClicked( item );
+ break;
+ case ID_ERROR_IGNORE:
+ IgnoreItem it = _errors.find(item->text()).data();
+
+ // if there is no pixmap, it's the whole file
+ if( !item->pixmap() )
+ {
+ it.validationTool = _toolID;
+ _ignores.append( it );
+ }
+ break;
+ }
+}
+
+void ValidateProgressDialog::readIgnores()
+{
+ IgnoreItem item;
+
+ QFile ignoreFile( _ignoreURL );
+ if( ignoreFile.open( IO_ReadOnly ) ) {
+ QDataStream s( &ignoreFile );
+ QString url;
+ int version;
+
+ s >> version;
+ if( version == IGNOREFILE_VERSION ) // Only read if correct versi
+ {
+ _ignores.clear();
+
+ while( !s.atEnd() ) {
+ s >> item;
+ _ignores.append(item);
+ }
+ }
+ ignoreFile.close();
+ }
+}
+
+void ValidateProgressDialog::writeIgnores()
+{
+ QFile ignoreFile( _ignoreURL );
+ if( ignoreFile.open( IO_WriteOnly ) ) {
+ QDataStream s( &ignoreFile );
+ QString url;
+ int version = IGNOREFILE_VERSION;
+
+ s << version;
+
+ for( QValueList<IgnoreItem>::Iterator it = _ignores.begin(); it!=_ignores.end(); ++it)
+ {
+ s << (*it);
+ }
+ ignoreFile.close();
+ }
+}
+
+QDataStream & operator<<( QDataStream & stream, const IgnoreItem & i )
+{
+ return stream << i.fileURL
+ << i.msgid
+ << i.msgstr
+ << i.index
+ << i.validationTool;
+}
+
+QDataStream & operator>>( QDataStream & stream, IgnoreItem & i ) {
+ return stream >> i.fileURL
+ >> i.msgid
+ >> i.msgstr
+ >> i.index
+ >> i.validationTool;
+}
+
+#include "validateprogress.moc"
diff --git a/kbabel/catalogmanager/validateprogress.h b/kbabel/catalogmanager/validateprogress.h
new file mode 100644
index 00000000..05133889
--- /dev/null
+++ b/kbabel/catalogmanager/validateprogress.h
@@ -0,0 +1,109 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2002-203 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 VALIDATEDLG_H
+#define VALIDATEDLG_H
+
+#include <qmap.h>
+
+#include <kdialogbase.h>
+#include <kurl.h>
+
+class CatManListItem;
+class ValidateProgressWidget;
+class KDataToolInfo;
+class KDataTool;
+class KPopupMenu;
+
+struct IgnoreItem
+{
+ KURL fileURL;
+ QStringList msgid;
+ QStringList msgstr;
+ uint index;
+ QString validationTool;
+};
+
+QDataStream & operator<<( QDataStream & stream, const IgnoreItem &ident );
+QDataStream & operator>>( QDataStream & stream, IgnoreItem & ident);
+
+class ValidateProgressDialog : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ ValidateProgressDialog(const QString& ignoreURL, QWidget* parent, const char *name=0);
+ virtual ~ValidateProgressDialog();
+
+ void setIgnoreFuzzy(bool enable) { _ignoreFuzzy = enable; }
+ void setMarkAsFuzzy(bool enable) { _setAsFuzzy = enable; }
+
+public slots:
+ void validate(const KDataToolInfo &tool, const QPtrList<CatManListItem> files);
+
+signals:
+ void errorDoubleClicked(const QString file, const int messageNumber);
+
+private slots:
+ /** implementation of the validation itself */
+ void validate_internal();
+
+ /** call this to stop current validation*/
+ void stop();
+
+ /** If user doubleclicked an item, this slot will be invoked.
+ * It emits errorDoubleClicked signal for corresponding error*/
+ void errorItemDoubleClicked(QListBoxItem * item);
+
+ /** show our context menu */
+ void showContextMenu(QListBoxItem * item, const QPoint & pos);
+
+private:
+ void readIgnores();
+ void writeIgnores();
+
+ ValidateProgressWidget *_mainWidget;
+ QString _ignoreURL;
+ KDataTool* _tool;
+ QString _toolID;
+ QPtrList<CatManListItem> _files;
+ bool _stopped;
+ KPopupMenu* _errorMenu;
+
+ bool _ignoreFuzzy;
+ bool _setAsFuzzy;
+
+ QValueList<IgnoreItem> _ignores;
+ QMap<QString,IgnoreItem> _errors;
+};
+
+#endif // VALIDATEDLG_H
diff --git a/kbabel/catalogmanager/validateprogresswidget.ui b/kbabel/catalogmanager/validateprogresswidget.ui
new file mode 100644
index 00000000..a181806b
--- /dev/null
+++ b/kbabel/catalogmanager/validateprogresswidget.ui
@@ -0,0 +1,129 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>ValidateProgressWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ValidateProgressWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>448</width>
+ <height>295</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>_currentAction</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>92</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Current:</string>
+ </property>
+ </widget>
+ <widget class="KProgress" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>_overallProgress</cstring>
+ </property>
+ </widget>
+ <widget class="KSqueezedTextLabel" row="0" column="2">
+ <property name="name">
+ <cstring>_currentTool</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Overall:</string>
+ </property>
+ </widget>
+ <widget class="KProgress" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>_currentFileProgress</cstring>
+ </property>
+ </widget>
+ <widget class="KSqueezedTextLabel" row="1" column="2">
+ <property name="name">
+ <cstring>_currentFile</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>_currentLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Current file:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Validation:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QListBox">
+ <item>
+ <property name="text">
+ <string>New Item</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>_errorList</cstring>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>ValidateProgressWidget</sender>
+ <signal>setValidationProgressBar(int)</signal>
+ <receiver>_currentFileProgress</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">validateprogresswidget.ui.h</include>
+</includes>
+<signals>
+ <signal>setValidationProgressBar(int)</signal>
+</signals>
+<slots>
+ <slot>setupFileProgressBar( QString text, int maxvalue )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kprogress.h</includehint>
+ <includehint>ksqueezedtextlabel.h</includehint>
+ <includehint>kprogress.h</includehint>
+ <includehint>ksqueezedtextlabel.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/catalogmanager/validateprogresswidget.ui.h b/kbabel/catalogmanager/validateprogresswidget.ui.h
new file mode 100644
index 00000000..88f36d60
--- /dev/null
+++ b/kbabel/catalogmanager/validateprogresswidget.ui.h
@@ -0,0 +1,48 @@
+/* ****************************************************************************
+ 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.
+
+** 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 ValidateProgressWidget::setupFileProgressBar( QString text, int maxvalue )
+{
+ _currentFileProgress->setTotalSteps(maxvalue);
+
+ QString t = text[0].upper()+text.mid(1)+":";
+
+ _currentAction->setText(t);
+ _currentAction->repaint();
+}
diff --git a/kbabel/catalogmanager/validationoptions.ui b/kbabel/catalogmanager/validationoptions.ui
new file mode 100644
index 00000000..61079ff3
--- /dev/null
+++ b/kbabel/catalogmanager/validationoptions.ui
@@ -0,0 +1,60 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>ValidationOptions</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ValidationOptions</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>174</width>
+ <height>70</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>markAsFuzzy</cstring>
+ </property>
+ <property name="text">
+ <string>Mark invalid as &amp;fuzzy</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Mark invalid as fuzzy&lt;/b&gt;&lt;p&gt;
+&lt;p&gt;If you select this option, all items,
+which identifies the tool as invalid, will be
+marked as fuzzy and the resulting file
+will be saved.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>ignoreFuzzy</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Do not validate fuzzy</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;&lt;p&gt;&lt;b&gt;Do not validate fuzzy&lt;/b&gt;&lt;p&gt;
+&lt;p&gt;If you select this option, all items
+marked as fuzzy will not be validated at all.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>