00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "trwindow.h"
00030 #include "finddialog.h"
00031 #include "translatedialog.h"
00032 #include "batchtranslationdialog.h"
00033 #include "translationsettingsdialog.h"
00034 #include "msgedit.h"
00035 #include "phrasebookbox.h"
00036 #include "printout.h"
00037 #include "statistics.h"
00038 #include "messagemodel.h"
00039 #include "phrasemodel.h"
00040 #include "translator.h"
00041 #include "previewtool/trpreviewtool.h"
00042
00043 #include <QAction>
00044 #include <QApplication>
00045 #include <QBitmap>
00046 #include <QDockWidget>
00047 #include <QFile>
00048 #include <QFileDialog>
00049 #include <QFileInfo>
00050 #include <QHeaderView>
00051 #include <QLabel>
00052 #include <QLayout>
00053 #include <QMenuBar>
00054 #include <QMessageBox>
00055 #include <QMenu>
00056 #include <QRegExp>
00057 #include <QSettings>
00058 #include <QStatusBar>
00059 #include <QToolBar>
00060 #include <QWhatsThis>
00061 #include <QAssistantClient>
00062 #include <QDesktopWidget>
00063 #include <QPrintDialog>
00064 #include <QLibraryInfo>
00065 #include <QUiLoader>
00066
00067 #define pagecurl_mask_width 53
00068 #define pagecurl_mask_height 51
00069 static const uchar pagecurl_mask_bits[] = {
00070 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
00071 0xff, 0x0f, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xfe, 0xff,
00072 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
00073 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
00074 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0xff,
00075 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
00076 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f,
00077 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff,
00078 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0,
00079 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
00080 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff,
00081 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff,
00082 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
00083 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f,
00084 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff,
00085 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0,
00086 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
00087 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
00088 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xfc,
00089 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00,
00090 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f,
00091 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
00092 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00,
00093 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
00094 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00095 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
00096 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
00097 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
00098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
00099 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
00100
00101 static const int ErrorMS = 600000;
00102 static const int MessageMS = 2500;
00103
00104 QPixmap *TrWindow::pxOn = 0;
00105 QPixmap *TrWindow::pxOff = 0;
00106 QPixmap *TrWindow::pxObsolete = 0;
00107 QPixmap *TrWindow::pxDanger = 0;
00108 QPixmap *TrWindow::pxWarning = 0;
00109 QPixmap *TrWindow::pxEmpty = 0;
00110
00111 enum Ending {End_None, End_FullStop, End_Interrobang, End_Colon,
00112 End_Ellipsis};
00113
00114 static Ending ending(QString str, QLocale::Language lang)
00115 {
00116 str = str.simplified();
00117 int ch = 0;
00118 if (!str.isEmpty())
00119 ch = str.right(1)[0].unicode();
00120
00121 switch (ch) {
00122 case 0x002e:
00123 if (str.endsWith(QString("...")))
00124 return End_Ellipsis;
00125 else
00126 return End_FullStop;
00127 case 0x0589:
00128 case 0x06d4:
00129 case 0x3002:
00130 return End_FullStop;
00131 case 0x0021:
00132 case 0x003f:
00133 case 0x00a1:
00134 case 0x00bf:
00135 case 0x01c3:
00136 case 0x037e:
00137 case 0x061f:
00138 case 0x203c:
00139 case 0x203d:
00140 case 0x2048:
00141 case 0x2049:
00142 case 0x2762:
00143 return End_Interrobang;
00144 case 0x003b:
00145 return lang == QLocale::Greek ? End_Interrobang : End_None;
00146 case 0x003a:
00147 return End_Colon;
00148 case 0x2026:
00149 return End_Ellipsis;
00150 default:
00151 return End_None;
00152 }
00153 }
00154
00155 const QPixmap TrWindow::pageCurl()
00156 {
00157 QPixmap pixmap;
00158 pixmap.load(":/images/pagecurl.png" );
00159 if ( !pixmap.isNull() ) {
00160 QBitmap pageCurlMask = QBitmap::fromData(QSize(pagecurl_mask_width, pagecurl_mask_height),
00161 pagecurl_mask_bits, QImage::Format_MonoLSB);
00162 pixmap.setMask(pageCurlMask);
00163 }
00164
00165 return pixmap;
00166 }
00167
00168 #ifdef Q_WS_MAC
00169 const QString rsrcString = ":/images/mac";
00170 #else
00171 const QString rsrcString = ":/images/win";
00172 #endif
00173
00174 TrWindow::TrWindow()
00175 : QMainWindow(0, Qt::Window)
00176 {
00177 ac = 0;
00178
00179 #ifndef Q_WS_MAC
00180 setWindowIcon(QPixmap(":/images/appicon.png" ));
00181 #endif
00182
00183 m_previewTool = 0;
00184
00185
00186 pxOn = new QPixmap(":/images/s_check_on.png");
00187 pxOff = new QPixmap(":/images/s_check_off.png");
00188 pxObsolete = new QPixmap(":/images/s_check_obsolete.png");
00189 pxDanger = new QPixmap(":/images/s_check_danger.png");
00190 pxWarning = new QPixmap(":/images/s_check_warning.png");
00191 pxEmpty = new QPixmap(":/images/s_check_empty.png");
00192
00193 setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
00194 setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
00195 setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
00196 setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
00197
00198
00199 dwScope = new QDockWidget(this);
00200 dwScope->setObjectName("ContextDockWidget");
00201 dwScope->setAllowedAreas(Qt::AllDockWidgetAreas);
00202 dwScope->setFeatures(QDockWidget::AllDockWidgetFeatures);
00203 dwScope->setWindowTitle(tr("Context"));
00204
00205 tv = new MessagesTreeView(dwScope);
00206 cmdl = new MessageModel(dwScope);
00207 tv->setModel(cmdl);
00208 dwScope->setWidget(tv);
00209 addDockWidget(Qt::LeftDockWidgetArea, dwScope);
00210
00211 me = new MessageEditor(cmdl, this);
00212
00213 ptv = me->phraseView();
00214 pmdl = qobject_cast<PhraseModel *>(ptv->model());
00215
00216 connect(tv->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
00217 this, SLOT(showNewCurrent(QModelIndex,QModelIndex)));
00218
00219 connect(cmdl, SIGNAL(languageChanged(QLocale::Language)), this, SLOT(updateLanguage(QLocale::Language)));
00220
00221 m_translatedlg = new TranslateDialog(this);
00222 m_batchTranslateDlg = new BatchTranslationDialog(cmdl, this);
00223 m_translationSettingsDialog = 0;
00224 finddlg = new FindDialog(this);
00225 findMatchCase = false;
00226 findWhere = 0;
00227 foundWhere = 0;
00228 foundOffset = 0;
00229
00230 setupMenuBar();
00231 setupToolBars();
00232
00233 QBoxLayout *lout = new QBoxLayout(QBoxLayout::TopToBottom, m_ui.centralwidget);
00234 lout->addWidget(me);
00235 lout->setMargin(0);
00236 m_ui.centralwidget->setLayout(lout);
00237
00238 progress = new QLabel(statusBar());
00239 statusBar()->addPermanentWidget(progress);
00240 modified = new QLabel(QString(" %1 ").arg(tr("MOD")), statusBar());
00241 statusBar()->addPermanentWidget(modified);
00242
00243 updateProgress();
00244 updateCaption();
00245
00246
00247 connect(tv, SIGNAL(clicked(QModelIndex)),
00248 this, SLOT(toggleFinished(QModelIndex)));
00249 connect(me, SIGNAL(translationChanged(QStringList)),
00250 this, SLOT(updateTranslation(QStringList)));
00251 connect(me, SIGNAL(finished(bool)), this, SLOT(updateFinished(bool)));
00252 connect(me, SIGNAL(prevUnfinished()), this, SLOT(prevUnfinished()));
00253 connect(me, SIGNAL(nextUnfinished()), this, SLOT(nextUnfinished()));
00254 connect(me, SIGNAL(focusSourceList()), this, SLOT(focusSourceList()));
00255 connect(me, SIGNAL(focusPhraseList()), this, SLOT(focusPhraseList()));
00256 connect(finddlg, SIGNAL(findNext(QString,int,bool)),
00257 this, SLOT(findNext(QString,int,bool)));
00258 connect(m_translatedlg, SIGNAL( translateAndFindNext(QString,QString,int,int,bool) ),
00259 this, SLOT( translateAndFindNext(QString,QString,int,int,bool) ));
00260
00261 connect(tv->header(), SIGNAL(sectionClicked(int)),
00262 tv, SLOT(clearSelection()));
00263
00264 tv->setWhatsThis(tr("This panel lists the source contexts."));
00265
00266 QSize as( qApp->desktop()->size() );
00267 as -= QSize( 30, 30 );
00268 resize( QSize( 1000, 800 ).boundedTo( as ) );
00269 readConfig();
00270 stats = 0;
00271
00272 QWidget::setTabOrder(ptv, tv);
00273 }
00274
00275 void TrWindow::updateLanguage(QLocale::Language lang)
00276 {
00277 QStringList forms;
00278 QByteArray rules;
00279
00280 getNumerusInfo(lang, cmdl->country(), &rules, &forms);
00281 me->setNumerusForms(tr("Translation"), forms);
00282 }
00283
00284 TrWindow::~TrWindow()
00285 {
00286 writeConfig();
00287 cmdl->clearContextList();
00288 delete stats;
00289 delete m_previewTool;
00290 }
00291
00292 void TrWindow::openFile( const QString& name )
00293 {
00294 if (name.isEmpty())
00295 return;
00296
00297 statusBar()->showMessage(tr("Loading..."));
00298 qApp->processEvents();
00299
00300 if (!cmdl->load(name)) {
00301 statusBar()->clearMessage();
00302 QMessageBox::warning(this, tr("Qt Linguist"), tr("Cannot open '%1'.").arg(name));
00303 return;
00304 }
00305
00306 MessageItem *m;
00307 for (MessageModel::iterator it = cmdl->begin() ; (m = it.current()) ; ++it) {
00308 updateDanger(m);
00309 }
00310
00311 tv->clearSelection();
00312
00313 setEnabled(true);
00314 updateProgress();
00315 filename = name;
00316
00317 updateCaption();
00318
00319 me->showNothing();
00320
00321 m_ui.actionDoneAndNext->setEnabled(false);
00322 m_ui.actionPreviewForm->setEnabled(true);
00323
00324 statusBar()->showMessage(tr("%n source phrase(s) loaded.", 0, cmdl->getMessageCount()), MessageMS);
00325 foundWhere = 0;
00326 foundOffset = 0;
00327
00328 if (cmdl->contextsInList() > 0) {
00329 m_ui.actionFind->setEnabled(true);
00330 m_ui.actionFindNext->setEnabled(false);
00331 m_ui.actionTranslationFileSettings->setEnabled(true);
00332 m_ui.actionBatchTranslation->setEnabled(true);
00333 m_ui.actionSearchAndTranslate->setEnabled(true);
00334 }
00335
00336 addRecentlyOpenedFile(name, recentFiles);
00337 updateStatistics();
00338 }
00339
00340 void TrWindow::open()
00341 {
00342 if (maybeSave()) {
00343 QString newFilename = QFileDialog::getOpenFileName( this, QString(), filename,
00344 tr("Qt translation source (*.ts)\nAll files (*)"));
00345 openFile(newFilename);
00346 }
00347 }
00348
00349 void TrWindow::save()
00350 {
00351 if (filename.isEmpty())
00352 return;
00353
00354 if (cmdl->save(filename)) {
00355 updateCaption();
00356 statusBar()->showMessage(tr("File saved."), MessageMS);
00357 } else {
00358 QMessageBox::warning(this, tr("Qt Linguist"), tr("Cannot save '%1'.").arg(filename));
00359 }
00360 }
00361
00362 void TrWindow::saveAs()
00363 {
00364 QString newFilename = QFileDialog::getSaveFileName(this, QString(), filename,
00365 tr( "Qt translation source (*.ts)\nAll files (*)"));
00366 if (!newFilename.isEmpty()) {
00367 filename = newFilename;
00368 save();
00369 updateCaption();
00370 }
00371 }
00372
00373 void TrWindow::releaseAs()
00374 {
00375 QString newFilename = filename;
00376 newFilename.replace(QRegExp(".ts$"), "");
00377 newFilename += QString(".qm");
00378
00379 newFilename = QFileDialog::getSaveFileName(this, tr("Release"), newFilename,
00380 tr("Qt message files for released applications (*.qm)\nAll files (*)"));
00381 if (!newFilename.isEmpty()) {
00382 if (cmdl->release(newFilename, false, false, Translator::Everything))
00383 statusBar()->showMessage(tr("File created."), MessageMS);
00384 else
00385 QMessageBox::warning(this, tr("Qt Linguist"), tr("Cannot save '%1'.").arg(newFilename));
00386 }
00387 }
00388
00389
00390 void TrWindow::release()
00391 {
00392 QString newFilename = filename;
00393 newFilename.replace(QRegExp(".ts$"), "");
00394 newFilename += QString(".qm");
00395
00396 if (!newFilename.isEmpty()) {
00397 if (cmdl->release(newFilename, false, false, Translator::Everything))
00398 statusBar()->showMessage(tr("File created."), MessageMS);
00399 else
00400 QMessageBox::warning(this, tr("Qt Linguist"), tr("Cannot save '%1'.").arg(newFilename));
00401 }
00402 }
00403
00404 void TrWindow::print()
00405 {
00406 int pageNum = 0;
00407 QList <ContextItem *> ctxtList;
00408 QList <MessageItem *> msgList;
00409 const MessageItem *m;
00410 ContextItem *c;
00411
00412 QPrintDialog dlg(&printer, this);
00413 if (dlg.exec()) {
00414 QApplication::setOverrideCursor(Qt::WaitCursor);
00415 printer.setDocName(filename);
00416 statusBar()->showMessage(tr("Printing..."));
00417 PrintOut pout(&printer);
00418 ctxtList = cmdl->contextList();
00419
00420 for (int i=0; i<ctxtList.count(); i++) {
00421 c = ctxtList.at(i);
00422 pout.vskip();
00423 pout.setRule(PrintOut::ThickRule);
00424 pout.setGuide(c->context());
00425 pout.addBox(100, tr("Context: %1").arg(c->context()),
00426 PrintOut::Strong);
00427 pout.flushLine();
00428 pout.addBox(4);
00429 pout.addBox(92, c->comment(), PrintOut::Emphasis);
00430 pout.flushLine();
00431 pout.setRule(PrintOut::ThickRule);
00432
00433 msgList = c->messageItemList();
00434 for (int j=0; j<msgList.count(); j++) {
00435 m = msgList.at(j);
00436 pout.setRule(PrintOut::ThinRule);
00437
00438 QString type;
00439 switch (m->message().type()) {
00440 case MetaTranslatorMessage::Finished:
00441 type = tr("finished");
00442 break;
00443 case MetaTranslatorMessage::Unfinished:
00444 type = m->danger() ? tr("unresolved") : QString("unfinished");
00445 break;
00446 case MetaTranslatorMessage::Obsolete:
00447 type = tr("obsolete");
00448 break;
00449 default:
00450 type = QString("");
00451 }
00452 pout.addBox(40, m->sourceText());
00453 pout.addBox(4);
00454 pout.addBox(40, m->translation());
00455 pout.addBox(4);
00456 pout.addBox(12, type, PrintOut::Normal, Qt::AlignRight);
00457 if (!m->comment().isEmpty()) {
00458 pout.flushLine();
00459 pout.addBox(4);
00460 pout.addBox(92, m->comment(), PrintOut::Emphasis);
00461 }
00462 pout.flushLine(true);
00463
00464 if (pout.pageNum() != pageNum) {
00465 pageNum = pout.pageNum();
00466 statusBar()->showMessage(tr("Printing... (page %1)")
00467 .arg(pageNum));
00468 }
00469 }
00470 }
00471 pout.flushLine(true);
00472 QApplication::restoreOverrideCursor();
00473 statusBar()->showMessage(tr("Printing completed"), MessageMS);
00474 } else {
00475 statusBar()->showMessage(tr("Printing aborted"), MessageMS);
00476 }
00477 }
00478
00479 void TrWindow::find()
00480 {
00481 finddlg->show();
00482 finddlg->activateWindow();
00483 finddlg->raise();
00484 }
00485
00486 void TrWindow::findAgain()
00487 {
00488 if (cmdl->contextsInList() <= 0)
00489 return;
00490
00491 int pass = 0;
00492 int scopeNo = 0;
00493 int itemNo = 0;
00494
00495
00496 QModelIndex indxItem = tv->currentIndex();
00497 if (indxItem.isValid())
00498 itemNo = indxItem.row();
00499 QModelIndex indxScope = tv->currentIndex().parent();
00500 if (indxScope.isValid())
00501 scopeNo = indxScope.row();
00502
00503 QString delayedMsg;
00504
00505
00506 ContextItem *c = cmdl->contextItem(cmdl->index(scopeNo, 1));
00507 MessageItem *m;
00508
00509 #if 1
00510
00511
00512
00513
00514 foundOffset = (int) 0x7fffffff;
00515 #else
00516 foundOffset++;
00517 #endif
00518
00519
00520
00521
00522 while (pass <= cmdl->contextsInList()) {
00523 for (int mit = itemNo; mit < c->messageItemsInList() ; ++mit) {
00524 m = c->messageItem(mit);
00525 switch (foundWhere) {
00526 case 0:
00527 foundWhere = FindDialog::SourceText;
00528 foundOffset = 0;
00529
00530 case FindDialog::SourceText:
00531 if (searchItem(m->sourceText(), scopeNo, mit)) {
00532 finddlg->hide();
00533 if (!delayedMsg.isEmpty())
00534 statusBar()->showMessage(delayedMsg, MessageMS);
00535 return;
00536 }
00537 foundWhere = FindDialog::Translations;
00538 foundOffset = 0;
00539
00540 case FindDialog::Translations:
00541 if (searchItem(m->translation(), scopeNo, mit)) {
00542 finddlg->hide();
00543 if (!delayedMsg.isEmpty())
00544 statusBar()->showMessage(delayedMsg, MessageMS);
00545 return;
00546 }
00547 foundWhere = FindDialog::Comments;
00548 foundOffset = 0;
00549
00550 case FindDialog::Comments:
00551 if (searchItem(c->fullContext(), scopeNo, mit)) {
00552 finddlg->hide();
00553 if (!delayedMsg.isEmpty())
00554 statusBar()->showMessage(delayedMsg, MessageMS);
00555 return;
00556 }
00557 foundWhere = 0;
00558 foundOffset = 0;
00559 }
00560 }
00561 itemNo = 0;
00562 ++pass;
00563
00564 ++scopeNo;
00565 if (scopeNo >= cmdl->contextsInList()) {
00566 scopeNo = 0;
00567 delayedMsg = tr("Search wrapped.");
00568 }
00569
00570 c = cmdl->contextItem(cmdl->index(scopeNo, 1));
00571 }
00572
00573 qApp->beep();
00574 QMessageBox::warning( finddlg, tr("Qt Linguist"),
00575 QString( tr("Cannot find the string '%1'.") ).arg(findText));
00576
00577 foundWhere = 0;
00578 foundOffset = 0;
00579 }
00580
00581 void TrWindow::showTranslateDialog()
00582 {
00583 m_translatedlg->show();
00584 m_translatedlg->activateWindow();
00585 m_translatedlg->raise();
00586 }
00587
00588 void TrWindow::showBatchTranslateDialog()
00589 {
00590 QList<PhraseBook> frasebooks = phraseBooks[PhraseEditMenu].values();
00591 m_batchTranslateDlg->setPhraseBooks(frasebooks);
00592 m_batchTranslateDlg->exec();
00593
00594 }
00595
00596 void TrWindow::translateAndFindNext(const QString& findWhat, const QString &translateTo,
00597 int matchOption, int mode, bool markFinished)
00598 {
00599 findText = findWhat;
00600 m_translateTo = translateTo;
00601 findMatchCase = matchOption & TranslateDialog::MatchCase;
00602 m_markFinished = markFinished;
00603 m_findMatchSubstring = false;
00604
00605 translate(mode);
00606 }
00607
00608 void TrWindow::translate(int mode)
00609 {
00610 int itemNo = 0;
00611 int scopeNo = 0;
00612 QModelIndex indxItem = tv->currentIndex();
00613 if (indxItem.isValid())
00614 itemNo = indxItem.row();
00615 QModelIndex indxScope = tv->currentIndex().parent();
00616 if (indxScope.isValid()) {
00617 scopeNo = indxScope.row();
00618 }else{
00619 scopeNo = itemNo;
00620 itemNo = 0;
00621 }
00622
00623 int translatedCount = 0;
00624 bool found = false;
00625
00626
00627 MessageModel::iterator it = cmdl->Iterator(scopeNo, itemNo);
00628 switch (mode) {
00629 case TranslateDialog::TranslateAll:
00630 {
00631 int passes = cmdl->getMessageCount();
00632 while (passes > 0) {
00633 MessageItem *m = it.current();
00634 if (!m) {
00635 it.reset();
00636 m = it.current();
00637 }
00638 if (m && m->compare(findText, m_findMatchSubstring, findMatchCase ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
00639 cmdl->setTranslation(it, m_translateTo);
00640 if (indxScope.isValid() && it.contextNo() == scopeNo && it.messageNo() == itemNo)
00641 me->setTranslation(m_translateTo, 0, false);
00642 updateFinished(it.contextNo(), it.messageNo(), m_markFinished);
00643 ++translatedCount;
00644 }
00645 ++it;
00646 --passes;
00647 }
00648 found = translatedCount == 0 ? false : true;
00649 if (found) {
00650 QMessageBox::warning( m_translatedlg, tr("Translate"),
00651 QString( tr("Translated %n entries to '%1'", 0, translatedCount).arg(m_translateTo) ));
00652 }
00653 }
00654 break;
00655 case TranslateDialog::Translate:
00656 {
00657 MessageItem *m = it.current();
00658 if (m && m->compare(findText, m_findMatchSubstring, findMatchCase ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
00659 cmdl->setTranslation(it, m_translateTo);
00660 updateFinished(it.contextNo(), it.messageNo(), m_markFinished);
00661 ++translatedCount;
00662 }
00663 }
00664 case TranslateDialog::Skip:
00665 {
00666 ++it;
00667 int passes = cmdl->getMessageCount() - 1;
00668 while (passes > 0) {
00669 MessageItem *m = it.current();
00670 if (!m) {
00671 it.reset();
00672 m = it.current();
00673 }
00674 if (m && m->compare(findText, m_findMatchSubstring, findMatchCase ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
00675 found = true;
00676 break;
00677 }
00678 ++it;
00679 --passes;
00680 }
00681 }
00682 break;
00683 }
00684
00685 if (found) {
00686 QModelIndex cidx = cmdl->index(it.contextNo(),0);
00687 if (cidx.isValid()) {
00688 setCurrentMessage(cmdl->index(it.messageNo(),0, cidx));
00689 }
00690 } else {
00691 qApp->beep();
00692 QMessageBox::warning( m_translatedlg, tr("Qt Linguist"),
00693 QString( tr("Cannot find the string '%1'.") ).arg(findText) );
00694 }
00695 }
00696
00697 bool TrWindow::searchItem(const QString &searchWhat, int c, int m)
00698 {
00699 if ((findWhere & foundWhere) != 0) {
00700 foundOffset = searchWhat.indexOf(findText, foundOffset,
00701 findMatchCase ? Qt::CaseSensitive : Qt::CaseInsensitive);
00702 if (foundOffset >= 0) {
00703 QModelIndex cidx = cmdl->index(c,0);
00704 setCurrentMessage(cmdl->index(m,0, cidx));
00705 return true;
00706 }
00707 }
00708 foundOffset = 0;
00709 return false;
00710 }
00711
00712 void TrWindow::newPhraseBook()
00713 {
00714 QString name;
00715 for (;;) {
00716 name = QFileDialog::getSaveFileName(this, tr("Create New Phrase Book"),
00717 QString(), tr("Qt phrase books (*.qph)\nAll files (*)"));
00718 if (name.isEmpty())
00719 break;
00720 else if (!QFile::exists(name)) {
00721 break;
00722 QMessageBox::warning(this, tr("Qt Linguist"),
00723 tr("A file called '%1' already exists."
00724 " Please choose another name.").arg(name));
00725 }
00726 }
00727 if (!name.isEmpty()) {
00728 PhraseBook pb;
00729 if (savePhraseBook(name, pb)) {
00730 if (openPhraseBook(name))
00731 statusBar()->showMessage(tr("Phrase book created."), MessageMS);
00732 }
00733 }
00734 }
00735
00736 bool TrWindow::phraseBooksContains(QString name)
00737 {
00738 foreach(PhraseBook pb, phraseBooks[PhraseCloseMenu]) {
00739 if (pb.fileName() == name)
00740 return true;
00741 }
00742
00743 return false;
00744 }
00745
00746 PhraseBook TrWindow::phraseBookFromFileName(QString name) const
00747 {
00748 foreach(PhraseBook pb, phraseBooks[PhraseCloseMenu]) {
00749 if (pb.fileName() == name)
00750 return pb;
00751 }
00752
00753 return PhraseBook();
00754 }
00755
00756 void TrWindow::openPhraseBook()
00757 {
00758 QString phrasebooks(QLibraryInfo::location(QLibraryInfo::DataPath));
00759 QString name = QFileDialog::getOpenFileName(this, tr("Open Phrase Book"),
00760 phrasebooks + "/phrasebooks", tr("Qt phrase books (*.qph)\nAll files (*)"));
00761
00762 if (!name.isEmpty() && !phraseBooksContains(name)) {
00763 if (openPhraseBook(name)) {
00764 int n = phraseBookFromFileName(name).count();
00765 statusBar()->showMessage(tr("%n phrase(s) loaded.", 0, n), MessageMS);
00766 }
00767 }
00768 }
00769
00770 void TrWindow::closePhraseBook(QAction *action)
00771 {
00772 PhraseBook pb = phraseBooks[PhraseCloseMenu].value(action);
00773 phraseBooks[PhraseCloseMenu].remove(action);
00774 m_ui.menuClosePhraseBook->removeAction(action);
00775
00776 QAction *act = phraseBooks[PhraseEditMenu].key(pb);
00777 phraseBooks[PhraseEditMenu].remove(act);
00778 m_ui.menuEditPhraseBook->removeAction(act);
00779
00780 act = phraseBooks[PhrasePrintMenu].key(pb);
00781 m_ui.menuPrintPhraseBook->removeAction(act);
00782
00783 updatePhraseDict();
00784 m_ui.actionBatchTranslation->setEnabled(phraseBooks[PhraseCloseMenu].count() > 0);
00785 }
00786
00787 void TrWindow::editPhraseBook(QAction *action)
00788 {
00789 PhraseBook pb = phraseBooks[PhraseEditMenu].value(action);
00790 PhraseBookBox box(pb.fileName(), pb, this);
00791 box.setWindowTitle(tr("%1 - %2").arg(tr("Qt Linguist"))
00792 .arg(pb.friendlyPhraseBookName()));
00793 box.resize(500, 300);
00794 box.exec();
00795
00796
00797
00798 phraseBooks[PhraseEditMenu].remove(action);
00799 QAction *closeact = phraseBooks[PhraseCloseMenu].key(pb);
00800 phraseBooks[PhraseCloseMenu].remove(closeact);
00801 QAction *printact = phraseBooks[PhrasePrintMenu].key(pb);
00802 phraseBooks[PhrasePrintMenu].remove(printact);
00803
00804 phraseBooks[PhraseEditMenu].insert(action, box.phraseBook());
00805 phraseBooks[PhraseCloseMenu].insert(closeact, box.phraseBook());
00806 phraseBooks[PhrasePrintMenu].insert(printact, box.phraseBook());
00807
00808 updatePhraseDict();
00809 }
00810
00811 void TrWindow::printPhraseBook(QAction *action)
00812 {
00813 PhraseBook phraseBook = phraseBooks[PhrasePrintMenu].value(action);
00814
00815 int pageNum = 0;
00816
00817 QPrintDialog dlg(&printer, this);
00818 if (dlg.exec()) {
00819 printer.setDocName(phraseBook.fileName());
00820 statusBar()->showMessage(tr("Printing..."));
00821 PrintOut pout(&printer);
00822 pout.setRule(PrintOut::ThinRule);
00823 foreach (Phrase p, phraseBook) {
00824 pout.setGuide(p.source());
00825 pout.addBox(29, p.source());
00826 pout.addBox(4);
00827 pout.addBox(29, p.target());
00828 pout.addBox(4);
00829 pout.addBox(34, p.definition(), PrintOut::Emphasis);
00830
00831 if (pout.pageNum() != pageNum) {
00832 pageNum = pout.pageNum();
00833 statusBar()->showMessage(tr("Printing... (page %1)")
00834 .arg(pageNum));
00835 }
00836 pout.setRule(PrintOut::NoRule);
00837 pout.flushLine(true);
00838 }
00839 pout.flushLine(true);
00840 statusBar()->showMessage(tr("Printing completed"), MessageMS);
00841 } else {
00842 statusBar()->showMessage(tr("Printing aborted"), MessageMS);
00843 }
00844 }
00845
00846 void TrWindow::revertSorting()
00847 {
00848 if (cmdl->contextsInList() < 0)
00849 return;
00850
00851 tv->clearSelection();
00852 tv->header()->setSortIndicator(1, Qt::AscendingOrder);
00853 tv->header()->setSortIndicatorShown(true);
00854 cmdl->sort(1, Qt::AscendingOrder);
00855
00856
00857 foreach(ContextItem *c, cmdl->contextList()) {
00858 c->sortMessages(1, Qt::AscendingOrder);
00859 }
00860 }
00861
00862 void TrWindow::manual()
00863 {
00864 if (!ac)
00865 ac = new QAssistantClient(QLibraryInfo::location(QLibraryInfo::BinariesPath), this);
00866 ac->showPage(QLibraryInfo::location(QLibraryInfo::DocumentationPath) +
00867 "/html/linguist-manual.html");
00868 }
00869
00870 void TrWindow::about()
00871 {
00872
00873 QMessageBox box(this);
00874 box.setTextFormat(Qt::RichText);
00875 QString version = tr("Version %1");
00876 #if QT_EDITION == QT_EDITION_OPENSOURCE
00877 QString open = tr(" Open Source Edition");
00878 version.append(open);
00879 #endif
00880 version = version.arg(QT_VERSION_STR);
00881
00882 QString edition =
00883 #if QT_EDITION == QT_EDITION_OPENSOURCE
00884 tr("This version of Qt Linguist is part of the Qt Open Source Edition, for use "
00885 "in the development of Open Source applications. "
00886 "Qt is a comprehensive C++ framework for cross-platform application "
00887 "development.<br/><br/>"
00888 "You need a commercial Qt license for development of proprietary (closed "
00889 "source) applications. Please see <tt>http://www.trolltech.com/company/model"
00890 ".html</tt> for an overview of Qt licensing.");
00891 #else
00892 tr("This program is licensed to you under the terms of the "
00893 "Qt Commercial License Agreement. For details, see the file LICENSE "
00894 "that came with this software distribution.");
00895 #endif
00896
00897 box.setText(tr("<center><img src=\":/images/splash.png\"/></img><p>%1</p></center>"
00898 "<p>Qt Linguist is a tool for adding translations to Qt "
00899 "applications.</p>"
00900 "<p>%2</p>"
00901 "<p>Copyright (C) 2000-2006 Trolltech ASA. All rights reserved."
00902 "</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
00903 " INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
00904 " PARTICULAR PURPOSE.</p>").arg(version).arg(edition));
00905
00906 box.setWindowTitle(QApplication::translate("AboutDialog", "Qt Linguist"));
00907 box.setIcon(QMessageBox::NoIcon);
00908 box.exec();
00909 }
00910
00911 void TrWindow::aboutQt()
00912 {
00913 QMessageBox::aboutQt(this, tr("Qt Linguist"));
00914 }
00915
00916 void TrWindow::setupPhrase()
00917 {
00918 bool enabled = !phraseBooks[PhraseCloseMenu].isEmpty();
00919 m_ui.menuClosePhraseBook->setEnabled(enabled);
00920 m_ui.menuEditPhraseBook->setEnabled(enabled);
00921 m_ui.menuPrintPhraseBook->setEnabled(enabled);
00922 }
00923
00924 void TrWindow::closeEvent(QCloseEvent *e)
00925 {
00926 if (maybeSave()) {
00927 e->accept();
00928 delete m_previewTool;
00929 m_previewTool = 0;
00930 } else {
00931 e->ignore();
00932 }
00933 }
00934
00935 bool TrWindow::maybeSave()
00936 {
00937 if (cmdl->isModified()) {
00938 switch (QMessageBox::information(this, tr("Qt Linguist"),
00939 tr("Do you want to save '%1'?").arg(filename),
00940 QMessageBox::Yes | QMessageBox::Default,
00941 QMessageBox::No,
00942 QMessageBox::Cancel | QMessageBox::Escape))
00943 {
00944 case QMessageBox::Cancel:
00945 return false;
00946 case QMessageBox::Yes:
00947 save();
00948 return !cmdl->isModified();
00949 case QMessageBox::No:
00950 break;
00951 }
00952 }
00953 return true;
00954 }
00955
00956 void TrWindow::updateCaption()
00957 {
00958 QString cap;
00959 bool enable = !filename.isEmpty();
00960 m_ui.actionSave->setEnabled(enable);
00961 m_ui.actionSaveAs->setEnabled(enable);
00962 m_ui.actionRelease->setEnabled(enable);
00963 m_ui.actionReleaseAs->setEnabled(enable);
00964 m_ui.actionPrint->setEnabled(enable);
00965 m_ui.actionAccelerators->setEnabled(enable);
00966 m_ui.actionEndingPunctuation->setEnabled(enable);
00967 m_ui.actionPhraseMatches->setEnabled(enable);
00968 m_ui.actionPlaceMarkerMatches->setEnabled(enable);
00969 m_ui.actionRevertSorting->setEnabled(enable);
00970
00971 if (filename.isEmpty())
00972 cap = tr("Qt Linguist by Trolltech");
00973 else
00974 cap = tr("%1 - %2%3").arg( tr("Qt Linguist by Trolltech"))
00975 .arg(filename).arg(cmdl->isModified() ? "*" : "");
00976 setWindowTitle(cap);
00977 modified->setEnabled(cmdl->isModified());
00978 }
00979
00980 void TrWindow::showNewCurrent(const QModelIndex ¤t, const QModelIndex &old)
00981 {
00982 if (current.isValid()) {
00983 MessageItem *m = cmdl->messageItem(current);
00984 ContextItem *c = cmdl->contextItem(current);
00985 if (m && c) {
00986 QStringList translations = cmdl->normalizedTranslations(*m);
00987 me->showMessage(m->sourceText(), m->comment(), c->fullContext(),
00988 translations, m->message().type(), getPhrases(m->sourceText()));
00989 if (m->danger())
00990 printDanger(m);
00991 else
00992 statusBar()->clearMessage();
00993
00994 m_ui.actionDoneAndNext->setEnabled(m->message().type() !=
00995 MetaTranslatorMessage::Obsolete);
00996 } else {
00997 me->showNothing();
00998 m_ui.actionDoneAndNext->setEnabled(false);
00999 }
01000 }
01001 else {
01002 me->showNothing();
01003 m_ui.actionDoneAndNext->setEnabled(false);
01004 }
01005
01006 m_ui.actionSelectAll->setEnabled(m_ui.actionDoneAndNext->isEnabled());
01007
01008 Q_UNUSED(old);
01009 }
01010
01011 void TrWindow::updateTranslation(const QStringList &translations)
01012 {
01013 QModelIndex item = tv->currentIndex();
01014 if (!item.isValid())
01015 return;
01016
01017 MessageItem *m = cmdl->messageItem(item);
01018 if (m) {
01019 if (translations != m->translations()) {
01020 m->setTranslations(translations);
01021 updateDanger(m, true);
01022 cmdl->updateItem(item);
01023
01024 if (m->finished()) {
01025 updateFinished(false);
01026 } else {
01027 cmdl->setModified(true);
01028 updateCaption();
01029 }
01030 }
01031 }
01032 }
01033
01037 void TrWindow::updateTranslation(int context, int message, const QString &translation)
01038 {
01039 MessageItem *m = cmdl->messageItem(context, message);
01040
01041 if (m && translation != m->translation()) {
01042 m->setTranslation(translation);
01043
01044 updateDanger(m, true);
01045
01046 if (m->finished())
01047 updateFinished(false);
01048 else
01049 updateCaption();
01050
01051
01052 QModelIndex idx = cmdl->modelIndex(context, message);
01053 cmdl->updateItem(idx);
01054 }
01055 }
01056
01057 void TrWindow::updateFinished(int context, int message, bool finished)
01058 {
01059 MessageItem *m = cmdl->messageItem(context, message);
01060 if (finished != m->finished()) {
01061 m->setFinished(finished);
01062 updateProgress();
01063 updateCaption();
01064 updateStatistics();
01065
01066
01067 QModelIndex idx = cmdl->modelIndex(context, message);
01068 cmdl->updateItem(idx);
01069 }
01070 }
01071
01072
01073 void TrWindow::updateFinished(bool finished)
01074 {
01075 QModelIndex item = tv->currentIndex();
01076 if (!item.isValid())
01077 return;
01078 MessageItem *m = cmdl->messageItem(item);
01079 if (finished != m->finished()) {
01080 m->setFinished(finished);
01081 updateProgress();
01082 updateCaption();
01083 updateStatistics();
01084
01085 cmdl->updateItem(item);
01086 }
01087 }
01088
01089 void TrWindow::doneAndNext()
01090 {
01091 if (!tv->currentIndex().isValid())
01092 return;
01093
01094 MessageItem *m = cmdl->messageItem(tv->currentIndex());
01095
01096 if (!m->danger()) {
01097 updateFinished(true);
01098 nextUnfinished();
01099 me->setEditorFocus();
01100 }
01101 else {
01102 qApp->beep();
01103 }
01104 }
01105
01106 void TrWindow::toggleFinished(const QModelIndex &index)
01107 {
01108 if ( !index.isValid() || (index.column() != 0) || (index.parent() == QModelIndex()) )
01109 return;
01110
01111 MessageItem *m = cmdl->messageItem(index);
01112
01113 if (m->message().type() == MetaTranslatorMessage::Obsolete)
01114 return;
01115
01116 if (m->danger())
01117 printDanger(m);
01118
01119 if (!m->danger() && !m->finished())
01120 updateFinished(true);
01121 else if (m->finished())
01122 updateFinished(false);
01123 }
01124
01125 int TrWindow::findCurrentContextRow()
01126 {
01127 QModelIndex index = tv->selectionModel()->currentIndex();
01128 if (index.isValid())
01129 return index.row();
01130
01131
01132 setCurrentContextRow(0);
01133 return 0;
01134 }
01135
01136 bool TrWindow::setNextContext(int *currentrow, bool checkUnfinished)
01137 {
01138 QModelIndex mindx;
01139 ++(*currentrow);
01140
01141 for (; *currentrow < cmdl->contextsInList(); ++(*currentrow)) {
01142 if (!checkUnfinished) {
01143 setCurrentContextRow(*currentrow);
01144 return true;
01145 }
01146
01147 mindx = cmdl->index(*currentrow, 0);
01148 if (cmdl->contextItem(mindx)->unFinishedCount() > 0) {
01149 setCurrentContext(mindx);
01150 return true;
01151 }
01152 }
01153
01154 return false;
01155 }
01156
01157 bool TrWindow::setPrevContext(int *currentrow, bool checkUnfinished)
01158 {
01159 QModelIndex mindx;
01160 --(*currentrow);
01161
01162 for (; *currentrow >= 0; --(*currentrow)) {
01163 if (!checkUnfinished) {
01164 setCurrentContextRow(*currentrow);
01165 return true;
01166 }
01167
01168 mindx = cmdl->index(*currentrow, 0);
01169 if (cmdl->contextItem(mindx)->unFinishedCount() > 0) {
01170 setCurrentContext(mindx);
01171 return true;
01172 }
01173 }
01174
01175 return false;
01176 }
01177
01178 bool TrWindow::setNextMessage(QModelIndex *currentIndex, bool checkUnfinished)
01179 {
01180 bool found = false;
01181 if (currentIndex->isValid()) {
01182 QModelIndex idx = *currentIndex;
01183 do {
01184 int row = 0;
01185 QModelIndex par = idx.parent();
01186 if (par.isValid()) {
01187 row = idx.row() + 1;
01188 } else {
01189 par = idx;
01190 }
01191
01192 if (row >= cmdl->rowCount(par)) {
01193 int toprow = par.row() + 1;
01194 if (toprow >= cmdl->rowCount()) toprow = 0;
01195 par = cmdl->index(toprow, 0);
01196 row = 0;
01197 idx = cmdl->index(row, 1, par);
01198 } else {
01199 idx = cmdl->index(row, 1, par);
01200 }
01201 found = checkUnfinished ? !cmdl->finished(idx) : true;
01202 if (idx == *currentIndex) break;
01203 } while(!found);
01204
01205 if (found) {
01206 *currentIndex = idx;
01207 tv->setCurrentIndex(*currentIndex);
01208 }
01209 }
01210 return found;
01211 }
01212
01213 bool TrWindow::setPrevMessage(QModelIndex *currentIndex, bool checkUnfinished)
01214 {
01215 bool found = false;
01216 Q_ASSERT(currentIndex);
01217 QModelIndex idx = currentIndex->isValid() ? *currentIndex : cmdl->index(0, 0);
01218 do {
01219 int row = idx.row() - 1;
01220 QModelIndex par = idx.parent();
01221 if (!par.isValid()) {
01222 par = idx;
01223 row = -1;
01224 }
01225
01226 if (row < 0) {
01227 int toprow = par.row() - 1;
01228 if (toprow < 0) toprow = cmdl->rowCount() - 1;
01229 par = cmdl->index(toprow, 0);
01230 row = cmdl->rowCount(par) - 1;
01231 idx = cmdl->index(row, 1, par);
01232 } else {
01233 idx = cmdl->index(row, 1, par);
01234 }
01235 found = checkUnfinished ? !cmdl->finished(idx) : true;
01236 if (idx == *currentIndex) break;
01237 } while(!found);
01238
01239 if (found) {
01240 *currentIndex = idx;
01241 tv->setCurrentIndex(*currentIndex);
01242 }
01243 return found;
01244 }
01245
01246 void TrWindow::nextUnfinished()
01247 {
01248 if (m_ui.actionNextUnfinished->isEnabled()) {
01249 if (!next(true)) {
01250
01251
01252 statusBar()->showMessage(tr("No untranslated phrases left."), MessageMS);
01253 qApp->beep();
01254 }
01255 }
01256 }
01257
01258 void TrWindow::prevUnfinished()
01259 {
01260 if (m_ui.actionNextUnfinished->isEnabled()) {
01261 if (!prev(true)) {
01262
01263
01264 statusBar()->showMessage(tr("No untranslated phrases left."), MessageMS);
01265 qApp->beep();
01266 }
01267 }
01268 }
01269
01270 void TrWindow::prev()
01271 {
01272 prev(false);
01273 }
01274
01275 bool TrWindow::prev(bool checkUnfinished)
01276 {
01277 QModelIndex current = tv->currentIndex();
01278 return setPrevMessage(¤t, checkUnfinished);
01279 }
01280
01281 bool TrWindow::next(bool checkUnfinished)
01282 {
01283 QModelIndex current = tv->currentIndex();
01284 return setNextMessage(¤t, checkUnfinished);
01285 }
01286
01287 void TrWindow::next()
01288 {
01289 next(false);
01290 }
01291
01292
01293 void TrWindow::findNext(const QString &text, int where, bool matchCase)
01294 {
01295 if (text.isEmpty())
01296 return;
01297 findText = text;
01298 findWhere = where;
01299 findMatchCase = matchCase;
01300 m_ui.actionFindNext->setEnabled(true);
01301 findAgain();
01302 }
01303
01304 void TrWindow::revalidate()
01305 {
01306 if (cmdl->contextsInList() <= 0)
01307 return;
01308
01309 ContextItem *c;
01310 MessageItem *m;
01311
01312 for (int ci=0; ci<cmdl->contextsInList(); ++ci) {
01313 c = cmdl->contextItem(cmdl->index(ci, 0));
01314 for (int mi=0; mi<c->messageItemsInList(); ++mi) {
01315 m = c->messageItem(mi);
01316 updateDanger(m);
01317
01318
01319 }
01320 cmdl->updateItem(cmdl->index(ci, 0));
01321 }
01322 }
01323
01324 QString TrWindow::friendlyString(const QString& str)
01325 {
01326 QString f = str.toLower();
01327 f.replace(QRegExp(QString("[.,:;!?()-]")), QString(" "));
01328 f.replace("&", QString(""));
01329 f = f.simplified();
01330 f = f.toLower();
01331 return f;
01332 }
01333
01334
01335 void TrWindow::setupMenuBar()
01336 {
01337 m_ui.setupUi(this);
01338 m_ui.actionAccelerators->setIcon(QIcon(rsrcString + "/accelerator.png"));
01339 m_ui.actionOpenPhraseBook->setIcon(QIcon(rsrcString + "/book.png"));
01340 m_ui.actionDoneAndNext->setIcon(QIcon(rsrcString + "/doneandnext.png"));
01341 m_ui.actionCopy->setIcon(QIcon(rsrcString + "/editcopy.png"));
01342 m_ui.actionCut->setIcon(QIcon(rsrcString + "/editcut.png"));
01343 m_ui.actionPaste->setIcon(QIcon(rsrcString + "/editpaste.png"));
01344 m_ui.actionOpen->setIcon(QIcon(rsrcString + "/fileopen.png"));
01345 m_ui.actionSave->setIcon(QIcon(rsrcString + "/filesave.png"));
01346 m_ui.actionNext->setIcon(QIcon(rsrcString + "/next.png"));
01347 m_ui.actionNextUnfinished->setIcon(QIcon(rsrcString + "/nextunfinished.png"));
01348 m_ui.actionPhraseMatches->setIcon(QIcon(rsrcString + "/phrase.png"));
01349 m_ui.actionEndingPunctuation->setIcon(QIcon(rsrcString + "/punctuation.png"));
01350 m_ui.actionPrev->setIcon(QIcon(rsrcString + "/prev.png"));
01351 m_ui.actionPrevUnfinished->setIcon(QIcon(rsrcString + "/prevunfinished.png"));
01352 m_ui.actionPrint->setIcon(QIcon(rsrcString + "/print.png"));
01353 m_ui.actionRedo->setIcon(QIcon(rsrcString + "/redo.png"));
01354 m_ui.actionFind->setIcon(QIcon(rsrcString + "/searchfind.png"));
01355 m_ui.actionUndo->setIcon(QIcon(rsrcString + "/undo.png"));
01356 m_ui.actionPlaceMarkerMatches->setIcon(QIcon(rsrcString + "/validateplacemarkers.png"));
01357 m_ui.actionWhatsThis->setIcon(QIcon(rsrcString + "/whatsthis.png"));
01358
01359
01360
01361 connect(m_ui.actionOpen, SIGNAL(triggered()), this, SLOT(open()));
01362 connect(m_ui.actionSave, SIGNAL(triggered()), this, SLOT(save()));
01363 connect(m_ui.actionSaveAs, SIGNAL(triggered()), this, SLOT(saveAs()));
01364 connect(m_ui.actionRelease, SIGNAL(triggered()), this, SLOT(release()));
01365 connect(m_ui.actionReleaseAs, SIGNAL(triggered()), this, SLOT(releaseAs()));
01366 connect(m_ui.actionPrint, SIGNAL(triggered()), this, SLOT(print()));
01367 connect(m_ui.actionExit, SIGNAL(triggered()), this, SLOT(close()));
01368
01369
01370 connect(m_ui.actionUndo, SIGNAL(triggered()), me, SLOT(undo()));
01371 connect(me, SIGNAL(undoAvailable(bool)), m_ui.actionUndo, SLOT(setEnabled(bool)));
01372
01373 connect(m_ui.actionRedo, SIGNAL(triggered()), me, SLOT(redo()));
01374 connect(me, SIGNAL(redoAvailable(bool)), m_ui.actionRedo, SLOT(setEnabled(bool)));
01375
01376 connect(m_ui.actionCopy, SIGNAL(triggered()), me, SLOT(copy()));
01377 connect(me, SIGNAL(copyAvailable(bool)), m_ui.actionCopy, SLOT(setEnabled(bool)));
01378
01379 connect(me, SIGNAL(cutAvailable(bool)), m_ui.actionCut, SLOT(setEnabled(bool)));
01380 connect(m_ui.actionCut, SIGNAL(triggered()), me, SLOT(cut()));
01381
01382 connect(me, SIGNAL(pasteAvailable(bool)), m_ui.actionPaste, SLOT(setEnabled(bool)));
01383 connect(m_ui.actionPaste, SIGNAL(triggered()), me, SLOT(paste()));
01384
01385 connect(m_ui.actionSelectAll, SIGNAL(triggered()), me, SLOT(selectAll()));
01386 connect(m_ui.actionFind, SIGNAL(triggered()), this, SLOT(find()));
01387 connect(m_ui.actionFindNext, SIGNAL(triggered()), this, SLOT(findAgain()));
01388 connect(m_ui.actionSearchAndTranslate, SIGNAL(triggered()), this, SLOT(showTranslateDialog()));
01389 connect(m_ui.actionBatchTranslation, SIGNAL(triggered()), this, SLOT(showBatchTranslateDialog()));
01390
01391 connect( m_ui.actionTranslationFileSettings, SIGNAL(triggered()), this, SLOT(showTranslationSettings()) );
01392
01393
01394
01395 connect(m_ui.actionPrevUnfinished, SIGNAL(triggered()), this, SLOT(prevUnfinished()));
01396 connect(m_ui.actionNextUnfinished, SIGNAL(triggered()), this, SLOT(nextUnfinished()));
01397 connect(m_ui.actionNext, SIGNAL(triggered()), this, SLOT(next()));
01398 connect(m_ui.actionPrev, SIGNAL(triggered()), this, SLOT(prev()));
01399 connect(m_ui.actionDoneAndNext, SIGNAL(triggered()), this, SLOT(doneAndNext()));
01400 connect(m_ui.actionBeginFromSource, SIGNAL(triggered()), me, SLOT(beginFromSource()));
01401 connect(me, SIGNAL(updateActions(bool)), m_ui.actionBeginFromSource, SLOT(setEnabled(bool)));
01402
01403
01404 connect(m_ui.actionNewPhraseBook, SIGNAL(triggered()), this, SLOT(newPhraseBook()));
01405 connect(m_ui.actionOpenPhraseBook, SIGNAL(triggered()), this, SLOT(openPhraseBook()));
01406 connect(m_ui.menuClosePhraseBook, SIGNAL(triggered(QAction*)),
01407 this, SLOT(closePhraseBook(QAction*)));
01408 connect(m_ui.menuEditPhraseBook, SIGNAL(triggered(QAction*)),
01409 this, SLOT(editPhraseBook(QAction*)));
01410 connect(m_ui.menuPrintPhraseBook, SIGNAL(triggered(QAction*)),
01411 this, SLOT(printPhraseBook(QAction*)));
01412
01413
01414 connect(m_ui.actionAccelerators, SIGNAL(triggered()), this, SLOT(revalidate()));
01415 connect(m_ui.actionEndingPunctuation, SIGNAL(triggered()), this, SLOT(revalidate()));
01416 connect(m_ui.actionPhraseMatches, SIGNAL(triggered()), this, SLOT(revalidate()));
01417 connect(m_ui.actionPlaceMarkerMatches, SIGNAL(triggered()), this, SLOT(revalidate()));
01418
01419
01420 connect(m_ui.actionRevertSorting, SIGNAL(triggered()), this, SLOT(revertSorting()));
01421 connect(m_ui.actionDisplayGuesses, SIGNAL(triggered()), this, SLOT(toggleGuessing()));
01422 connect(m_ui.actionStatistics, SIGNAL(triggered()), this, SLOT(toggleStatistics()));
01423 connect(m_ui.menuView, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu()));
01424 m_ui.menuViewViews->addAction( dwScope->toggleViewAction() );
01425 m_ui.menuViewViews->addAction( me->phraseDockWnd()->toggleViewAction() );
01426
01427
01428 connect(m_batchTranslateDlg, SIGNAL(finished()), this, SLOT(finishedBatchTranslation()));
01429 connect(m_ui.actionPreviewForm, SIGNAL(triggered()), this, SLOT(previewForm()));
01430
01431 #if defined(Q_WS_MAC)
01432
01433 QMenu *windowMenu = new QMenu(tr("&Window"), this);
01434 menuBar()->insertMenu(m_ui.menuHelp->menuAction(), windowMenu);
01435 windowMenu->addAction(tr("Minimize"), this,
01436 SLOT(showMinimized()), QKeySequence(tr("Ctrl+M")));
01437 #endif
01438
01439
01440 connect(m_ui.actionManual, SIGNAL(triggered()), this, SLOT(manual()));
01441 connect(m_ui.actionAbout, SIGNAL(triggered()), this, SLOT(about()));
01442 connect(m_ui.actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
01443 connect(m_ui.actionWhatsThis, SIGNAL(triggered()), this, SLOT(onWhatsThis()));
01444
01445 connect(m_ui.menuFile, SIGNAL(aboutToShow()), this,
01446 SLOT(setupRecentFilesMenu()));
01447 connect(m_ui.menuRecentlyOpenedFiles, SIGNAL(triggered(QAction*)), this,
01448 SLOT(recentFileActivated(QAction*)));
01449
01450 m_ui.actionManual->setWhatsThis(tr("Display the manual for %1.").arg(tr("Qt Linguist")));
01451 m_ui.actionAbout->setWhatsThis(tr("Display information about %1.").arg(tr("Qt Linguist")));
01452 m_ui.actionDoneAndNext->setShortcuts(QList<QKeySequence>()
01453 << QKeySequence("Ctrl+Return")
01454 << QKeySequence("Ctrl+Enter"));
01455
01456
01457 connect(m_ui.menuPhrases, SIGNAL(aboutToShow()), this, SLOT(setupPhrase()));
01458 }
01459
01460 void TrWindow::updateViewMenu()
01461 {
01462 if (stats)
01463 m_ui.actionStatistics->setChecked(stats->isVisible());
01464 else
01465 m_ui.actionStatistics->setChecked(false);
01466 }
01467
01468 void TrWindow::onWhatsThis()
01469 {
01470 QWhatsThis::enterWhatsThisMode();
01471 }
01472
01473 void TrWindow::setupToolBars()
01474 {
01475 QToolBar *filet = new QToolBar(this);
01476 filet->setObjectName("FileToolbar");
01477 filet->setWindowTitle(tr("File"));
01478 this->addToolBar(filet);
01479 m_ui.menuToolbars->addAction(filet->toggleViewAction());
01480
01481 QToolBar *editt = new QToolBar(this);
01482 editt->setVisible(false);
01483 editt->setObjectName("EditToolbar");
01484 editt->setWindowTitle(tr("Edit"));
01485 this->addToolBar(editt);
01486 m_ui.menuToolbars->addAction(editt->toggleViewAction());
01487
01488 QToolBar *translationst = new QToolBar(this);
01489 translationst->setObjectName("TranslationToolbar");
01490 translationst->setWindowTitle(tr("Translation"));
01491 this->addToolBar(translationst);
01492 m_ui.menuToolbars->addAction(translationst->toggleViewAction());
01493
01494 QToolBar *validationt = new QToolBar(this);
01495 validationt->setObjectName("ValidationToolbar");
01496 validationt->setWindowTitle(tr("Validation"));
01497 this->addToolBar(validationt);
01498 m_ui.menuToolbars->addAction(validationt->toggleViewAction());
01499
01500 QToolBar *helpt = new QToolBar(this);
01501 helpt->setVisible(false);
01502 helpt->setObjectName("HelpToolbar");
01503 helpt->setWindowTitle(tr("Help"));
01504 this->addToolBar(helpt);
01505 m_ui.menuToolbars->addAction(helpt->toggleViewAction());
01506
01507
01508 filet->addAction(m_ui.actionOpen);
01509 filet->addAction(m_ui.actionSave);
01510 filet->addAction(m_ui.actionPrint);
01511 filet->addSeparator();
01512 filet->addAction(m_ui.actionOpenPhraseBook);
01513
01514 editt->addAction(m_ui.actionUndo);
01515 editt->addAction(m_ui.actionRedo);
01516 editt->addSeparator();
01517 editt->addAction(m_ui.actionCut);
01518 editt->addAction(m_ui.actionCopy);
01519 editt->addAction(m_ui.actionPaste);
01520 editt->addSeparator();
01521 editt->addAction(m_ui.actionFind);
01522
01523 translationst->addAction(m_ui.actionPrev);
01524 translationst->addAction(m_ui.actionNext);
01525 translationst->addAction(m_ui.actionPrevUnfinished);
01526 translationst->addAction(m_ui.actionNextUnfinished);
01527 translationst->addAction(m_ui.actionDoneAndNext);
01528
01529 validationt->addAction(m_ui.actionAccelerators);
01530 validationt->addAction(m_ui.actionEndingPunctuation);
01531 validationt->addAction(m_ui.actionPhraseMatches);
01532 validationt->addAction(m_ui.actionPlaceMarkerMatches);
01533
01534 helpt->addAction(m_ui.actionWhatsThis);
01535
01536 }
01537
01538 void TrWindow::setCurrentContext(const QModelIndex &indx)
01539 {
01540 tv->setCurrentIndex(indx);
01541 tv->scrollTo(indx);
01542 }
01543
01544 void TrWindow::setCurrentContextRow(int row)
01545 {
01546 QModelIndex mdlI = cmdl->index(row,1);
01547 tv->setCurrentIndex(mdlI);
01548 tv->scrollTo(mdlI);
01549 }
01550
01551 void TrWindow::setCurrentMessage(const QModelIndex &indx)
01552 {
01553 tv->setCurrentIndex(indx);
01554 tv->scrollTo(indx);
01555 }
01556
01557 bool TrWindow::openPhraseBook(const QString& name)
01558 {
01559 PhraseBook pb;
01560 if (!pb.load(name)) {
01561 QMessageBox::warning(this, tr("Qt Linguist"),
01562 tr("Cannot read from phrase book '%1'.").arg(name));
01563 return false;
01564 }
01565
01566 QAction *a = m_ui.menuClosePhraseBook->addAction(pb.friendlyPhraseBookName());
01567 phraseBooks[PhraseCloseMenu].insert(a, pb);
01568 a->setWhatsThis(tr("Close this phrase book."));
01569
01570 a = m_ui.menuEditPhraseBook->addAction(pb.friendlyPhraseBookName());
01571 phraseBooks[PhraseEditMenu].insert(a, pb);
01572 a->setWhatsThis(tr("Allow you to add, modify, or delete"
01573 " phrases of this phrase book."));
01574
01575 a = m_ui.menuPrintPhraseBook->addAction(pb.friendlyPhraseBookName());
01576 phraseBooks[PhrasePrintMenu].insert(a, pb);
01577 a->setWhatsThis(tr("Print the entries of the phrase"
01578 " book."));
01579
01580 updatePhraseDict();
01581 m_ui.actionBatchTranslation->setEnabled(phraseBooks[PhraseCloseMenu].count() > 0);
01582 return true;
01583 }
01584
01585 bool TrWindow::savePhraseBook(QString &name, const PhraseBook &pb)
01586 {
01587 if (!name.contains(".qph") && !name.contains("."))
01588 name += ".qph";
01589
01590 if (!pb.save(name)) {
01591 QMessageBox::warning(this, tr("Qt Linguist"),
01592 tr("Cannot create phrase book '%1'.").arg(name));
01593 return false;
01594 }
01595 return true;
01596 }
01597
01598 void TrWindow::updateProgress()
01599 {
01600 int numNonobsolete = cmdl->getNumNonobsolete();
01601 int numFinished = cmdl->getNumFinished();
01602 if (numNonobsolete == 0)
01603 progress->setText(QString(" " " "));
01604 else
01605 progress->setText(QString(" %1/%2 ").arg(numFinished)
01606 .arg(numNonobsolete));
01607 m_ui.actionPrevUnfinished->setEnabled(numFinished != numNonobsolete);
01608 m_ui.actionNextUnfinished->setEnabled(numFinished != numNonobsolete);
01609
01610 m_ui.actionPrev->setEnabled(cmdl->contextsInList() > 0);
01611 m_ui.actionNext->setEnabled(cmdl->contextsInList() > 0);
01612 }
01613
01614 void TrWindow::updatePhraseDict()
01615 {
01616 phraseDict.clear();
01617
01618 foreach (PhraseBook pb, phraseBooks[PhraseCloseMenu]) {
01619 foreach (Phrase p, pb) {
01620 QString f = friendlyString(p.source());
01621 if ( f.length() > 0 ) {
01622 f = f.split(QChar(' ')).first();
01623 if (!phraseDict.contains(f)) {
01624 PhraseBook pbe;
01625 phraseDict.insert(f, pbe);
01626 }
01627 phraseDict[f].append(p);
01628 }
01629 }
01630 }
01631 revalidate();
01632 }
01633
01634 PhraseBook TrWindow::getPhrases(const QString &source)
01635 {
01636 PhraseBook phrases;
01637 QString f = friendlyString(source);
01638 QStringList lookupWords = f.split(QChar(' '));
01639
01640 foreach (QString s, lookupWords) {
01641 if (phraseDict.contains(s)) {
01642 PhraseBook ent = phraseDict.value(s);
01643 foreach (Phrase p, ent) {
01644 if (f.indexOf(friendlyString((p).source())) >= 0)
01645 phrases.append(p);
01646 }
01647 }
01648 }
01649 return phrases;
01650 }
01651
01652 void TrWindow::printDanger(MessageItem *m)
01653 {
01654 danger(m, true);
01655 }
01656
01657 bool TrWindow::updateDanger(MessageItem *m, bool verbose)
01658 {
01659 bool dngr = danger(m, verbose);
01660
01661 if (dngr != m->danger())
01662 m->setDanger(dngr);
01663
01664 return dngr;
01665 }
01666
01667 bool TrWindow::danger( const MessageItem *m,
01668 bool verbose )
01669 {
01670 QString source = m->sourceText();
01671 QStringList translations = m->translations();
01672 if (m_ui.actionAccelerators->isChecked()) {
01673 bool sk = source.contains(Qt::Key_Ampersand);
01674 bool tk = true;
01675 for (int i = 0; i < translations.count() && tk; ++i) {
01676 tk &= bool(translations[i].contains(Qt::Key_Ampersand));
01677 }
01678
01679 if (!sk && tk) {
01680 if (verbose)
01681 statusBar()->showMessage(tr("Accelerator possibly superfluous in"
01682 " translation."), ErrorMS);
01683 return true;
01684 } else if (sk && !tk) {
01685 if (verbose)
01686 statusBar()->showMessage(tr("Accelerator possibly missing in"
01687 " translation."), ErrorMS);
01688 return true;
01689 }
01690 }
01691 if (m_ui.actionEndingPunctuation->isChecked()) {
01692 bool endingok = true;
01693 for (int i = 0; i < translations.count() && endingok; ++i) {
01694 endingok &= (ending( source, cmdl->language()) == ending(translations[i], cmdl->language() ));
01695 }
01696
01697 if (!endingok) {
01698 if (verbose)
01699 statusBar()->showMessage(tr("Translation does not end with the"
01700 " same punctuation as the source text."), ErrorMS);
01701 return true;
01702 }
01703 }
01704 if (m_ui.actionPhraseMatches->isChecked()) {
01705 QString fsource = friendlyString(source);
01706 QString ftranslation = friendlyString(translations.first());
01707 QStringList lookupWords = fsource.split(QChar(' '));
01708
01709 bool phraseFound;
01710 foreach (QString s, lookupWords) {
01711 if (phraseDict.contains(s)) {
01712 PhraseBook ent = phraseDict.value(s);
01713 phraseFound = false;
01714 foreach (Phrase p, ent) {
01715 if (fsource.indexOf(friendlyString(p.source())) < 0 ||
01716 ftranslation.indexOf(friendlyString(p.target())) >= 0) {
01717 phraseFound = true;
01718 break;
01719 }
01720 }
01721 if (!phraseFound) {
01722 if (verbose)
01723 statusBar()->showMessage(tr("A phrase book suggestion for"
01724 " '%1' was ignored.").arg(s), ErrorMS );
01725 return true;
01726 }
01727 }
01728 }
01729 }
01730
01731 if (m_ui.actionPlaceMarkerMatches->isChecked()) {
01732
01733
01734
01735
01736
01737
01738
01739 QVector<int> placeMarkerIndexes;
01740 QString translation;
01741 int numTranslations = translations.count();
01742 for (int pass = 0; pass < numTranslations + 1; ++pass) {
01743 const QChar *uc_begin = source.unicode();
01744 const QChar *uc_end = uc_begin + source.length();
01745 if (pass >= 1) {
01746 translation = translations[pass - 1];
01747 uc_begin = translation.unicode();
01748 uc_end = uc_begin + translation.length();
01749 }
01750 const QChar *c = uc_begin;
01751 while (c < uc_end) {
01752 if (c->unicode() == '%') {
01753 const QChar *escape_start = ++c;
01754 while (c->isDigit()) ++c;
01755 const QChar *escape_end = c;
01756 bool ok = true;
01757 int markerIndex = QString::fromRawData(escape_start, escape_end - escape_start).toInt(&ok);
01758 if (ok) {
01759 if (markerIndex >= placeMarkerIndexes.size()) {
01760 placeMarkerIndexes.resize(markerIndex + 1);
01761 }
01762 placeMarkerIndexes[markerIndex]+= (pass == 0 ? numTranslations : -1);
01763 }
01764 }
01765 ++c;
01766 }
01767 }
01768
01769 for (int i = 0; i < placeMarkerIndexes.size(); ++i) {
01770 if (placeMarkerIndexes.at(i) != 0) {
01771 if (verbose)
01772 statusBar()->showMessage(tr("Translation does not refer"
01773 " to the same place markers as in the source text."), ErrorMS);
01774 return true;
01775
01776 }
01777 }
01778 }
01779 if (verbose)
01780 statusBar()->clearMessage();
01781
01782 return false;
01783 }
01784
01785 void TrWindow::readConfig()
01786 {
01787 QString keybase(QString::number((QT_VERSION >> 16) & 0xff)
01788 + "." + QString::number((QT_VERSION >> 8) & 0xff) + "/");
01789 QSettings config;
01790
01791 QRect r( pos(), size() );
01792 recentFiles = config.value(keybase + "RecentlyOpenedFiles").toStringList();
01793 restoreGeometry(config.value(keybase + "Geometry/WindowGeometry").toByteArray());
01794 restoreState(config.value(keybase + "MainWindowState").toByteArray());
01795
01796 m_ui.actionAccelerators->setChecked(config.value(keybase+ "Validators/Accelerator", true).toBool());
01797 m_ui.actionEndingPunctuation->setChecked(config.value(keybase+ "Validators/EndingPunctuation", true).toBool());
01798 m_ui.actionPhraseMatches->setChecked(config.value(keybase+ "Validators/PhraseMatch", true).toBool());
01799 m_ui.actionPlaceMarkerMatches->setChecked(config.value(keybase+ "Validators/PlaceMarkers", true).toBool());
01800 }
01801
01802 void TrWindow::writeConfig()
01803 {
01804 QString keybase(QString::number( (QT_VERSION >> 16) & 0xff ) +
01805 "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" );
01806 QSettings config;
01807 config.setValue(keybase + "RecentlyOpenedFiles", recentFiles);
01808 config.setValue(keybase + "Geometry/WindowGeometry", saveGeometry());
01809 config.setValue(keybase+ "Validators/Accelerator", m_ui.actionAccelerators->isChecked());
01810 config.setValue(keybase+ "Validators/EndingPunctuation", m_ui.actionEndingPunctuation->isChecked());
01811 config.setValue(keybase+ "Validators/PhraseMatch", m_ui.actionPhraseMatches->isChecked());
01812 config.setValue(keybase+ "Validators/PlaceMarkers", m_ui.actionPlaceMarkerMatches->isChecked());
01813 config.setValue(keybase + "MainWindowState", saveState());
01814 }
01815
01816 void TrWindow::setupRecentFilesMenu()
01817 {
01818 m_ui.menuRecentlyOpenedFiles->clear();
01819
01820 if (recentFiles.count() > 0) {
01821 m_ui.menuRecentlyOpenedFiles->setEnabled(true);
01822 QStringList::Iterator it = recentFiles.begin();
01823 for (; it != recentFiles.end(); ++it) {
01824 m_ui.menuRecentlyOpenedFiles->addAction(*it);
01825 }
01826 } else {
01827 m_ui.menuRecentlyOpenedFiles->setEnabled(false);
01828 }
01829 }
01830
01831 void TrWindow::recentFileActivated(QAction *action)
01832 {
01833 if (!action->text().isEmpty()) {
01834 if (maybeSave())
01835 openFile(action->text());
01836 }
01837 }
01838
01839 void TrWindow::addRecentlyOpenedFile(const QString &fn, QStringList &lst)
01840 {
01841 QFileInfo fi(fn);
01842 if (lst.contains(fi.absoluteFilePath()))
01843 return;
01844 if ( lst.count() >= 10 )
01845 lst.removeLast();
01846
01847 lst.prepend(fi.absoluteFilePath());
01848 }
01849
01850 void TrWindow::toggleGuessing()
01851 {
01852 me->toggleGuessing();
01853 }
01854
01855 void TrWindow::focusSourceList()
01856 {
01857 stv->setFocus();
01858 }
01859
01860 void TrWindow::focusPhraseList()
01861 {
01862 ptv->setFocus();
01863 }
01864
01865 void TrWindow::toggleStatistics()
01866 {
01867 if (m_ui.actionStatistics->isChecked()) {
01868 if (!stats) {
01869 stats = new Statistics(this);
01870 connect(cmdl, SIGNAL(statsChanged(int,int,int,int,int,int)), stats,
01871 SLOT(updateStats(int,int,int,int,int,int)));
01872 }
01873 stats->show();
01874 updateStatistics();
01875 }
01876 else if (stats) {
01877 stats->close();
01878 }
01879 }
01880
01881 void TrWindow::updateStatistics()
01882 {
01883
01884
01885 if (!stats || !stats->isVisible())
01886 return;
01887
01888 cmdl->updateStatistics();
01889 }
01890
01891 void TrWindow::finishedBatchTranslation()
01892 {
01893 updateStatistics();
01894 updateProgress();
01895 updateCaption();
01896 }
01897
01898 QStringList TrWindow::findFormFilesInCurrentTranslationFile()
01899 {
01900 QStringList ret;
01901 for (MessageModel::iterator it = cmdl->begin(); it != cmdl->end(); ++it) {
01902 QString fileName = (*it)->message().fileName();
01903 if (fileName.endsWith(QLatin1String(".ui"))) {
01904 if (!ret.contains(fileName)) {
01905 ret+=fileName;
01906 }
01907 }
01908 }
01909 return ret;
01910 }
01911
01912 void TrWindow::previewForm()
01913 {
01914 if (m_previewTool.isNull()) {
01915 m_previewTool = new TrPreviewTool();
01916 QStringList fileNames = findFormFilesInCurrentTranslationFile();
01917 bool ok = true;
01918 for (QStringList::iterator it = fileNames.begin(); it != fileNames.end(); ++it) {
01919 QString fileName = *it;
01920 if (!fileName.isEmpty() && QFileInfo(fileName).exists()) {
01921 if (!m_previewTool->addFormFile(fileName)) {
01922 ok = false;
01923 break;
01924 }
01925 }
01926 }
01927 if (ok) {
01928 ok = m_previewTool->addTranslator(cmdl->translator(), QFileInfo(filename).fileName());
01929 if (ok) {
01930 m_previewTool->cascade();
01931 } else {
01932 QMessageBox::warning(this, tr("Qt Linguist"), tr("There was a problem in the preparation of form preview."));
01933 }
01934 }
01935 } else {
01936
01937 m_previewTool->reloadTranslations();
01938 }
01939 m_previewTool->show();
01940 }
01941
01942 void TrWindow::showTranslationSettings()
01943 {
01944 if (!m_translationSettingsDialog) {
01945 m_translationSettingsDialog = new TranslationSettingsDialog(this);
01946 }
01947 m_translationSettingsDialog->setMessageModel(cmdl);
01948 m_translationSettingsDialog->exec();
01949 }