File indexing completed on 2024-05-12 15:55:07
0001 /*************************************************************************** 0002 kocrstartdia.cpp - description 0003 ------------------- 0004 begin : Fri Now 10 2000 0005 copyright : (C) 2000 by Klaas Freitag 0006 email : freitag@suse.de 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This file may be distributed and/or modified under the terms of the * 0012 * GNU General Public License version 2 as published by the Free Software * 0013 * Foundation and appearing in the file COPYING included in the * 0014 * packaging of this file. * 0015 * 0016 * As a special exception, permission is given to link this program * 0017 * with any version of the KADMOS ocr/icr engine of reRecognition GmbH, * 0018 * Kreuzlingen and distribute the resulting executable without * 0019 * including the source code for KADMOS in the source distribution. * 0020 * 0021 * As a special exception, permission is given to link this program * 0022 * with any edition of Qt, and distribute the resulting executable, * 0023 * without including the source code for Qt in the source distribution. * 0024 * * 0025 ***************************************************************************/ 0026 0027 #include "ocrkadmosdialog.h" 0028 0029 #include <qlayout.h> 0030 #include <qlabel.h> 0031 #include <qfileinfo.h> 0032 #include <qtooltip.h> 0033 #include <qdir.h> 0034 #include <qmap.h> 0035 #include <qradiobutton.h> 0036 #include <qcombobox.h> 0037 #include <qcheckbox.h> 0038 #include <qstringlist.h> 0039 0040 #include <kconfig.h> 0041 #include <kglobal.h> 0042 #include <KLocalizedString> 0043 #include <kseparator.h> 0044 #include <kmessagebox.h> 0045 #include <kstandarddirs.h> 0046 #include <QVBoxLayout> 0047 #include <QHBoxLayout> 0048 0049 #include "ocrkadmosengine.h" 0050 #include "ocr_logging.h" 0051 0052 /* defines for konfig-reading */ 0053 #define CFG_GROUP_KADMOS "Kadmos" 0054 #define CFG_KADMOS_CLASSIFIER_PATH "classifierPath" 0055 #define CFG_KADMOS_CLASSIFIER "classifier" 0056 0057 #define CNTRY_CZ i18n( "Czech Republic, Slovakia") 0058 #define CNTRY_GB i18n( "Great Britain, USA" ) 0059 0060 KadmosDialog::KadmosDialog(QWidget *parent) 0061 : OcrBaseDialog(parent), 0062 m_cbNoise(0), 0063 m_cbAutoscale(0), 0064 m_haveNorm(false) 0065 { 0066 //qCDebug(OCR_LOG); 0067 // Layout-Boxes 0068 findClassifiers(); 0069 } 0070 0071 QString KadmosDialog::ocrEngineLogo() const 0072 { 0073 return ("kadmoslogo.png"); 0074 } 0075 0076 QString KadmosDialog::ocrEngineName() const 0077 { 0078 return (OcrEngine::engineName(OcrEngine::EngineKadmos)); 0079 } 0080 0081 QString KadmosDialog::ocrEngineDesc() const 0082 { 0083 return (OcrKadmosEngine::engineDesc()); 0084 } 0085 0086 OcrEngine::EngineError KadmosDialog::findClassifiers() 0087 { 0088 findClassifierPath(); 0089 0090 KLocale *locale = KLocale::global(); 0091 const QStringList allCountries = locale->allCountriesList(); 0092 for (QStringList::const_iterator it = allCountries.constBegin(); 0093 it != allCountries.constEnd(); ++it) { 0094 m_longCountry2short[locale->countryCodeToName(*it)] = *it; 0095 } 0096 m_longCountry2short[i18n("European Countries")] = "eu"; 0097 m_longCountry2short[CNTRY_CZ] = "cz"; 0098 m_longCountry2short[CNTRY_GB] = "us"; 0099 0100 QStringList lst; 0101 0102 /* custom Path */ 0103 if (! m_customClassifierPath.isEmpty()) { 0104 QDir dir(m_customClassifierPath); 0105 0106 QStringList lst1 = dir.entryList(QStringList("ttf*.rec")); 0107 0108 for (QStringList::Iterator it = lst1.begin(); it != lst1.end(); ++it) { 0109 lst << m_customClassifierPath + *it; 0110 } 0111 0112 lst1 = dir.entryList(QStringList("hand*.rec")); 0113 0114 for (QStringList::Iterator it = lst1.begin(); it != lst1.end(); ++it) { 0115 lst << m_customClassifierPath + *it; 0116 } 0117 0118 lst1 = dir.entryList(QStringList("norm*.rec")); 0119 0120 for (QStringList::Iterator it = lst1.begin(); it != lst1.end(); ++it) { 0121 lst << m_customClassifierPath + *it; 0122 } 0123 } else { 0124 /* standard location */ 0125 KStandardDirs stdDir; 0126 //qCDebug(OCR_LOG) << "Starting to read resources"; 0127 0128 lst = stdDir.findAllResources("data", 0129 "kooka/classifiers/*.rec", 0130 KStandardDirs::Recursive | KStandardDirs::NoDuplicates); 0131 } 0132 0133 /* no go through lst and sort out hand-, ttf- and norm classifier */ 0134 for (QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) { 0135 //qCDebug(OCR_LOG) << "Checking file:" << (*it); 0136 QFileInfo fi(*it); 0137 QString name = fi.fileName().toLower(); 0138 0139 if (name.startsWith("ttf")) { 0140 QString lang = name.mid(3, 2); 0141 if (allCountries.contains(lang)) { 0142 QString lngCountry = locale->countryCodeToName(lang); 0143 if (lngCountry.isEmpty()) { 0144 lngCountry = name; 0145 } 0146 m_ttfClassifier << lngCountry; 0147 //qCDebug(OCR_LOG) << "TTF: Insert country" << lngCountry; 0148 } else if (lang == "cz") { 0149 m_ttfClassifier << CNTRY_CZ; 0150 } else if (lang == "us") { 0151 m_ttfClassifier << CNTRY_GB; 0152 } else { 0153 m_ttfClassifier << name; 0154 //qCDebug(OCR_LOG) << "TTF: Unknown country"; 0155 } 0156 } else if (name.startsWith("hand")) { 0157 QString lang = name.mid(4, 2); 0158 if (allCountries.contains(lang)) { 0159 QString lngCountry = locale->countryCodeToName(lang); 0160 if (lngCountry.isEmpty()) { 0161 lngCountry = name; 0162 } 0163 m_handClassifier << lngCountry; 0164 } else if (lang == "cz") { 0165 m_handClassifier << i18n("Czech Republic, Slovakia"); 0166 } else if (lang == "us") { 0167 m_handClassifier << i18n("Great Britain, USA"); 0168 } else { 0169 //qCDebug(OCR_LOG) << "HAND: Unknown country" << lang; 0170 m_handClassifier << name; 0171 } 0172 } else if (name.startsWith("norm")) { 0173 m_haveNorm = true; 0174 } 0175 0176 //qCDebug(OCR_LOG) << "Found classifier:" << (*it); 0177 m_classifierPath << *it; 0178 } 0179 0180 if (m_handClassifier.count() + m_ttfClassifier.count() > 0) { 0181 /* There are classifiers */ 0182 return OcrEngine::ENG_OK; 0183 } else { 0184 /* Classifier are missing */ 0185 return OcrEngine::ENG_DATA_MISSING; 0186 } 0187 } 0188 0189 OcrEngine::EngineError KadmosDialog::findClassifierPath() 0190 { 0191 KStandardDirs stdDir; 0192 OcrEngine::EngineError err = OcrEngine::ENG_OK; 0193 0194 const KConfigGroup grp = KSharedConfig::openConfig()->group(CFG_GROUP_KADMOS); 0195 m_customClassifierPath = grp.readPathEntry(CFG_KADMOS_CLASSIFIER_PATH, ""); 0196 #if 0 0197 if (m_customClassifierPath == "NotFound") { 0198 /* Wants the classifiers from the standard kde paths */ 0199 KMessageBox::error(0, i18n("The classifier files for KADMOS could not be found.\n" 0200 "OCR with KADMOS will not be possible.\n\n" 0201 "Change the OCR engine in the preferences dialog."), 0202 i18n("Installation Error")); 0203 } else { 0204 m_classifierPath = customPath; 0205 } 0206 #endif 0207 return err; 0208 0209 } 0210 0211 OcrEngine::EngineError KadmosDialog::setupGui() 0212 { 0213 0214 OcrEngine::EngineError err = OcrBaseDialog::setupGui(); 0215 0216 // setupPreprocessing( addVBoxPage( i18n("Preprocessing"))); 0217 // setupSegmentation( addVBoxPage( i18n("Segmentation"))); 0218 // setupClassification( addVBoxPage( i18n("Classification"))); 0219 0220 /* continue page setup on the first page */ 0221 QWidget *page = new QWidget(this); 0222 QVBoxLayout *pageVBoxLayout = new QVBoxLayout(page); 0223 pageVBoxLayout->setMargin(0); 0224 0225 // FIXME: dynamic classifier reading. 0226 0227 new QLabel(i18n("Please classify the font type and language of the text on the image:"), page); 0228 QWidget *locBox = new QWidget(page); 0229 QHBoxLayout *locBoxHBoxLayout = new QHBoxLayout(locBox); 0230 locBoxHBoxLayout->setMargin(0); 0231 pageVBoxLayout->addWidget(locBox); 0232 m_bbFont = new Q3ButtonGroup(1, Qt::Horizontal, i18n("Font Type Selection"), locBox); 0233 locBoxHBoxLayout->addWidget(m_bbFont); 0234 0235 m_rbMachine = new QRadioButton(i18n("Machine print"), m_bbFont); 0236 m_rbHand = new QRadioButton(i18n("Hand writing"), m_bbFont); 0237 m_rbNorm = new QRadioButton(i18n("Norm font"), m_bbFont); 0238 0239 m_gbLang = new Q3GroupBox(1, Qt::Horizontal, i18n("Country"), locBox); 0240 locBoxHBoxLayout->addWidget(m_gbLang); 0241 0242 m_cbLang = new QComboBox(m_gbLang); 0243 m_cbLang->setItemText(m_cbLang->currentIndex(), KLocale::defaultCountry()); 0244 0245 connect(m_bbFont, &Q3ButtonGroup::clicked, this, &KadmosDialog::slFontChanged); 0246 m_rbMachine->setChecked(true); 0247 0248 /* --- */ 0249 QWidget *innerBox = new QWidget(page); 0250 QHBoxLayout *innerBoxHBoxLayout = new QHBoxLayout(innerBox); 0251 innerBoxHBoxLayout->setMargin(0); 0252 pageVBoxLayout->addWidget(innerBox); 0253 innerBoxHBoxLayout->setSpacing(KDialog::spacingHint()); 0254 0255 Q3ButtonGroup *cbGroup = new Q3ButtonGroup(1, Qt::Horizontal, i18n("OCR Modifier"), innerBox); 0256 innerBoxHBoxLayout->addWidget(cbGroup); 0257 Q_CHECK_PTR(cbGroup); 0258 0259 m_cbNoise = new QCheckBox(i18n("Enable automatic noise reduction"), cbGroup); 0260 m_cbAutoscale = new QCheckBox(i18n("Enable automatic scaling"), cbGroup); 0261 0262 addExtraSetupWidget(page); 0263 0264 if (err != OcrEngine::ENG_OK) { 0265 enableFields(false); 0266 enableButton(User1, false); 0267 } 0268 0269 if (m_ttfClassifier.count() == 0) { 0270 m_rbMachine->setEnabled(false); 0271 } 0272 if (m_handClassifier.count() == 0) { 0273 m_rbHand->setEnabled(false); 0274 } 0275 if (!m_haveNorm) { 0276 m_rbNorm->setEnabled(false); 0277 } 0278 0279 if ((m_ttfClassifier.count() + m_handClassifier.count()) == 0 && ! m_haveNorm) { 0280 KMessageBox::error(0, i18n("The classifier files for KADMOS could not be found.\n" 0281 "OCR with KADMOS will not be possible.\n\n" 0282 "Change the OCR engine in the preferences dialog."), 0283 i18n("Installation Error")); 0284 err = OcrEngine::ENG_BAD_SETUP; 0285 } else { 0286 slotFontChanged(0); // Load machine print font language list 0287 } 0288 0289 ocrShowInfo(QString()); 0290 return err; 0291 } 0292 0293 void KadmosDialog::slotFontChanged(int id) 0294 { 0295 m_cbLang->clear(); 0296 0297 const KConfigGroup grp = KSharedConfig::openConfig()->group(CFG_GROUP_KADMOS); 0298 m_customClassifierPath = grp.readPathEntry(CFG_KADMOS_CLASSIFIER_PATH, ""); 0299 0300 bool enable = true; 0301 0302 if (id == 0) { /* Machine Print */ 0303 m_cbLang->addItems(m_ttfClassifier); 0304 } else if (id == 1) { /* Hand Writing */ 0305 m_cbLang->addItems(m_handClassifier); 0306 } else if (id == 2) { /* Norm Font */ 0307 enable = false; 0308 } 0309 m_cbLang->setEnabled(enable); 0310 } 0311 0312 void KadmosDialog::setupPreprocessing(QWidget *box) 0313 { 0314 } 0315 0316 void KadmosDialog::setupSegmentation(QWidget *box) 0317 { 0318 } 0319 0320 void KadmosDialog::setupClassification(QWidget *box) 0321 { 0322 } 0323 0324 /* 0325 * returns the complete path of the classifier selected in the 0326 * GUI in the parameter path. The result value indicates if there 0327 * was one found. 0328 */ 0329 0330 bool KadmosDialog::getSelClassifier(QString &path) const 0331 { 0332 QString classifier = getSelClassifierName(); 0333 0334 QString cmplPath; 0335 /* 0336 * Search the complete path for the classifier file name 0337 * returned from the getSelClassifierName method 0338 */ 0339 for (QStringList::ConstIterator it = m_classifierPath.begin(); 0340 it != m_classifierPath.end(); ++it) { 0341 QFileInfo fi(*it); 0342 if (fi.fileName() == classifier) { 0343 cmplPath = *it; 0344 break; 0345 } 0346 } 0347 0348 bool res = true; 0349 0350 if (cmplPath.isEmpty()) { 0351 /* hm, no path was found */ 0352 //qCDebug(OCR_LOG) << "Error: The entire path is empty"; 0353 res = false; 0354 } else { 0355 /* Check if the classifier exists on the HD. If not, return an empty string */ 0356 QFileInfo fi(cmplPath); 0357 0358 if (res && ! fi.exists()) { 0359 //qCDebug(OCR_LOG) << "Classifier file does not exist"; 0360 path = i18n("Classifier file %1 does not exist", classifier); 0361 res = false; 0362 } 0363 0364 if (res && ! fi.isReadable()) { 0365 //qCDebug(OCR_LOG) << "Classifier file could not be read"; 0366 path = i18n("Classifier file %1 is not readable", classifier); 0367 res = false; 0368 } 0369 0370 if (res) { 0371 path = cmplPath; 0372 } 0373 } 0374 return res; 0375 } 0376 0377 QString KadmosDialog::getSelClassifierName() const 0378 { 0379 QAbstractButton *butt = m_bbFont->selected(); 0380 0381 QString fType, rType; 0382 0383 if (butt) { 0384 int fontTypeID = m_bbFont->id(butt); 0385 if (fontTypeID == 0) { 0386 fType = "ttf"; 0387 } else if (fontTypeID == 1) { 0388 fType = "hand"; 0389 } else if (fontTypeID == 2) { 0390 fType = "norm"; 0391 } else { 0392 //qCDebug(OCR_LOG) << "Error: Wrong font type ID"; 0393 } 0394 } 0395 0396 /* Get the long text from the combo box */ 0397 QString selLang = m_cbLang->currentText(); 0398 QString trans; 0399 if (fType != "norm" && m_longCountry2short.contains(selLang)) { 0400 QString langType = m_longCountry2short[selLang]; 0401 trans = fType + langType + ".rec"; 0402 } else { 0403 if (selLang.endsWith(".rec")) { 0404 /* can be a undetected */ 0405 trans = selLang; 0406 } else if (fType == "norm") { 0407 trans = "norm.rec"; 0408 } else { 0409 //qCDebug(OCR_LOG) << "Error: Not a valid classifier"; 0410 } 0411 } 0412 //qCDebug(OCR_LOG) << "Returning" << trans; 0413 return (trans); 0414 } 0415 0416 bool KadmosDialog::getAutoScale() 0417 { 0418 return (m_cbAutoscale ? m_cbAutoscale->isChecked() : false); 0419 } 0420 0421 bool KadmosDialog::getNoiseReduction() 0422 { 0423 return (m_cbNoise ? m_cbNoise->isChecked() : false); 0424 0425 } 0426 0427 KadmosDialog::~KadmosDialog() 0428 { 0429 0430 } 0431 0432 void KadmosDialog::slotWriteConfig() 0433 { 0434 //qCDebug(OCR_LOG); 0435 0436 OcrBaseDialog::slotWriteConfig(); 0437 0438 //KConfig *conf = KSharedConfig::openConfig(); 0439 // TODO: must be something to save here! 0440 } 0441 0442 void KadmosDialog::enableFields(bool state) 0443 { 0444 m_cbNoise->setEnabled(state); 0445 m_cbAutoscale->setEnabled(state); 0446 0447 m_bbFont->setEnabled(state); 0448 m_gbLang->setEnabled(state); 0449 }