• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

lokalize

  • sources
  • kde-4.14
  • kdesdk
  • lokalize
  • src
  • tm
tmview.cpp
Go to the documentation of this file.
1 /* ****************************************************************************
2  This file is part of Lokalize
3 
4  Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License as
8  published by the Free Software Foundation; either version 2 of
9  the License or (at your option) version 3 or any later version
10  accepted by the membership of KDE e.V. (or its successor approved
11  by the membership of KDE e.V.), which shall act as a proxy
12  defined in Section 14 of version 3 of the license.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 **************************************************************************** */
23 
24 #include "tmview.h"
25 
26 #include "jobs.h"
27 #include "tmscanapi.h"
28 #include "catalog.h"
29 #include "cmd.h"
30 #include "project.h"
31 #include "prefs_lokalize.h"
32 #include "dbfilesmodel.h"
33 #include "diff.h"
34 #include "xlifftextedit.h"
35 
36 #include <klocale.h>
37 #include <kdebug.h>
38 #include <threadweaver/ThreadWeaver.h>
39 #include <ktextbrowser.h>
40 #include <kglobalsettings.h>
41 #include <kpassivepopup.h>
42 #include <kaction.h>
43 #include <kmessagebox.h>
44 
45 #include <QTime>
46 #include <QDragEnterEvent>
47 #include <QFileInfo>
48 #include <QDir>
49 #include <QSignalMapper>
50 #include <QTimer>
51 #include <QToolTip>
52 #include <QMenu>
53 
54 #ifdef NDEBUG
55 #undef NDEBUG
56 #endif
57 #define DEBUG
58 using namespace TM;
59 
60 
61 struct DiffInfo
62 {
63  DiffInfo(int reserveSize);
64 
65  QString diffClean;
66  QString old;
67  //Formatting info:
68  QByteArray diffIndex;
69  //Map old string-->d.diffClean
70  QVector<int> old2DiffClean;
71 };
72 
73 DiffInfo::DiffInfo(int reserveSize)
74 {
75  diffClean.reserve(reserveSize);
76  old.reserve(reserveSize);
77  diffIndex.reserve(reserveSize);
78  old2DiffClean.reserve(reserveSize);
79 }
80 
81 
82 
92 static DiffInfo getDiffInfo(const QString& diff)
93 {
94  DiffInfo d(diff.size());
95 
96  QChar sep('{');
97  char state='0';
98  //walk through diff string char-by-char
99  //calculate old and others
100  int pos=-1;
101  while (++pos<diff.size())
102  {
103  if (diff.at(pos)==sep)
104  {
105  if (diff.indexOf("{KBABELDEL}",pos)==pos)
106  {
107  state='-';
108  pos+=10;
109  }
110  else if (diff.indexOf("{KBABELADD}",pos)==pos)
111  {
112  state='+';
113  pos+=10;
114  }
115  else if (diff.indexOf("{/KBABEL",pos)==pos)
116  {
117  state='0';
118  pos+=11;
119  }
120  }
121  else
122  {
123  if (state!='+')
124  {
125  d.old.append(diff.at(pos));
126  d.old2DiffClean.append(d.diffIndex.count());
127  }
128  d.diffIndex.append(state);
129  d.diffClean.append(diff.at(pos));
130  }
131  }
132  return d;
133 }
134 
135 
136 void TextBrowser::mouseDoubleClickEvent(QMouseEvent* event)
137 {
138  KTextBrowser::mouseDoubleClickEvent(event);
139 
140  QString sel=textCursor().selectedText();
141  if (!(sel.isEmpty()||sel.contains(' ')))
142  emit textInsertRequested(sel);
143 }
144 
145 
146 TMView::TMView(QWidget* parent, Catalog* catalog, const QVector<KAction*>& actions)
147  : QDockWidget ( i18nc("@title:window","Translation Memory"), parent)
148  , m_browser(new TextBrowser(this))
149  , m_catalog(catalog)
150  , m_currentSelectJob(0)
151  , m_actions(actions)
152  , m_normTitle(i18nc("@title:window","Translation Memory"))
153  , m_hasInfoTitle(m_normTitle+" [*]")
154  , m_hasInfo(false)
155  , m_isBatching(false)
156  , m_markAsFuzzy(false)
157 {
158  setObjectName("TMView");
159  setWidget(m_browser);
160 
161  m_browser->document()->setDefaultStyleSheet("p.close_match { font-weight:bold; }");
162  m_browser->viewport()->setBackgroundRole(QPalette::Background);
163 
164  QTimer::singleShot(0,this,SLOT(initLater()));
165  connect(m_catalog,SIGNAL(signalFileLoaded(KUrl)),
166  this,SLOT(slotFileLoaded(KUrl)));
167 }
168 
169 TMView::~TMView()
170 {
171  int i=m_jobs.size();
172  while (--i>=0)
173  ThreadWeaver::Weaver::instance()->dequeue(m_jobs.takeLast());
174 }
175 
176 void TMView::initLater()
177 {
178  setAcceptDrops(true);
179 
180  QSignalMapper* signalMapper=new QSignalMapper(this);
181  int i=m_actions.size();
182  while(--i>=0)
183  {
184  connect(m_actions.at(i),SIGNAL(triggered()),signalMapper,SLOT(map()));
185  signalMapper->setMapping(m_actions.at(i), i);
186  }
187  connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(slotUseSuggestion(int)));
188 
189  setToolTip(i18nc("@info:tooltip","Double-click any word to insert it into translation"));
190 
191  DBFilesModel::instance();
192 
193  connect(m_browser,SIGNAL(textInsertRequested(QString)),this,SIGNAL(textInsertRequested(QString)));
194  connect(m_browser,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
195  //TODO ? kdisplayPaletteChanged
196 // connect(KGlobalSettings::self(),,SIGNAL(kdisplayPaletteChanged()),this,SLOT(slotPaletteChanged()));
197 
198 }
199 
200 void TMView::dragEnterEvent(QDragEnterEvent* event)
201 {
202  if (dragIsAcceptable(event->mimeData()->urls()))
203  event->acceptProposedAction();
204 }
205 
206 void TMView::dropEvent(QDropEvent *event)
207 {
208  if (scanRecursive(event->mimeData()->urls(),Project::instance()->projectID()))
209  event->acceptProposedAction();
210 }
211 
212 void TMView::slotFileLoaded(const KUrl& url)
213 {
214  const QString& pID=Project::instance()->projectID();
215 
216  if (Settings::scanToTMOnOpen())
217  {
218  ScanJob* job=new ScanJob(url,pID);
219  connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
220  ThreadWeaver::Weaver::instance()->enqueue(job);
221  }
222 
223  if (!Settings::prefetchTM()
224  &&!m_isBatching)
225  return;
226 
227  m_cache.clear();
228  int i=m_jobs.size();
229  while (--i>=0)
230  ThreadWeaver::Weaver::instance()->dequeue(m_jobs.takeLast());
231 
232  DocPosition pos;
233  while(switchNext(m_catalog,pos))
234  {
235  if (!m_catalog->isEmpty(pos.entry)
236  &&m_catalog->isApproved(pos.entry))
237  continue;
238  SelectJob* j=initSelectJob(m_catalog, pos, pID);
239  connect(j,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotCacheSuggestions(ThreadWeaver::Job*)));
240  m_jobs.append(j);
241  }
242 
243  //dummy job for the finish indication
244  BatchSelectFinishedJob* m_seq=new BatchSelectFinishedJob(this);
245  connect(m_seq,SIGNAL(done(ThreadWeaver::Job*)),m_seq,SLOT(deleteLater()));
246  connect(m_seq,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotBatchSelectDone(ThreadWeaver::Job*)));
247  ThreadWeaver::Weaver::instance()->enqueue(m_seq);
248  m_jobs.append(m_seq);
249 }
250 
251 void TMView::slotCacheSuggestions(ThreadWeaver::Job* j)
252 {
253  m_jobs.removeAll(j);
254  SelectJob* job=static_cast<SelectJob*>(j);
255  kDebug()<<job->m_pos.entry;
256  if (job->m_pos.entry==m_pos.entry)
257  slotSuggestionsCame(j);
258 
259  m_cache[DocPos(job->m_pos)]=job->m_entries.toVector();
260 }
261 
262 void TMView::slotBatchSelectDone(ThreadWeaver::Job* /*j*/)
263 {
264  m_jobs.clear();
265  if (!m_isBatching)
266  return;
267 
268  bool insHappened=false;
269  DocPosition pos;
270  while(switchNext(m_catalog,pos))
271  {
272  if (!(m_catalog->isEmpty(pos.entry)
273  ||!m_catalog->isApproved(pos.entry))
274  )
275  continue;
276  const QVector<TMEntry>& suggList=m_cache.value(DocPos(pos));
277  if (suggList.isEmpty())
278  continue;
279  const TMEntry& entry=suggList.first();
280  if (entry.score<9900)//hacky
281  continue;
282  {
283  bool forceFuzzy=(suggList.size()>1&&suggList.at(1).score>=10000)
284  ||entry.score<10000;
285  bool ctxtMatches=entry.score==1001;
286  if (!m_catalog->isApproved(pos.entry))
287  {
289  removeTargetSubstring(m_catalog, pos, 0, m_catalog->targetWithTags(pos).string.size());
290  if ( ctxtMatches || !(m_markAsFuzzy||forceFuzzy) )
291  SetStateCmd::push(m_catalog,pos,true);
292  }
293  else if ((m_markAsFuzzy&&!ctxtMatches)||forceFuzzy)
294  {
295  SetStateCmd::push(m_catalog,pos,false);
296  }
298  insertCatalogString(m_catalog, pos, entry.target, 0);
299 
300  if (KDE_ISUNLIKELY( m_pos.entry==pos.entry&&pos.form==m_pos.form ))
301  emit refreshRequested();
302 
303  }
304  if (!insHappened)
305  {
306  insHappened=true;
307  m_catalog->beginMacro(i18nc("@item Undo action","Batch translation memory filling"));
308  }
309  }
310  QString msg=i18nc("@info","Batch translation has been completed.");
311  if (insHappened)
312  m_catalog->endMacro();
313  else
314  {
315  // xgettext: no-c-format
316  msg+=' ';
317  msg+=i18nc("@info","No suggestions with exact matches were found.");
318  }
319 
320  KPassivePopup::message(KPassivePopup::Balloon,
321  i18nc("@title","Batch translation complete"),
322  msg,
323  this);
324 }
325 
326 void TMView::slotBatchTranslate()
327 {
328  m_isBatching=true;
329  m_markAsFuzzy=false;
330  if (!Settings::prefetchTM())
331  slotFileLoaded(m_catalog->url());
332  else if (m_jobs.isEmpty())
333  return slotBatchSelectDone(0);
334  KPassivePopup::message(KPassivePopup::Balloon,
335  i18nc("@title","Batch translation"),
336  i18nc("@info","Batch translation has been scheduled."),
337  this);
338 
339 }
340 
341 void TMView::slotBatchTranslateFuzzy()
342 {
343  m_isBatching=true;
344  m_markAsFuzzy=true;
345  if (!Settings::prefetchTM())
346  slotFileLoaded(m_catalog->url());
347  else if (m_jobs.isEmpty())
348  slotBatchSelectDone(0);
349  KPassivePopup::message(KPassivePopup::Balloon,
350  i18nc("@title","Batch translation"),
351  i18nc("@info","Batch translation has been scheduled."),
352  this);
353 
354 }
355 
356 void TMView::slotNewEntryDisplayed(const DocPosition& pos)
357 {
358  if (m_catalog->numberOfEntries()<=pos.entry)
359  return;//because of Qt::QueuedConnection
360 
361  ThreadWeaver::Weaver::instance()->dequeue(m_currentSelectJob);
362 
363  //update DB
364  //m_catalog->flushUpdateDBBuffer();
365  //this is called via subscribtion
366 
367  if (pos.entry!=-1)
368  m_pos=pos;
369  m_browser->clear();
370  if (Settings::prefetchTM()
371  &&m_cache.contains(DocPos(m_pos)))
372  {
373  QTimer::singleShot(0,this,SLOT(displayFromCache()));
374  }
375  m_currentSelectJob=initSelectJob(m_catalog, m_pos);
376  connect(m_currentSelectJob,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotSuggestionsCame(ThreadWeaver::Job*)));
377 }
378 
379 void TMView::displayFromCache()
380 {
381  if (m_prevCachePos.entry==m_pos.entry
382  &&m_prevCachePos.form==m_pos.form)
383  return;
384  SelectJob* temp=initSelectJob(m_catalog, m_pos, QString(), 0);
385  temp->m_entries=m_cache.value(DocPos(m_pos)).toList();
386  slotSuggestionsCame(temp);
387  temp->deleteLater();
388  m_prevCachePos=m_pos;
389 }
390 
391 void TMView::slotSuggestionsCame(ThreadWeaver::Job* j)
392 {
393  QTime time;time.start();
394 
395  SelectJob& job=*(static_cast<SelectJob*>(j));
396  if (job.m_pos.entry!=m_pos.entry)
397  return;
398 
399  Catalog& catalog=*m_catalog;
400  if (catalog.numberOfEntries()<=m_pos.entry)
401  return;//because of Qt::QueuedConnection
402 
403 
404  //BEGIN query other DBs handling
405  Project* project=Project::instance();
406  const QString& projectID=project->projectID();
407  //check if this is an additional query, from secondary DBs
408  if (job.m_dbName!=projectID)
409  {
410  job.m_entries+=m_entries;
411  qSort(job.m_entries.begin(), job.m_entries.end(), qGreater<TMEntry>());
412  int limit=qMin(Settings::suggCount(),job.m_entries.size());
413  int i=job.m_entries.size();
414  while(--i>=limit)
415  job.m_entries.removeLast();
416  }
417  else if (job.m_entries.isEmpty()||job.m_entries.first().score<8500)
418  {
419  //be careful, as we switched to QDirModel!
420  const DBFilesModel& dbFilesModel=*(DBFilesModel::instance());
421  QModelIndex root=dbFilesModel.rootIndex();
422  int i=dbFilesModel.rowCount(root);
423  //kWarning()<<"query other DBs,"<<i<<"total";
424  while (--i>=0)
425  {
426  const QString& dbName=dbFilesModel.data(dbFilesModel.index(i,0,root)).toString();
427  if (projectID!=dbName && dbFilesModel.m_configurations.value(dbName).targetLangCode==catalog.targetLangCode())
428  {
429  SelectJob* j=initSelectJob(m_catalog, m_pos, dbName);
430  connect(j,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotSuggestionsCame(ThreadWeaver::Job*)));
431  m_jobs.append(j);
432  }
433  }
434  }
435  //END query other DBs handling
436 
437  m_entries=job.m_entries;
438 
439  int limit=job.m_entries.size();
440 
441  if (!limit)
442  {
443  if (m_hasInfo)
444  {
445  m_hasInfo=false;
446  setWindowTitle(m_normTitle);
447  }
448  return;
449  }
450  if (!m_hasInfo)
451  {
452  m_hasInfo=true;
453  setWindowTitle(m_hasInfoTitle);
454  }
455 
456  setUpdatesEnabled(false);
457  m_browser->clear();
458  m_entryPositions.clear();
459 
460  //m_entries=job.m_entries;
461  //m_browser->insertHtml("<html>");
462 
463  int i=0;
464  QTextBlockFormat blockFormatBase;
465  QTextBlockFormat blockFormatAlternate; blockFormatAlternate.setBackground(QPalette().alternateBase());
466  QTextCharFormat noncloseMatchCharFormat;
467  QTextCharFormat closeMatchCharFormat; closeMatchCharFormat.setFontWeight(QFont::Bold);
468  forever
469  {
470  QTextCursor cur=m_browser->textCursor();
471  QString html;
472  html.reserve(1024);
473 
474  const TMEntry& entry=job.m_entries.at(i);
475  html+=(entry.score>9500)?"<p class='close_match'>":"<p>";
476  //kDebug()<<entry.target.string<<entry.hits;
477 
478  html+=QString("/%1%/ ").arg(entry.score > 10000 ? 100: float(entry.score)/100);
479 
480  //int sourceStartPos=cur.position();
481  QString result=Qt::escape(entry.diff);
482  //result.replace("&","&amp;");
483  //result.replace("<","&lt;");
484  //result.replace(">","&gt;");
485  result.replace("{KBABELADD}","<font style=\"background-color:"%Settings::addColor().name()%";color:black\">");
486  result.replace("{/KBABELADD}","</font>");
487  result.replace("{KBABELDEL}","<font style=\"background-color:"%Settings::delColor().name()%";color:black\">");
488  result.replace("{/KBABELDEL}","</font>");
489  result.replace("\\n","\\n<br>");
490  result.replace("\\n","\\n<br>");
491  html+=result;
492 #if 0
493  cur.insertHtml(result);
494 
495  cur.movePosition(QTextCursor::PreviousCharacter,QTextCursor::MoveAnchor,cur.position()-sourceStartPos);
496  CatalogString catStr(entry.diff);
497  catStr.string.remove("{KBABELDEL}"); catStr.string.remove("{/KBABELDEL}");
498  catStr.string.remove("{KBABELADD}"); catStr.string.remove("{/KBABELADD}");
499  catStr.tags=entry.source.tags;
500  DiffInfo d=getDiffInfo(entry.diff);
501  int j=catStr.tags.size();
502  while(--j>=0)
503  {
504  catStr.tags[j].start=d.old2DiffClean.at(catStr.tags.at(j).start);
505  catStr.tags[j].end =d.old2DiffClean.at(catStr.tags.at(j).end);
506  }
507  insertContent(cur,catStr,job.m_source,false);
508 #endif
509 
510  //str.replace('&',"&amp;"); TODO check
511  html+="<br>";
512  if (KDE_ISLIKELY( i<m_actions.size() ))
513  {
514  m_actions.at(i)->setStatusTip(entry.target.string);
515  html+=QString("[%1] ").arg(m_actions.at(i)->shortcut().toString());
516  }
517  else
518  html+="[ - ] ";
519 /*
520  QString str(entry.target.string);
521  str.replace('<',"&lt;");
522  str.replace('>',"&gt;");
523  html+=str;
524 */
525  cur.insertHtml(html); html.clear();
526  cur.setCharFormat((entry.score>9500)?closeMatchCharFormat:noncloseMatchCharFormat);
527  insertContent(cur,entry.target);
528  m_entryPositions.insert(cur.anchor(),i);
529 
530  html+=i?"<br></p>":"</p>";
531  cur.insertHtml(html);
532 
533  if (KDE_ISUNLIKELY( ++i>=limit ))
534  break;
535 
536  cur.insertBlock(i%2?blockFormatAlternate:blockFormatBase);
537 
538  }
539  m_browser->insertHtml("</html>");
540  setUpdatesEnabled(true);
541 // kWarning()<<"ELA "<<time.elapsed()<<"BLOCK COUNT "<<m_browser->document()->blockCount();
542 }
543 
544 
545 /*
546 void TMView::slotPaletteChanged()
547 {
548 
549 }*/
550 bool TMView::event(QEvent *event)
551 {
552  if (event->type()==QEvent::ToolTip)
553  {
554  QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
555  //int block1=m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).blockNumber();
556  QMap<int,int>::iterator block =m_entryPositions.lowerBound(m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).anchor());
557  if (block!=m_entryPositions.end() && *block<m_entries.size())
558  {
559  const TMEntry& tmEntry=m_entries.at(*block);
560  QString file=tmEntry.file;
561  if (file==m_catalog->url().toLocalFile())
562  file=i18nc("File argument in tooltip, when file is current file", "this");
563  QString tooltip=i18nc("@info:tooltip","File: %1<br />Addition date: %2",file, tmEntry.date.toString(Qt::ISODate));
564  if (!tmEntry.changeDate.isNull() && tmEntry.changeDate!=tmEntry.date)
565  tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Last change date: %1", tmEntry.changeDate.toString(Qt::ISODate));
566  if (!tmEntry.changeAuthor.isEmpty())
567  tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Last change author: %1", tmEntry.changeAuthor);
568  tooltip+=i18nc("@info:tooltip on TM entry continues","<br />TM: %1", tmEntry.dbName);
569  if (tmEntry.obsolete)
570  tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Is not present in the file anymore");
571  QToolTip::showText(helpEvent->globalPos(),tooltip);
572  return true;
573  }
574  }
575  return QWidget::event(event);
576 }
577 
578 void TMView::contextMenu(const QPoint& pos)
579 {
580  int block=*m_entryPositions.lowerBound(m_browser->cursorForPosition(pos).anchor());
581  kWarning()<<block;
582  if (block>=m_entries.size())
583  return;
584 
585  const TMEntry& e=m_entries.at(block);
586  enum {Remove, Open};
587  QMenu popup;
588  popup.addAction(i18nc("@action:inmenu", "Remove this entry"))->setData(Remove);
589  if (e.file!= m_catalog->url().toLocalFile() && QFile::exists(e.file))
590  popup.addAction(i18nc("@action:inmenu", "Open file containing this entry"))->setData(Open);
591  QAction* r=popup.exec(m_browser->mapToGlobal(pos));
592  if (!r)
593  return;
594  if ((r->data().toInt()==Remove) &&
595  KMessageBox::Yes==KMessageBox::questionYesNo(this, i18n("<html>Do you really want to remove this entry:<br/><i>%1</i><br/>from translation memory %2?</html>", Qt::escape(e.target.string), e.dbName),
596  i18nc("@title:window","Translation Memory Entry Removal")))
597  {
598  RemoveJob* job=new RemoveJob(e);
599  connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
600  connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotNewEntryDisplayed()));
601  ThreadWeaver::Weaver::instance()->enqueue(job);
602  }
603  else if (r->data().toInt()==Open)
604  emit fileOpenRequested(e.file, e.source.string, e.ctxt);
605 }
606 
612 static int nextPlacableIn(const QString& old, int start, QString& cap)
613 {
614  static QRegExp rxNum("[\\d\\.\\%]+");
615  static QRegExp rxAbbr("\\w+");
616 
617  int numPos=rxNum.indexIn(old,start);
618 // int abbrPos=rxAbbr.indexIn(old,start);
619  int abbrPos=start;
620  //kWarning()<<"seeing"<<old.size()<<old;
621  while (((abbrPos=rxAbbr.indexIn(old,abbrPos))!=-1))
622  {
623  QString word=rxAbbr.cap(0);
624  //check if tail contains uppoer case characters
625  const QChar* c=word.unicode()+1;
626  int i=word.size()-1;
627  while (--i>=0)
628  {
629  if ((c++)->isUpper())
630  break;
631  }
632  abbrPos+=rxAbbr.matchedLength();
633  }
634 
635  int pos=qMin(numPos,abbrPos);
636  if (pos==-1)
637  pos=qMax(numPos,abbrPos);
638 
639 // if (pos==numPos)
640 // cap=rxNum.cap(0);
641 // else
642 // cap=rxAbbr.cap(0);
643 
644  cap=(pos==numPos?rxNum:rxAbbr).cap(0);
645  //kWarning()<<cap;
646 
647  return pos;
648 }
649 
650 
651 
652 
653 
654 //TODO thorough testing
655 
660 CatalogString TM::targetAdapted(const TMEntry& entry, const CatalogString& ref)
661 {
662  kWarning()<<entry.source.string<<entry.target.string<<entry.diff;
663 
664  QString diff=entry.diff;
665  CatalogString target=entry.target;
666  //QString english=entry.english;
667 
668 
669  QRegExp rxAdd("<font style=\"background-color:[^>]*" % Settings::addColor().name() % "[^>]*\">([^>]*)</font>");
670  QRegExp rxDel("<font style=\"background-color:[^>]*" % Settings::delColor().name() % "[^>]*\">([^>]*)</font>");
671  //rxAdd.setMinimal(true);
672  //rxDel.setMinimal(true);
673 
674  //first things first
675  int pos=0;
676  while ((pos=rxDel.indexIn(diff,pos))!=-1)
677  diff.replace(pos,rxDel.matchedLength(),"\tKBABELDEL\t" % rxDel.cap(1) % "\t/KBABELDEL\t");
678  pos=0;
679  while ((pos=rxAdd.indexIn(diff,pos))!=-1)
680  diff.replace(pos,rxAdd.matchedLength(),"\tKBABELADD\t" % rxAdd.cap(1) % "\t/KBABELADD\t");
681 
682  diff.replace("&lt;","<");
683  diff.replace("&gt;",">");
684 
685  //possible enhancement: search for non-translated words in removedSubstrings...
686  //QStringList removedSubstrings;
687  //QStringList addedSubstrings;
688 
689 
690  /*
691  0 - common
692  + - add
693  - - del
694  M - modified
695 
696  so the string is like 00000MM00+++---000
697  */
698  DiffInfo d=getDiffInfo(diff);
699 
700  bool sameMarkup=Project::instance()->markup()==entry.markupExpr&&!entry.markupExpr.isEmpty();
701  bool tryMarkup=entry.target.tags.size() && sameMarkup;
702  //search for changed markup
703  if (tryMarkup)
704  {
705  QRegExp rxMarkup(entry.markupExpr);
706  rxMarkup.setMinimal(true);
707  pos=0;
708  int replacingPos=0;
709  while ((pos=rxMarkup.indexIn(d.old,pos))!=-1)
710  {
711  //kWarning()<<"size"<<oldM.size()<<pos<<pos+rxMarkup.matchedLength();
712  QByteArray diffIndexPart(d.diffIndex.mid(d.old2DiffClean.at(pos),
713  d.old2DiffClean.at(pos+rxMarkup.matchedLength()-1)+1-d.old2DiffClean.at(pos)));
714  //kWarning()<<"diffMPart"<<diffMPart;
715  if (diffIndexPart.contains('-')
716  ||diffIndexPart.contains('+'))
717  {
718  //form newMarkup
719  QString newMarkup;
720  newMarkup.reserve(diffIndexPart.size());
721  int j=-1;
722  while(++j<diffIndexPart.size())
723  {
724  if (diffIndexPart.at(j)!='-')
725  newMarkup.append(d.diffClean.at(d.old2DiffClean.at(pos)+j));
726  }
727 
728  //replace first ocurrence
729  int tmp=target.string.indexOf(rxMarkup.cap(0),replacingPos);
730  if (tmp!=-1)
731  {
732  target.replace(tmp,
733  rxMarkup.cap(0).size(),
734  newMarkup);
735  replacingPos=tmp;
736  //kWarning()<<"d.old"<<rxMarkup.cap(0)<<"new"<<newMarkup;
737 
738  //avoid trying this part again
739  tmp=d.old2DiffClean.at(pos+rxMarkup.matchedLength()-1);
740  while(--tmp>=d.old2DiffClean.at(pos))
741  d.diffIndex[tmp]='M';
742  //kWarning()<<"M"<<diffM;
743  }
744  }
745 
746  pos+=rxMarkup.matchedLength();
747  }
748  }
749 
750  //del, add only markup, punct, num
751  //TODO further improvement: spaces, punct marked as 0
752 //BEGIN BEGIN HANDLING
753  QRegExp rxNonTranslatable;
754  if (tryMarkup)
755  rxNonTranslatable.setPattern("^((" % entry.markupExpr % ")|(\\W|\\d)+)+");
756  else
757  rxNonTranslatable.setPattern("^(\\W|\\d)+");
758 
759  //kWarning()<<"("+entry.markup+"|(\\W|\\d)+";
760 
761 
762  //handle the beginning
763  int len=d.diffIndex.indexOf('0');
764  if (len>0)
765  {
766  QByteArray diffMPart(d.diffIndex.left(len));
767  int m=diffMPart.indexOf('M');
768  if (m!=-1)
769  diffMPart.truncate(m);
770 
771 #if 0
772 nono
773  //first goes del, then add. so stop on second del sequence
774  bool seenAdd=false;
775  int j=-1;
776  while(++j<diffMPart.size())
777  {
778  if (diffMPart.at(j)=='+')
779  seenAdd=true;
780  else if (seenAdd && diffMPart.at(j)=='-')
781  {
782  diffMPart.truncate(j);
783  break;
784  }
785  }
786 #endif
787  //form 'oldMarkup'
788  QString oldMarkup;
789  oldMarkup.reserve(diffMPart.size());
790  int j=-1;
791  while(++j<diffMPart.size())
792  {
793  if (diffMPart.at(j)!='+')
794  oldMarkup.append(d.diffClean.at(j));
795  }
796 
797  //kWarning()<<"old"<<oldMarkup;
798  rxNonTranslatable.indexIn(oldMarkup);
799  oldMarkup=rxNonTranslatable.cap(0);
800  if (target.string.startsWith(oldMarkup))
801  {
802 
803  //form 'newMarkup'
804  QString newMarkup;
805  newMarkup.reserve(diffMPart.size());
806  j=-1;
807  while(++j<diffMPart.size())
808  {
809  if (diffMPart.at(j)!='-')
810  newMarkup.append(d.diffClean.at(j));
811  }
812  //kWarning()<<"new"<<newMarkup;
813  rxNonTranslatable.indexIn(newMarkup);
814  newMarkup=rxNonTranslatable.cap(0);
815 
816  //replace
817  kWarning()<<"BEGIN HANDLING. replacing"<<target.string.left(oldMarkup.size())<<"with"<<newMarkup;
818  target.remove(0,oldMarkup.size());
819  target.insert(0,newMarkup);
820 
821  //avoid trying this part again
822  j=diffMPart.size();
823  while(--j>=0)
824  d.diffIndex[j]='M';
825  //kWarning()<<"M"<<diffM;
826  }
827 
828  }
829 //END BEGIN HANDLING
830 //BEGIN END HANDLING
831  if (tryMarkup)
832  rxNonTranslatable.setPattern("(("% entry.markupExpr %")|(\\W|\\d)+)+$");
833  else
834  rxNonTranslatable.setPattern("(\\W|\\d)+$");
835 
836  //handle the end
837  if (!d.diffIndex.endsWith('0'))
838  {
839  len=d.diffIndex.lastIndexOf('0')+1;
840  QByteArray diffMPart(d.diffIndex.mid(len));
841  int m=diffMPart.lastIndexOf('M');
842  if (m!=-1)
843  {
844  len=m+1;
845  diffMPart=diffMPart.mid(len);
846  }
847 
848  //form 'oldMarkup'
849  QString oldMarkup;
850  oldMarkup.reserve(diffMPart.size());
851  int j=-1;
852  while(++j<diffMPart.size())
853  {
854  if (diffMPart.at(j)!='+')
855  oldMarkup.append(d.diffClean.at(len+j));
856  }
857  //kWarning()<<"old-"<<oldMarkup;
858  rxNonTranslatable.indexIn(oldMarkup);
859  oldMarkup=rxNonTranslatable.cap(0);
860  if (target.string.endsWith(oldMarkup))
861  {
862 
863  //form newMarkup
864  QString newMarkup;
865  newMarkup.reserve(diffMPart.size());
866  j=-1;
867  while(++j<diffMPart.size())
868  {
869  if (diffMPart.at(j)!='-')
870  newMarkup.append(d.diffClean.at(len+j));
871  }
872  //kWarning()<<"new"<<newMarkup;
873  rxNonTranslatable.indexIn(newMarkup);
874  newMarkup=rxNonTranslatable.cap(0);
875 
876  //replace
877  target.string.chop(oldMarkup.size());
878  target.string.append(newMarkup);
879 
880  //avoid trying this part again
881  j=diffMPart.size();
882  while(--j>=0)
883  d.diffIndex[len+j]='M';
884  //kWarning()<<"M"<<diffM;
885  }
886  }
887 //END BEGIN HANDLING
888 
889  //search for numbers and stuff
890  //QRegExp rxNum("[\\d\\.\\%]+");
891  pos=0;
892  int replacingPos=0;
893  QString cap;
894  QString _;
895  //while ((pos=rxNum.indexIn(old,pos))!=-1)
896  kWarning()<<"string:"<<target.string<<"searching for placeables in"<<d.old;
897  while ((pos=nextPlacableIn(d.old,pos,cap))!=-1)
898  {
899  kWarning()<<"considering placable"<<cap;
900  //save these so we can use rxNum in a body
901  int endPos1=pos+cap.size()-1;
902  int endPos=d.old2DiffClean.at(endPos1);
903  int startPos=d.old2DiffClean.at(pos);
904  QByteArray diffMPart=d.diffIndex.mid(startPos,
905  endPos+1-startPos);
906 
907  kWarning()<<"starting diffMPart"<<diffMPart;
908 
909  //the following loop extends replacement text, e.g. for 1 -> 500 cases
910  while ((++endPos<d.diffIndex.size())
911  &&(d.diffIndex.at(endPos)=='+')
912  &&(-1!=nextPlacableIn(QString(d.diffClean.at(endPos)),0,_))
913  )
914  diffMPart.append('+');
915 
916  kWarning()<<"diffMPart extended 1"<<diffMPart;
917 // if ((pos-1>=0) && (d.old2DiffClean.at(pos)>=0))
918 // {
919 // kWarning()<<"d.diffIndex"<<d.diffIndex<<d.old2DiffClean.at(pos)-1;
920 // kWarning()<<"(d.diffIndex.at(d.old2DiffClean.at(pos-1))=='+')"<<(d.diffIndex.at(d.old2DiffClean.at(pos-1))=='+');
921 // //kWarning()<<(-1!=nextPlacableIn(QString(d.diffClean.at(d.old2DiffClean.at(pos))),0,_));
922 // }
923 
924  //this is for the case when +'s preceed -'s:
925  while ((--startPos>=0)
926  &&(d.diffIndex.at(startPos)=='+')
927  //&&(-1!=nextPlacableIn(QString(d.diffClean.at(d.old2DiffClean.at(pos))),0,_))
928  )
929  diffMPart.prepend('+');
930  ++startPos;
931 
932  kWarning()<<"diffMPart extended 2"<<diffMPart;
933 
934  if ((diffMPart.contains('-')
935  ||diffMPart.contains('+'))
936  &&(!diffMPart.contains('M')))
937  {
938  //form newMarkup
939  QString newMarkup;
940  newMarkup.reserve(diffMPart.size());
941  int j=-1;
942  while(++j<diffMPart.size())
943  {
944  if (diffMPart.at(j)!='-')
945  newMarkup.append(d.diffClean.at(startPos+j));
946  }
947  if (newMarkup.endsWith(' ')) newMarkup.chop(1);
948  //kWarning()<<"d.old"<<cap<<"new"<<newMarkup;
949 
950 
951  //replace first ocurrence
952  int tmp=target.string.indexOf(cap,replacingPos);
953  if (tmp!=-1)
954  {
955  kWarning()<<"replacing"<<cap<<"with"<<newMarkup;
956  target.replace(tmp, cap.size(), newMarkup);
957  replacingPos=tmp;
958 
959  //avoid trying this part again
960  tmp=d.old2DiffClean.at(endPos1)+1;
961  while(--tmp>=d.old2DiffClean.at(pos))
962  d.diffIndex[tmp]='M';
963  //kWarning()<<"M"<<diffM;
964  }
965  else
966  kWarning()<<"newMarkup"<<newMarkup<<"wasn't used";
967  }
968  pos=endPos1+1;
969  }
970  adaptCatalogString(target, ref);
971  return target;
972 }
973 
974 void TMView::slotUseSuggestion(int i)
975 {
976  if (KDE_ISUNLIKELY( i>=m_entries.size() ))
977  return;
978 
979  CatalogString target=targetAdapted(m_entries.at(i), m_catalog->sourceWithTags(m_pos));
980 
981 #if 0
982  QString tmp=target.string;
983  tmp.replace(TAGRANGE_IMAGE_SYMBOL, '*');
984  kWarning()<<"targetAdapted"<<tmp;
985 
986  foreach (InlineTag tag, target.tags)
987  kWarning()<<"tag"<<tag.start<<tag.end;
988 #endif
989  if (KDE_ISUNLIKELY( target.isEmpty() ))
990  return;
991 
992  m_catalog->beginMacro(i18nc("@item Undo action","Use translation memory suggestion"));
993 
994  QString old=m_catalog->targetWithTags(m_pos).string;
995  if (!old.isEmpty())
996  {
997  m_pos.offset=0;
998  //FIXME test!
999  removeTargetSubstring(m_catalog, m_pos, 0, old.size());
1000  //m_catalog->push(new DelTextCmd(m_catalog,m_pos,m_catalog->msgstr(m_pos)));
1001  }
1002  kWarning()<<"1"<<target.string;
1003 
1004  //m_catalog->push(new InsTextCmd(m_catalog,m_pos,target)/*,true*/);
1005  insertCatalogString(m_catalog, m_pos, target, 0);
1006 
1007  if (m_entries.at(i).score>9900 && !m_catalog->isApproved(m_pos.entry))
1008  SetStateCmd::push(m_catalog,m_pos,true);
1009 
1010  m_catalog->endMacro();
1011 
1012  emit refreshRequested();
1013 }
1014 
1015 
1016 #include "tmview.moc"
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
QSortFilterProxyModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
QTextCursor::position
int position() const
TM::DBFilesModel
Definition: dbfilesmodel.h:39
QList::clear
void clear()
QModelIndex
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QEvent
TM::scanRecursive
int scanRecursive(const QList< QUrl > &urls, const QString &dbName)
wrapper. returns gross number of jobs started
Definition: tmscanapi.cpp:92
project.h
QWidget
Catalog::url
const KUrl & url() const
Definition: catalog.h:189
QRegExp::cap
QString cap(int nth) const
TM::TMEntry::file
QString file
Definition: tmentry.h:41
Catalog::targetWithTags
CatalogString targetWithTags(const DocPosition &pos) const
Definition: catalog.cpp:211
QString::append
QString & append(QChar ch)
QEvent::type
Type type() const
dragIsAcceptable
bool dragIsAcceptable(const QList< QUrl > &urls)
Definition: tmscanapi.cpp:151
TM::TMEntry::dbName
QString dbName
Definition: tmentry.h:51
TM::TMView::dropEvent
void dropEvent(QDropEvent *)
Definition: tmview.cpp:206
QTextCursor
QDropEvent::mimeData
const QMimeData * mimeData() const
TM::TMEntry::markupExpr
QString markupExpr
Definition: tmentry.h:57
Catalog::targetLangCode
QString targetLangCode() const
Definition: catalog.cpp:474
TM::TMEntry::score
short score
Definition: tmentry.h:48
QDate::toString
QString toString(Qt::DateFormat format) const
nextPlacableIn
static int nextPlacableIn(const QString &old, int start, QString &cap)
helper function: searches to th nearest rxNum or ABBR clears rxNum if ABBR is found before rxNum ...
Definition: tmview.cpp:612
SetStateCmd::push
static void push(Catalog *catalog, const DocPosition &pos, bool approved)
Definition: cmd.cpp:182
QTextCursor::insertHtml
void insertHtml(const QString &html)
QByteArray
QByteArray::at
char at(int i) const
QDockWidget
TAGRANGE_IMAGE_SYMBOL
#define TAGRANGE_IMAGE_SYMBOL
Definition: catalogstring.h:33
QRegExp::setMinimal
void setMinimal(bool minimal)
QUndoStack::beginMacro
void beginMacro(const QString &text)
QByteArray::lastIndexOf
int lastIndexOf(char ch, int from) const
QChar
QAction::data
QVariant data() const
switchNext
bool switchNext(Catalog *&catalog, DocPosition &pos, int parts)
Definition: pos.cpp:88
QTextBlockFormat
TM::DBFilesModel::m_configurations
QMap< QString, TMConfig > m_configurations
Definition: dbfilesmodel.h:102
QList::at
const T & at(int i) const
QMap
Project::instance
static Project * instance()
Definition: project.cpp:67
TM::TextBrowser::mouseDoubleClickEvent
void mouseDoubleClickEvent(QMouseEvent *event)
Definition: tmview.cpp:136
QString::size
int size() const
QMenu::addAction
void addAction(QAction *action)
TM::DBFilesModel::data
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition: dbfilesmodel.cpp:203
TM::SelectJob::m_entries
QList< TMEntry > m_entries
Definition: jobs.h:163
TM::TMView::slotNewEntryDisplayed
void slotNewEntryDisplayed(const DocPosition &pos=DocPosition())
Definition: tmview.cpp:356
TM::SelectJob
Definition: jobs.h:130
QPoint
QVector::first
T & first()
ProjectBase::markup
QString markup() const
Get Markup.
Definition: projectbase.h:252
CatalogString::string
QString string
Definition: catalogstring.h:130
cmd.h
QMouseEvent
insertContent
void insertContent(QTextCursor &cursor, const CatalogString &catStr, const CatalogString &refStr, bool insertText)
Definition: xlifftextedit.cpp:344
QFile::exists
bool exists() const
QString::remove
QString & remove(int position, int n)
dbfilesmodel.h
Settings::delColor
static QColor delColor()
Get DelColor.
Definition: prefs_lokalize.h:133
QMap::clear
void clear()
QString::chop
void chop(int n)
CatalogString::insert
void insert(int position, const QString &str)
Definition: catalogstring.cpp:240
TM::TMView::slotFileLoaded
void slotFileLoaded(const KUrl &)
Definition: tmview.cpp:212
QToolTip::showText
void showText(const QPoint &pos, const QString &text, QWidget *w)
QTime
QTextCursor::anchor
int anchor() const
Catalog::isEmpty
bool isEmpty(uint index) const
Definition: catalog.cpp:432
QSortFilterProxyModel::rowCount
virtual int rowCount(const QModelIndex &parent) const
QTextCursor::movePosition
bool movePosition(MoveOperation operation, MoveMode mode, int n)
QList::size
int size() const
TM::targetAdapted
CatalogString targetAdapted(const TMEntry &entry, const CatalogString &ref)
this tries some black magic naturally, there are many assumptions that might not always be true ...
Definition: tmview.cpp:660
DocPosition::offset
uint offset
Definition: pos.h:51
DocPosition::entry
int entry
Definition: pos.h:48
QString::clear
void clear()
TM::TMView::~TMView
~TMView()
Definition: tmview.cpp:169
QRegExp::setPattern
void setPattern(const QString &pattern)
TM::ScanJob
Definition: jobs.h:229
getDiffInfo
static DiffInfo getDiffInfo(const QString &diff)
0 - common
Definition: tmview.cpp:92
QRegExp::matchedLength
int matchedLength() const
DocPosition
This struct represents a position in a catalog.
Definition: pos.h:38
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
TM::TMView::textInsertRequested
void textInsertRequested(const QString &)
TM::TMView::slotSuggestionsCame
void slotSuggestionsCame(ThreadWeaver::Job *)
Definition: tmview.cpp:391
QRegExp
TM::TMEntry
Definition: tmentry.h:35
CatalogString::isEmpty
bool isEmpty() const
Definition: catalogstring.h:144
QObject::name
const char * name() const
QByteArray::indexOf
int indexOf(char ch, int from) const
QSignalMapper::setMapping
void setMapping(QObject *sender, int id)
QTextCursor::insertBlock
void insertBlock()
Project
Singleton object that represents project.
Definition: project.h:51
QList::append
void append(const T &value)
TM::TMEntry::changeDate
QDate changeDate
Definition: tmentry.h:43
removeTargetSubstring
bool removeTargetSubstring(Catalog *catalog, DocPosition pos, int delStart, int delLen)
Definition: cmd.cpp:364
QVariant::toInt
int toInt(bool *ok) const
QDate::isNull
bool isNull() const
Settings::addColor
static QColor addColor()
Get AddColor.
Definition: prefs_lokalize.h:115
QWidget::setUpdatesEnabled
void setUpdatesEnabled(bool enable)
QHelpEvent::globalPos
const QPoint & globalPos() const
catalog.h
QByteArray::prepend
QByteArray & prepend(char ch)
QDropEvent
QList::isEmpty
bool isEmpty() const
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
TM::TMView::TMView
TMView(QWidget *, Catalog *, const QVector< KAction * > &)
Definition: tmview.cpp:146
QList::removeAll
int removeAll(const T &value)
InlineTag::start
int start
Definition: catalogstring.h:68
DocPosition::form
char form
Definition: pos.h:50
QTextFormat::setBackground
void setBackground(const QBrush &brush)
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
TM::SelectJob::m_source
CatalogString m_source
Definition: jobs.h:155
QWidget::pos
QPoint pos() const
TM::TMView::slotUseSuggestion
void slotUseSuggestion(int)
Definition: tmview.cpp:974
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
TM::TMEntry::source
CatalogString source
Definition: tmentry.h:37
QObject::deleteLater
void deleteLater()
QString
QMap::end
iterator end()
TM::initSelectJob
SelectJob * initSelectJob(Catalog *, DocPosition pos, QString db=QString(), int opt=Enqueue)
Definition: jobs.cpp:1084
diff.h
QMenu::exec
QAction * exec()
adaptCatalogString
void adaptCatalogString(CatalogString &target, const CatalogString &ref)
prepares
Definition: catalogstring.cpp:271
QMap::lowerBound
iterator lowerBound(const Key &key)
Settings::suggCount
static int suggCount()
Get SuggCount.
Definition: prefs_lokalize.h:313
TM::TextBrowser
Definition: tmview.h:113
QWidget::setAcceptDrops
void setAcceptDrops(bool on)
QByteArray::append
QByteArray & append(char ch)
QTextCharFormat
QList::end
iterator end()
QVector::reserve
void reserve(int size)
QMenu
TM::RemoveJob
Definition: jobs.h:173
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
TM::TMView::displayFromCache
void displayFromCache()
Definition: tmview.cpp:379
TM::TMEntry::date
QDate date
Definition: tmentry.h:42
TM::TMEntry::target
CatalogString target
Definition: tmentry.h:38
Settings::scanToTMOnOpen
static bool scanToTMOnOpen()
Get ScanToTMOnOpen.
Definition: prefs_lokalize.h:349
TM::TMEntry::diff
QString diff
Definition: tmentry.h:53
QDockWidget::setWidget
void setWidget(QWidget *widget)
QTextCharFormat::setFontWeight
void setFontWeight(int weight)
QString::replace
QString & replace(int position, int n, QChar after)
QString::unicode
const QChar * unicode() const
CatalogString
data structure used to pass info about inline elements a XLIFF tag is represented by a TAGRANGE_IMAGE...
Definition: catalogstring.h:128
xlifftextedit.h
QVector::at
const T & at(int i) const
insertCatalogString
void insertCatalogString(Catalog *catalog, DocPosition pos, const CatalogString &catStr, int start)
Definition: cmd.cpp:421
jobs.h
QList::takeLast
T takeLast()
TM::TMEntry::changeAuthor
QString changeAuthor
Definition: tmentry.h:44
QVector< int >
QDragEnterEvent
prefs_lokalize.h
TM::TMView::fileOpenRequested
void fileOpenRequested(const KUrl &path, const QString &str, const QString &ctxt)
TM::TMView::refreshRequested
void refreshRequested()
ProjectBase::projectID
QString projectID() const
Get ProjectID.
Definition: projectbase.h:31
TM::DBFilesModel::rootIndex
QModelIndex rootIndex() const
Definition: dbfilesmodel.cpp:95
QMimeData::urls
QList< QUrl > urls() const
QUndoStack::endMacro
void endMacro()
Qt::escape
QString escape(const QString &plain)
QVector::isEmpty
bool isEmpty() const
Catalog::sourceWithTags
CatalogString sourceWithTags(const DocPosition &pos) const
Definition: catalog.cpp:203
CatalogString::tags
QList< InlineTag > tags
Definition: catalogstring.h:131
tmscanapi.h
TM::SelectJob::m_dbName
QString m_dbName
Definition: jobs.h:165
QString::at
const QChar at(int position) const
QWidget::setWindowTitle
void setWindowTitle(const QString &)
QAction
Catalog::isApproved
bool isApproved(uint index) const
Definition: catalog.cpp:410
Catalog::numberOfEntries
int numberOfEntries() const
Definition: catalog.cpp:171
DocPos
simpler version of DocPosition for use in QMap
Definition: pos.h:82
QByteArray::contains
bool contains(char ch) const
TM::TMView::slotBatchTranslateFuzzy
void slotBatchTranslateFuzzy()
Definition: tmview.cpp:341
QString::reserve
void reserve(int size)
QString::left
QString left(int n) const
QTime::start
void start()
Catalog
This class represents a catalog It uses CatalogStorage interface to work with catalogs in different f...
Definition: catalog.h:74
CatalogString::replace
void replace(int position, int len, const QString &str)
Definition: catalogstring.h:142
QTextCursor::setCharFormat
void setCharFormat(const QTextCharFormat &format)
QMap::insert
iterator insert(const Key &key, const T &value)
CatalogString::remove
void remove(int position, int len)
Definition: catalogstring.cpp:234
QWidget::setToolTip
void setToolTip(const QString &)
TM::TextBrowser::textInsertRequested
void textInsertRequested(const QString &)
TM::TMEntry::obsolete
bool obsolete
Definition: tmentry.h:50
QByteArray::size
int size() const
InlineTag::end
int end
Definition: catalogstring.h:69
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVector::size
int size() const
QHelpEvent
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QWidget::event
virtual bool event(QEvent *event)
TM::TMEntry::ctxt
QString ctxt
Definition: tmentry.h:40
QSignalMapper
TM::BatchSelectFinishedJob
Definition: jobs.h:257
InlineTag
data structure used to pass info about inline elements a XLIFF tag is represented by a TAGRANGE_IMAGE...
Definition: catalogstring.h:44
QPalette
TM::TMView::slotBatchTranslate
void slotBatchTranslate()
Definition: tmview.cpp:326
tmview.h
Settings::prefetchTM
static bool prefetchTM()
Get PrefetchTM.
Definition: prefs_lokalize.h:295
TM::SelectJob::m_pos
DocPosition m_pos
Definition: jobs.h:162
TM::DBFilesModel::instance
static DBFilesModel * instance()
Definition: dbfilesmodel.cpp:46
TM::TMView::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *event)
Definition: tmview.cpp:200
QTimer::singleShot
singleShot
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:40:07 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

lokalize

Skip menu "lokalize"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal