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

lokalize

kaiderview.cpp

Go to the documentation of this file.
00001 /* ****************************************************************************
00002   This file is part of Lokalize (some bits of KBabel code were reused)
00003 
00004   Copyright (C) 2007-2008 by Nick Shaforostoff <shafff@ukr.net>
00005   Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
00006                 2001-2004 by Stanislav Visnovsky <visnovsky@kde.org>
00007 
00008   This program is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 2 of the License, or
00011   (at your option) any later version.
00012 
00013   This program is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017 
00018   You should have received a copy of the GNU General Public License
00019   along with this program; if not, write to the Free Software
00020   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021 
00022   In addition, as a special exception, the copyright holders give
00023   permission to link the code of this program with any edition of
00024   the Qt library by Trolltech AS, Norway (or with modified versions
00025   of Qt that use the same license as Qt), and distribute linked
00026   combinations including the two.  You must obey the GNU General
00027   Public License in all respects for all of the code used other than
00028   Qt. If you modify this file, you may extend this exception to
00029   your version of the file, but you are not obligated to do so.  If
00030   you do not wish to do so, delete this exception statement from
00031   your version.
00032 
00033 **************************************************************************** */
00034 
00035 #include "kaiderview.h"
00036 #include "project.h"
00037 #include "catalog.h"
00038 #include "cmd.h"
00039 #include "prefs_lokalize.h"
00040 #include "syntaxhighlighter.h"
00041 
00042 #include <QTimer>
00043 #include <QMenu>
00044 #include <QDragEnterEvent>
00045 
00046 #include <QLabel>
00047 #include <QHBoxLayout>
00048 
00049 
00050 #ifdef XLIFF
00051 #include <QPixmap>
00052 #endif
00053 
00054 #include <ktabbar.h>
00055 #include <kled.h>
00056 #include <kmessagebox.h>
00057 #include <klocale.h>
00058 #include <kdebug.h>
00059 #include <kurl.h>
00060 #include <kstandardshortcut.h>
00061 #include <kcolorscheme.h>
00062 
00063 
00064 //parent is set on qsplitter insertion
00065 class LedsWidget:public QWidget
00066 {
00067 public:
00068     LedsWidget(QWidget* parent)
00069     : QWidget(parent)
00070 //     , _ledFuzzy(0)
00071 //     , _ledUntr(0)
00072 //     , _ledErr(0)
00073     {
00074         KColorScheme colorScheme(QPalette::Normal);
00075 
00076         QHBoxLayout* layout=new QHBoxLayout(this);
00077         layout->addStretch();
00078         layout->addWidget(new QLabel(i18nc("@label whether entry is fuzzy","Fuzzy:"),this));
00079         layout->addWidget(ledFuzzy=new KLed(colorScheme.foreground(KColorScheme::NeutralText)/*Qt::green*/,KLed::Off,KLed::Sunken,KLed::Rectangular));
00080         layout->addWidget(new QLabel(i18nc("@label whether entry is untranslated","Untranslated:"),this));
00081         layout->addWidget(ledUntr=new KLed(colorScheme.foreground(KColorScheme::NegativeText)/*Qt::red*/,KLed::Off,KLed::Sunken,KLed::Rectangular));
00082         layout->addSpacing(1);
00083         layout->addWidget(lblColumn=new QLabel(this));
00084         layout->addStretch();
00085         setMaximumHeight(minimumSizeHint().height());
00086     }
00087 
00088 //NOTE the config shit doesn't work
00089 private:
00090     void contextMenuEvent(QContextMenuEvent* event)
00091     {
00092         QMenu menu;
00093         menu.addAction(i18nc("@action","Hide"));
00094         if (menu.exec(event->globalPos()))
00095         {
00096             Settings::setLeds(false);
00097             Settings::self()->writeConfig();
00098             hide();
00099         }
00100     }
00101 
00102 public:
00103     KLed* ledFuzzy;
00104     KLed* ledUntr;
00105     //KLed* ledErr;
00106     QLabel* lblColumn;
00107 
00108 };
00109 
00110 void ProperTextEdit::keyPressEvent(QKeyEvent *keyEvent)
00111 {
00112     // ALT+123 feature TODO this is general so should be on another level
00113     if( (keyEvent->modifiers()&Qt::AltModifier)
00114          &&!keyEvent->text().isEmpty()
00115          &&keyEvent->text().at(0).isDigit() )
00116     {
00117         QString text=keyEvent->text();
00118         while (!text.isEmpty()&& text.at(0).isDigit() )
00119         {
00120             m_currentUnicodeNumber = 10*m_currentUnicodeNumber+(text.at(0).digitValue());
00121             text.remove(0,1);
00122         }
00123     }
00124     else
00125         KTextEdit::keyPressEvent(keyEvent);
00126 }
00127 
00128 void ProperTextEdit::keyReleaseEvent(QKeyEvent* e)
00129 {
00130     if ( (e->key()==Qt::Key_Alt) && m_currentUnicodeNumber >= 32 )
00131     {
00132         insertPlainText(QChar( m_currentUnicodeNumber ));
00133         m_currentUnicodeNumber=0;
00134     }
00135     else
00136         KTextEdit::keyReleaseEvent(e);
00137 }
00138 
00139 QString ProperTextEdit::toPlainText()
00140 {
00141     QTextCursor cursor = textCursor();
00142     cursor.select(QTextCursor::Document);
00143     QString text=cursor.selectedText();
00144     text.replace(QChar(8233),'\n');
00145 /*
00146     int ii=text.size();
00147     while(--ii>=0)
00148         kWarning()<<text.at(ii).unicode();
00149 */
00150     return text;
00151 }
00152 
00153 
00154 #ifdef XLIFF
00155 //BEGIN XLIFF
00156 
00157 
00158 inline static QImage generateImage(QString str, ProperTextEdit* w)
00159 {
00160     str.prepend(' ');
00161     QFontMetrics metrics(w->currentFont());
00162     QRect rect=metrics.boundingRect(str);
00163     rect.moveTo(0,0);
00164 
00165     QLabel test(str,w);
00166     test.setGeometry(rect);
00167 
00168     QPixmap pixmap=QPixmap::grabWidget(&test,rect);
00169     return pixmap.toImage();
00170 
00171 }
00172 
00173 void ProperTextEdit::setContent(const CatalogString& catStr)
00174 {
00175     //kWarning()<<str<<ranges.size();
00176     //prevent undo tracking system from recording this 'action'
00177     document()->blockSignals(true);
00178     clear();
00179     QTextCursor cur=textCursor();
00180 
00181 
00182     static const char* inlineElementNames[(int)InlineElementCount]={
00183     "_unknown",
00184     "bpt",
00185     "ept",
00186     "ph",
00187     "it",
00188 //    "_NEVERSHOULDBECHOSEN",
00189     "mrk",
00190     "g",
00191     "sub",
00192     "_NEVERSHOULDBECHOSEN",
00193     "x",
00194     "bx",
00195     "ex",
00196     };
00197 
00198     QMap<int,int> posToTagRange;
00199     int i=catStr.ranges.size();
00200     while(--i>=0)
00201     {
00202         posToTagRange.insert(catStr.ranges.at(i).start,i);
00203         posToTagRange.insert(catStr.ranges.at(i).end,i);
00204     }
00205 
00206 
00207 
00208     i=0;
00209     int prev=0;
00210     while ((i = catStr.string.indexOf(TAGRANGE_IMAGE_SYMBOL, i)) != -1)
00211     {
00212         kWarning()<<"HAPPENED!!";
00213         int tagRangeIndex=posToTagRange.value(i);
00214         cur.insertText(catStr.string.mid(prev,i-prev));
00215 
00216         TagRange ourRange=catStr.ranges.at(tagRangeIndex);
00217         QString name=' '+ourRange.id;
00218         QString text=QString::number(tagRangeIndex);
00219         if (ourRange.start!=ourRange.end)
00220         {
00221 //             kWarning()<<"a"<<ranges.at(tagRangeIndex).start;
00222 //             kWarning()<<"b"<<i;
00223             if (ourRange.start==i)
00224             {
00225                 text.append(" {");
00226                 name.append("-start");
00227             }
00228             else
00229             {
00230                 text.prepend("} ");
00231                 name.append("-end");
00232             }
00233         }
00234         document()->addResource(QTextDocument::ImageResource, QUrl(name), generateImage(text,this));
00235         cur.insertImage(name);//NOTE what if twice the same name?
00236 
00237         prev=++i;
00238     }
00239     cur.insertText(catStr.string.mid(prev));
00240 
00241     document()->blockSignals(false);
00242 }
00243 
00244 //END XLIFF
00245 #endif
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 KAiderView::KAiderView(QWidget *parent,Catalog* catalog/*,keyEventHandler* kh*/)
00267     : QSplitter(Qt::Vertical,parent)
00268     , _catalog(catalog)
00269     , _msgidEdit(new ProperTextEdit(this))
00270     , _msgstrEdit(new ProperTextEdit(this))
00271     , m_msgidHighlighter(new SyntaxHighlighter(_msgidEdit->document()))
00272     , m_msgstrHighlighter(new SyntaxHighlighter(_msgstrEdit->document()))
00273     , m_pluralTabBar(new KTabBar(this))
00274     , _leds(0)
00275     , _currentEntry(-1)
00276     , m_approvementState(true)
00277     , m_modifiedAfterFind(false)
00278 {
00279     //( new QTreeView(this) )->selectAll();
00280     m_pluralTabBar->hide();
00281 //     _msgidEdit->setWhatsThis(i18n("<qt><p><b>Original String</b></p>\n"
00282 //                                   "<p>This part of the window shows the original message\n"
00283 //                                   "of the currently displayed entry.</p></qt>"));
00284 
00285     _msgidEdit->setReadOnly(true);
00286 
00287     //apply changes to catalog via undo/redo
00288     connect (_msgstrEdit->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
00289     connect (_msgstrEdit, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));
00290 
00291 
00292     _msgidEdit->setUndoRedoEnabled(false);
00293     _msgstrEdit->setUndoRedoEnabled(false);
00294     _msgstrEdit->setAcceptRichText(false);
00295     _msgstrEdit->installEventFilter(this);
00296     _msgidEdit->installEventFilter(this);
00297 
00298     addWidget(m_pluralTabBar);
00299     addWidget(_msgidEdit);
00300     addWidget(_msgstrEdit);
00301 
00302     QWidget::setTabOrder(_msgstrEdit,_msgidEdit);
00303     QWidget::setTabOrder(_msgidEdit,_msgstrEdit);
00304     setFocusProxy(_msgstrEdit);
00305 //     QTimer::singleShot(3000,this,SLOT(setupWhatsThis()));
00306     settingsChanged();
00307 }
00308 
00309 KAiderView::~KAiderView()
00310 {
00311     /*
00312     delete _msgidEdit;
00313     delete _msgstrEdit;
00314     delete m_pluralTabBar;
00315     */
00316 }
00317 
00318 // void KAiderView::setupWhatsThis()
00319 // {
00320 //     _msgidEdit->setWhatsThis(i18n("<qt><p><b>Original String</b></p>\n"
00321 //                                   "<p>This part of the window shows the original message\n"
00322 //                                   "of the currently displayed entry.</p></qt>"));
00323 // }
00324 
00325 static bool isMasked(const QString& str, uint col)
00326 {
00327     if(col == 0 || str.isEmpty())
00328         return false;
00329 
00330     uint counter=0;
00331     int pos=col;
00332 
00333     while(pos >= 0 && str.at(pos) == '\\')
00334     {
00335         counter++;
00336         pos--;
00337     }
00338 
00339     return !(bool)(counter%2);
00340 }
00341 
00342 
00343 bool KAiderView::eventFilter(QObject* obj, QEvent* event)
00344 {
00345     if (event->type() != QEvent::KeyPress)
00346         return false;//QObject::eventFilter(obj, event);
00347     QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
00348 
00349 
00350 
00351     if(keyEvent->matches(QKeySequence::MoveToPreviousPage))
00352     {
00353         emit signalGotoPrev();
00354         return true;
00355     }
00356     else if(keyEvent->matches(QKeySequence::MoveToNextPage))
00357     {
00358         emit signalGotoNext();
00359         return true;
00360     }
00361     if (obj!=_msgstrEdit)
00362         return false;
00363 
00364 
00365     static QString spclChars("abfnrtv'\"?\\");
00366     if(keyEvent->matches(QKeySequence::Undo))
00367     {
00368         if (_catalog->canUndo())
00369         {
00370             emit signalUndo();
00371             approvedEntryDisplayed(_catalog->isApproved(_currentEntry));
00372             return true;
00373         }
00374     }
00375     else if(keyEvent->matches(QKeySequence::Redo))
00376     {
00377         if (_catalog->canRedo())
00378         {
00379             emit signalRedo();
00380             approvedEntryDisplayed(_catalog->isApproved(_currentEntry));
00381             return true;
00382         }
00383     }
00384     else if (keyEvent->modifiers() == (Qt::AltModifier|Qt::ControlModifier))
00385     {
00386         if(keyEvent->key()==Qt::Key_Home)
00387         {
00388             emit signalGotoFirst();
00389             return true;
00390         }
00391         else if(keyEvent->key()==Qt::Key_End)
00392         {
00393             emit signalGotoLast();
00394             return true;
00395         }
00396     }
00397     else if (!keyEvent->modifiers()&&(keyEvent->key()==Qt::Key_Backspace||keyEvent->key()==Qt::Key_Delete))
00398     {
00399         //only for cases when:
00400         //-BkSpace was hit and cursor was atStart
00401         //-Del was hit and cursor was atEnd
00402         if (KDE_ISUNLIKELY( !_catalog->isApproved(_currentEntry) && !_msgstrEdit->textCursor().hasSelection() ))
00403                           //&& (_msgstrEdit->textCursor().atStart()||_msgstrEdit->textCursor().atEnd()) ))
00404             toggleApprovement(true);
00405         return false;
00406     }
00407     //clever editing
00408     else if(keyEvent->key()==Qt::Key_Return||keyEvent->key()==Qt::Key_Enter)
00409     {
00410         QString str=_msgstrEdit->toPlainText();
00411         QTextCursor t=_msgstrEdit->textCursor();
00412         int pos=t.position();
00413         QString ins;
00414         if( keyEvent->modifiers()&Qt::ShiftModifier )
00415         {
00416             if(pos>0
00417                &&!str.isEmpty()
00418                &&str.at(pos-1)=='\\'
00419                &&!isMasked(str,pos-1))
00420             {
00421                 ins='n';
00422             }
00423             else
00424             {
00425                 ins="\\n";
00426             }
00427         }
00428         else if(!(keyEvent->modifiers()&Qt::ControlModifier))
00429         {
00430             if(pos>0
00431                &&!str.isEmpty()
00432                &&!str.at(pos-1).isSpace())
00433             {
00434                 if(str.at(pos-1)=='\\'
00435                    &&!isMasked(str,pos-1))
00436                     ins='\\';
00437                 // if there is no new line at the end
00438                 if(pos<2||str.midRef(pos-2,2)!="\\n")
00439                     ins+=' ';
00440             }
00441             else if(str.isEmpty())
00442             {
00443                 ins="\\n";
00444             }
00445         }
00446         if (!str.isEmpty())
00447             ins+='\n';
00448         _msgstrEdit->insertPlainText(ins);
00449 
00450         return true;
00451     }
00452     else if(keyEvent->key() == Qt::Key_Tab)
00453     {
00454         _msgstrEdit->insertPlainText("\\t");
00455         return true;
00456     }
00457     else if( (keyEvent->modifiers()&Qt::ControlModifier)?
00458                 (keyEvent->key()==Qt::Key_D) :
00459                 (keyEvent->key()==Qt::Key_Delete))
00460     {
00461         QTextCursor t=_msgstrEdit->textCursor();
00462         if(!t.hasSelection())
00463         {
00464             int pos=t.position();
00465             QString str=_msgstrEdit->toPlainText();
00466             if(!str.isEmpty()
00467                 &&str.at(pos) == '\\'
00468                 &&!isMasked(str,pos))
00469             {
00470                 if(pos<str.length()-1&&spclChars.contains(str.at(pos+1)))
00471                     t.deleteChar();
00472             }
00473         }
00474 
00475         t.deleteChar();
00476         _msgstrEdit->setTextCursor(t);
00477 
00478         return true;
00479     }
00480     else if( (!keyEvent->modifiers()&&keyEvent->key()==Qt::Key_Backspace)
00481             || ( ( keyEvent->modifiers() & Qt::ControlModifier ) && keyEvent->key() == Qt::Key_H ) )
00482     {
00483         QTextCursor t=_msgstrEdit->textCursor();
00484         if(!t.hasSelection())
00485         {
00486             int pos=t.position();
00487             QString str=_msgstrEdit->toPlainText();
00488             if(!str.isEmpty() && pos>0 && spclChars.contains(str.at(pos-1)))
00489             {
00490                 if(pos>1 && str.at(pos-2)=='\\' && !isMasked(str,pos-2))
00491                     t.deletePreviousChar();
00492             }
00493 
00494         }
00495         t.deletePreviousChar();
00496         _msgstrEdit->setTextCursor(t);
00497 
00498         return true;
00499     }
00500     else if(keyEvent->text()=="\"")
00501     {
00502         QTextCursor t=_msgstrEdit->textCursor();
00503         int pos=t.position();
00504         QString str=_msgstrEdit->toPlainText();
00505         QString ins;
00506 
00507         if(pos==0 || str.at(pos-1)!='\\' || isMasked(str,pos-1))
00508             ins="\\\"";
00509         else
00510             ins="\"";
00511 
00512         t.insertText(ins);
00513         _msgstrEdit->setTextCursor(t);
00514         return true;
00515     }
00516     else if( keyEvent->key() == Qt::Key_Space && ( keyEvent->modifiers() & Qt::AltModifier ) )
00517     {
00518         _msgstrEdit->insertPlainText(QChar(0x00a0U));
00519         return true;
00520     }
00521 
00522     return false;
00523 }
00524 
00525 
00526 
00527 
00528 void KAiderView::settingsChanged()
00529 {
00530     //Settings::self()->config()->setGroup("Editor");
00531     _msgidEdit->document()->setDefaultFont(Settings::msgFont());
00532     _msgstrEdit->document()->setDefaultFont(Settings::msgFont());
00533     if (Settings::leds())
00534     {
00535         if (_leds)
00536             _leds->show();
00537         else
00538         {
00539             _leds=new LedsWidget(this);
00540             if (!_catalog->isApproved(_currentEntry))
00541                 _leds->ledFuzzy->on();
00542             if (_catalog->msgstr(_currentPos).isEmpty())
00543                 _leds->ledUntr->on();
00544             cursorPositionChanged();
00545             insertWidget(2,_leds);
00546         }
00547     }
00548     else if (_leds)
00549         _leds->hide();
00550 
00551 }
00552 
00553 void KAiderView::cursorPositionChanged()
00554 {
00555     if (_leds)
00556         _leds->lblColumn->setText(i18nc("@info:label cursor position", "Column: %1", _msgstrEdit->textCursor().columnNumber()));
00557 }
00558 
00559 void KAiderView::contentsChanged(int offset, int charsRemoved, int charsAdded)
00560 {
00561     QString editText=_msgstrEdit->toPlainText();
00562     if (KDE_ISUNLIKELY( _currentEntry==-1 || editText==_oldMsgstr ))
00563         return;
00564 
00565     DocPosition pos=_currentPos;
00566     pos.offset=offset;
00567     //kWarning()<<"offset"<<offset<<"charsRemoved"<<charsRemoved<<"_oldMsgstr"<<_oldMsgstr;
00568 
00569 #ifdef XLIFF
00570     QString target=_catalog->targetWithTags(pos).string;
00571 
00572     //protect from tag removal
00573     if ((charsRemoved && target.mid(offset,charsRemoved).contains(TAGRANGE_IMAGE_SYMBOL))
00574        ||(charsAdded && editText.mid(offset,charsAdded).contains(TAGRANGE_IMAGE_SYMBOL)))
00575     {
00576         //refresh
00577         refreshMsgEdit(/*keepCursor*/true);
00578         return;
00579     }
00580 #endif
00581 
00582     m_modifiedAfterFind=true;
00583 
00584 
00585     if (charsRemoved)
00586         _catalog->push(new DelTextCmd(_catalog,pos,_oldMsgstr.mid(offset,charsRemoved)));
00587 
00588     _oldMsgstr=editText;//newStr becomes OldStr
00589     //kWarning()<<"char"<<editText[offset].unicode();
00590     if (charsAdded)
00591         _catalog->push(new InsTextCmd(_catalog,pos,editText.mid(offset,charsAdded)));
00592 
00593     if (_leds)
00594     {
00595         if (_catalog->msgstr(pos).isEmpty())
00596             _leds->ledUntr->on();
00597         else
00598             _leds->ledUntr->off();
00599     }
00600 
00601     if (!_catalog->isApproved(_currentEntry))
00602         toggleApprovement(true);
00603 
00604     // for mergecatalog (remove entry from index)
00605     // and for statusbar
00606     emit signalChanged(pos.entry);
00607 }
00608 
00609 void KAiderView::approvedEntryDisplayed(bool approved, bool force)
00610 {
00611     //kWarning()<<"approvedEntryDisplayed. entry:"<<_currentEntry<<"approved:"<<approved<<"force:"<<force;
00612     if (KDE_ISUNLIKELY( _currentEntry==-1 || (m_approvementState==approved && !force) ))
00613     {
00614         //kWarning()<<"approvedEntryDisplayed returning";
00615         return;
00616     }
00617     m_approvementState=approved;
00618 
00619     _msgstrEdit->setFontItalic(!approved);
00620     if (force)
00621         refreshMsgEdit(/*keepCursor*/true);
00622 
00623     if (approved)
00624     {
00625         _msgstrEdit->viewport()->setBackgroundRole(QPalette::Base);
00626         if (_leds)
00627             _leds->ledFuzzy->off();
00628     }
00629     else
00630     {
00631         _msgstrEdit->viewport()->setBackgroundRole(QPalette::AlternateBase);
00632         if (_leds)
00633             _leds->ledFuzzy->on();
00634     }
00635 }
00636 
00637 
00641 void KAiderView::refreshMsgEdit(bool keepCursor)
00642 {
00643     ProperTextEdit& msgEdit=*_msgstrEdit;
00644     QTextCursor cursor=msgEdit.textCursor();
00645 
00646     int pos=cursor.position();
00647     int anchor=cursor.anchor();
00648 
00649 #ifdef XLIFF
00650     CatalogString targetWithTags=_catalog->targetWithTags(_currentPos);
00651     QString target=targetWithTags.string;
00652 #else
00653     QString target=_catalog->target(_currentPos);
00654 #endif
00655     _oldMsgstr=target;
00656 
00657     if (!keepCursor && msgEdit.toPlainText()!=target)
00658     {
00659         pos=0;
00660         anchor=0;
00661     }
00662 
00663 
00664     disconnect (msgEdit.document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
00665 
00666 #ifdef XLIFF
00667     msgEdit.setContent(targetWithTags);
00668 #else
00669     //prevent undo tracking system from recording this 'action'
00670     msgEdit.document()->blockSignals(true);
00671     msgEdit.setPlainText(target);
00672     msgEdit.document()->blockSignals(false);
00673 #endif
00674 
00675     QTextCursor t=msgEdit.textCursor();
00676     t.movePosition(QTextCursor::Start);
00677     if (pos || anchor)
00678     {
00679         //int anchorDiff=pos-anchor;
00680 /*        t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,qMin(anchor,pos));
00681         t.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor,qMax(anchor,pos));
00682         */
00683         // I don't know why the following (more correct) code does not work
00684         t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,anchor);
00685         int length=pos-anchor;
00686         if (length)
00687             t.movePosition(length<0?QTextCursor::PreviousCharacter:QTextCursor::NextCharacter,QTextCursor::KeepAnchor,qAbs(length));
00688     }
00689     msgEdit.setTextCursor(t);
00690 
00691     m_msgstrHighlighter->rehighlight();
00692     connect (msgEdit.document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
00693 }
00694 
00695 
00696 //main function in this file :)
00697 void KAiderView::gotoEntry(const DocPosition& pos,int selection)
00698 {
00699     setUpdatesEnabled(false);
00700 
00701     _currentPos=pos;
00702     _currentEntry=pos.entry;
00703 
00704     if (KDE_ISUNLIKELY( _catalog->isPlural(_currentEntry)))
00705     {
00706         if (KDE_ISUNLIKELY( _catalog->numberOfPluralForms()!=m_pluralTabBar->count() ))
00707         {
00708             int i=m_pluralTabBar->count();
00709             if (_catalog->numberOfPluralForms()>m_pluralTabBar->count())
00710                 while (i<_catalog->numberOfPluralForms())
00711                     m_pluralTabBar->addTab(i18nc("@title:tab","Plural Form %1",++i));
00712             else
00713                 while (i>_catalog->numberOfPluralForms())
00714                     m_pluralTabBar->removeTab(i--);
00715         }
00716         m_pluralTabBar->show();
00717         m_pluralTabBar->blockSignals(true);
00718         m_pluralTabBar->setCurrentIndex(_currentPos.form);
00719         m_pluralTabBar->blockSignals(false);
00720     }
00721     else
00722         m_pluralTabBar->hide();
00723 
00724     //force this because there are conditions when the
00725     //signal isn't emitted (haven't identify them yet)
00726     approvedEntryDisplayed(_catalog->isApproved(_currentEntry),false);
00727 
00728 #ifdef XLIFF
00729     _msgidEdit->setContent(_catalog->sourceWithTags(_currentPos));
00730     m_msgidHighlighter->rehighlight(); //explicitly because setContent disables signals
00731 #else
00732     _msgidEdit->setPlainText(_catalog->msgid(_currentPos)/*, _catalog->msgctxt(_currentIndex)*/);
00733 #endif
00734 
00735 
00736 #ifdef UNWRAP_MSGID
00737     unwrap(_msgidEdit);
00738 #endif
00739 
00740     //kWarning()<<"calling refreshMsgEdit";
00741     refreshMsgEdit();//sets msgstredit text along the way
00742 
00743     QString targetString=_catalog->targetWithTags(_currentPos).string;
00744     bool untrans=targetString.isEmpty();
00745     if (_leds)
00746     {
00747         if (untrans)
00748             _leds->ledUntr->on();
00749         else
00750             _leds->ledUntr->off();
00751     }
00752     ProperTextEdit* msgEdit=_msgstrEdit;
00753     QTextCursor t=msgEdit->textCursor();
00754     t.movePosition(QTextCursor::Start);
00755 
00756     if (pos.offset || selection)
00757     {
00758         if (pos.part==Msgid)
00759         {
00760             msgEdit=_msgidEdit;
00761             t=msgEdit->textCursor();
00762             t.movePosition(QTextCursor::Start);
00763         }
00764 
00765         t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,pos.offset);
00766         //NOTE this was kinda bug due to on-the-fly msgid wordwrap
00767         if (selection)
00768             t.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor,selection);
00769     }
00770     else if (!untrans)
00771     {
00772         //what if msg starts with a tag?
00773         if (KDE_ISUNLIKELY( targetString.startsWith('<') ))
00774         {
00775             int offset=targetString.indexOf(QRegExp(">[^<]"));
00776             if ( offset!=-1 )
00777                 t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,offset+1);
00778         }
00779         else if (KDE_ISUNLIKELY( _catalog->msgstr(_currentPos).startsWith(TAGRANGE_IMAGE_SYMBOL) ))
00780         {
00781             int offset=targetString.indexOf(QRegExp("[^"+TAGRANGE_IMAGE_SYMBOL+']'));
00782             if ( offset!=-1 )
00783                 t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,offset+1);
00784         }
00785     }
00786 
00787     msgEdit->setTextCursor(t);
00788 
00789     //for undo/redo tracking
00790     //_oldMsgstr=_catalog->msgstr(_currentPos); :::this is done in refreshMsgEdit()
00791 
00792     //prevent undo tracking system from recording this 'action'
00793 //     disconnect (_msgstrEdit->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
00794 //     m_msgstrHighlighter->rehighlight();
00795 //     connect (_msgstrEdit->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
00796 
00797     _msgstrEdit->setFocus();
00798 
00799     //kWarning()<<"anchor"<<t.anchor()<<"pos"<<t.position();
00800     setUpdatesEnabled(true);
00801 }
00802 /*
00803 void KAiderView::dragEnterEvent(QDragEnterEvent* event)
00804 {
00805     if(event->mimeData()->hasUrls() && event->mimeData()->urls().first().path().endsWith(".po"))
00806         event->acceptProposedAction();
00807 }
00808 
00809 void KAiderView::dropEvent(QDropEvent *event)
00810 {
00811     emit fileOpenRequested(KUrl(event->mimeData()->urls().first()));
00812     event->acceptProposedAction();
00813 }
00814 
00815 
00816 
00817 */
00818 
00819 
00820 
00821 
00822 
00823 //BEGIN edit actions that are easier to do in this class
00824 void KAiderView::clearMsgStr()
00825 {
00826     if (KDE_ISUNLIKELY( _currentEntry==-1 ))
00827         return;
00828 
00829     _currentPos.offset=0;
00830     _catalog->push(new DelTextCmd(_catalog,_currentPos,_catalog->msgstr(_currentPos)));
00831     if (!_catalog->isApproved(_currentEntry))
00832         toggleApprovement(true);
00833 
00834     gotoEntry(_currentPos);
00835     emit signalChanged(_currentEntry);
00836 }
00837 
00838 void KAiderView::toggleBookmark(bool checked)
00839 {
00840     if (KDE_ISUNLIKELY( _currentEntry==-1 ))
00841         return;
00842 
00843     _catalog->setBookmark(_currentEntry,checked);
00844 }
00845 
00846 void KAiderView::toggleApprovement(bool approved)
00847 {
00848     kWarning()<<"called";
00849     if (KDE_ISUNLIKELY( _currentEntry==-1 ))
00850         return;
00851 
00852     _catalog->push(new ToggleApprovementCmd(_catalog,_currentEntry,approved));
00853     approvedEntryDisplayed(approved, /*force*/true);
00854 }
00855 
00856 
00857 void KAiderView::msgid2msgstr()
00858 {
00859     QString text(_catalog->msgid(_currentPos));
00860     QString out;
00861     QString ctxt(_catalog->msgctxt(_currentPos.entry));
00862 
00863    // this is KDE specific:
00864     if( ctxt.startsWith( "NAME OF TRANSLATORS" ) || text.startsWith( "_: NAME OF TRANSLATORS\\n" ))
00865     {
00866         if (!_catalog->msgstr(_currentPos).isEmpty())
00867             out=", ";
00868         out+=Settings::authorLocalizedName();
00869     }
00870     else if( ctxt.startsWith( "EMAIL OF TRANSLATORS" ) || text.startsWith( "_: EMAIL OF TRANSLATORS\\n" ))
00871     {
00872         if (!_catalog->msgstr(_currentPos).isEmpty())
00873             out=", ";
00874         out+=Settings::authorEmail();
00875     }
00876     else if( /*_catalog->isGeneratedFromDocbook() &&*/ text.startsWith( "ROLES_OF_TRANSLATORS" ) )
00877     {
00878         if (!_catalog->msgstr(_currentPos).isEmpty())
00879             out='\n';
00880         out+="<othercredit role=\\\"translator\\\">\n"
00881         "<firstname></firstname><surname></surname>\n"
00882         "<affiliation><address><email>"+Settings::authorEmail()+"</email></address>\n"
00883         "</affiliation><contrib></contrib></othercredit>";
00884     }
00885     else if( text.startsWith( "CREDIT_FOR_TRANSLATORS" ) )
00886     {
00887         if (!_catalog->msgstr(_currentPos).isEmpty())
00888             out='\n';
00889         out+="<para>"+Settings::authorLocalizedName()+'\n'+
00890             "<email>"+Settings::authorEmail()+"</email></para>";
00891     }
00892 /*    else if(text.contains(_catalog->miscSettings().singularPlural))
00893     {
00894         text.replace(_catalog->miscSettings().singularPlural,"");
00895     }*/
00896     // end of KDE specific part
00897 
00898 
00899 /*    QRegExp reg=_catalog->miscSettings().contextInfo;
00900     if(text.contains(reg))
00901     {
00902         text.replace(reg,"");
00903     }*/
00904 
00905     //modifyMsgstrText(0,text,true);
00906 
00907     if (out.isEmpty())
00908     {
00909         DocPosition pos=_currentPos;pos.offset=0;
00910         //_msgstrEdit->setPlainText(text);
00911         _catalog->push(new DelTextCmd(_catalog,pos,_catalog->target(_currentPos)));
00912         _oldMsgstr="";//newStr becomes OldStr
00913         _catalog->push(new InsTextCmd(_catalog,pos,text));
00914         if (KDE_ISUNLIKELY( !_catalog->isApproved(pos.entry) ))
00915             toggleApprovement(true);
00916         else
00917             approvedEntryDisplayed(true, true);
00918     }
00919     else
00920     {
00921         QTextCursor t=_msgstrEdit->textCursor();
00922         t.movePosition(QTextCursor::End);
00923         t.insertText(out);
00924         _msgstrEdit->setTextCursor(t);
00925     }
00926 }
00927 
00928 
00929 
00930 void KAiderView::unwrap(ProperTextEdit* editor)
00931 {
00932     if (!editor)
00933         editor=_msgstrEdit;
00934 
00935     QTextCursor t=editor->document()->find(QRegExp("[^(\\\\n)]$"));
00936     if (t.isNull())
00937         return;
00938 
00939     if (editor==_msgstrEdit)
00940         _catalog->beginMacro(i18nc("@item Undo action item","Unwrap"));
00941     t.movePosition(QTextCursor::EndOfLine);
00942     if (!t.atEnd())
00943         t.deleteChar();
00944 
00945     QRegExp rx("[^(\\\\n)>]$");
00946     //remove '\n's skipping "\\\\n"
00947     while (!(t=editor->document()->find(rx,t)).isNull())
00948     {
00949         t.movePosition(QTextCursor::EndOfLine);
00950         if (!t.atEnd())
00951             t.deleteChar();
00952     }
00953     if (editor==_msgstrEdit)
00954         _catalog->endMacro();
00955 }
00956 
00957 void KAiderView::insertTerm(const QString& term)
00958 {
00959     _msgstrEdit->insertPlainText(term);
00960     _msgstrEdit->setFocus();
00961 }
00962 
00963 void KAiderView::tagMenu()
00964 {
00965     if (KDE_ISUNLIKELY( Project::instance()->markup().isEmpty() ))
00966         return;
00967 
00968     QMenu menu;
00969 
00970     //QRegExp tag("(<[^>]*>)+|\\&\\w+\\;");
00971     QRegExp tag(Project::instance()->markup());
00972     tag.setMinimal(true);
00973     QString en(_msgidEdit->toPlainText());
00974     QString target(_msgstrEdit->toPlainText());
00975     en.remove('\n');
00976     target.remove('\n');
00977     int pos=0;
00978     //tag.indexIn(en);
00979     int posInMsgStr=0;
00980     QAction* txt=0;
00981     while ((pos=tag.indexIn(en,pos))!=-1)
00982     {
00983 /*        QString str(tag.cap(0));
00984         str.replace("&","&&");*/
00985         txt=menu.addAction(tag.cap(0));
00986         pos+=tag.matchedLength();
00987 
00988         if (posInMsgStr!=-1 && (posInMsgStr=target.indexOf(tag.cap(0),posInMsgStr))==-1)
00989             menu.setActiveAction(txt);
00990         else if (posInMsgStr!=-1)
00991             posInMsgStr+=tag.matchedLength();
00992     }
00993     if (!txt)
00994         return;
00995 
00996     txt=menu.exec(_msgidEdit->mapToGlobal(QPoint(0,0)));
00997     if (txt)
00998         _msgstrEdit->insertPlainText(txt->text());
00999 
01000 }
01001 
01002 //END edit actions that are easier to do in this class
01003 
01004 
01005 
01006 
01007 #include "kaiderview.moc"

lokalize

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

kdesdk

Skip menu "kdesdk"
  • kapptemplate
  • kate
  •     kate
  • kbugbuster
  • kcachegrind
  • kompare
  • lokalize
  • umbrello
  •   umbrello
Generated for kdesdk by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal