📄 msgedit.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Linguist of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//* TRANSLATOR MsgEdit This is the right panel of the main window.*/#include "msgedit.h"#include "trwindow.h"#include "simtexth.h"#include "messagemodel.h"#include "phrasemodel.h"#include <QMenu>#include <QAction>#include <QApplication>#include <QClipboard>#include <QLabel>#include <QLayout>#include <QTextEdit>#include <QPalette>#include <QString>#include <QPainter>#include <QHeaderView>#include <QDockWidget>#include <QFont>#include <QTreeView>#include <QScrollArea>#include <QtGui/QTextDocumentFragment>#include <QtGui/QTextCursor>#include <QtGui/QTextBlock>#include <QtGui/QTextFragment>#include <QtGui/QTextImageFormat>#include <QtGui/QPainter>#include <QtGui/QImage>#include <QtCore/QUrl>#include <QAbstractTextDocumentLayout>static const int MaxCandidates = 5;const char MessageEditor::backTab[] = "\a\b\f\n\r\t";const char * const MessageEditor::friendlyBackTab[] = { QT_TRANSLATE_NOOP("MessageEditor", "bell"), QT_TRANSLATE_NOOP("MessageEditor", "backspace"), QT_TRANSLATE_NOOP("MessageEditor", "new page"), QT_TRANSLATE_NOOP("MessageEditor", "new line"), QT_TRANSLATE_NOOP("MessageEditor", "carriage return"), QT_TRANSLATE_NOOP("MessageEditor", "tab") };const char *bellImageName = "trolltech/bellImage";const char *backspaceImageName = "trolltech/bsImage";const char *newpageImageName = "trolltech/newpageImage";const char *newlineImageName = "trolltech/newlineImage";const char *crImageName = "trolltech/crImage";const char *tabImageName = "trolltech/tabImage";const char *backTabImages[] = { bellImageName, backspaceImageName, newpageImageName, newlineImageName, crImageName, tabImageName};class BackTabTextEdit : public QTextEdit{public: BackTabTextEdit(QWidget *parent = 0) : QTextEdit(parent) { } virtual QVariant loadResource ( int type, const QUrl & name ); virtual void keyPressEvent ( QKeyEvent * e); virtual void focusInEvent ( QFocusEvent * e); QMap<QUrl, QImage> m_backTabOmages; QImage m_tabImg; QImage m_newlineImg;};QVariant BackTabTextEdit::loadResource ( int type, const QUrl & name ){ QImage img; if (type == QTextDocument::ImageResource) { img = m_backTabOmages.value(name); if (img.isNull()) { for (uint i = 0; i < qstrlen(MessageEditor::backTab); ++i) { if (backTabImages[i] && name == QUrl(QLatin1String(backTabImages[i]))) { QFont fnt = font(); fnt.setItalic(true); QFontMetrics fm(fnt); int h = fm.height(); QString str = QString::fromAscii("(%1)").arg(MessageEditor::friendlyBackTab[i]); int w = fm.boundingRect(str).width() + 1; //### QImage textimg(w, h, QImage::Format_RGB32); textimg.fill(qRgb(255,255,255)); QPainter p(&textimg); p.setPen(QColor(Qt::blue)); p.setFont(fnt); p.drawText(0, fm.ascent(), str); //### document()->addResource(QTextDocument::ImageResource, QUrl(QLatin1String(backTabImages[i])), textimg); m_backTabOmages.insert(name, textimg); return textimg; } } } } return img;}void BackTabTextEdit::focusInEvent ( QFocusEvent * e){ TransEditor *te = qobject_cast<TransEditor*>(parent()); te->gotFocusInEvent(e); QTextEdit::focusInEvent(e);}void BackTabTextEdit::keyPressEvent ( QKeyEvent * e ){ bool eatevent = false; QTextCursor tc = textCursor(); if (e->modifiers() == Qt::NoModifier) { switch (e->key()) { case Qt::Key_Tab: { tc = textCursor(); tc.insertImage(QLatin1String(tabImageName)); eatevent = true; break; } case Qt::Key_Return: { tc = textCursor(); document()->blockSignals(true); tc.beginEditBlock(); tc.insertImage(QLatin1String(newlineImageName)); document()->blockSignals(false); tc.insertBlock(); tc.endEditBlock(); eatevent = true; break; } case Qt::Key_Backspace: if (tc.anchor() == tc.position()) { QTextCursor tc = textCursor(); if (!tc.atStart() && tc.atBlockStart()) { tc.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 1); QTextCharFormat fmt = tc.charFormat(); if (fmt.isImageFormat()) { tc.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 1); } tc.removeSelectedText(); eatevent = true; } } break; case Qt::Key_Delete: if (tc.anchor() == tc.position()) { QTextCursor tc = textCursor(); tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1); QTextCharFormat fmt = tc.charFormat(); if (fmt.isImageFormat()) { if (!tc.atEnd() && tc.atBlockEnd()) { tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1); } tc.removeSelectedText(); eatevent = true; } } break; } } // Also accept Key_Enter on the numpad if (e->modifiers() == Qt::KeypadModifier && e->key() == Qt::Key_Enter) { tc = textCursor(); document()->blockSignals(true); tc.beginEditBlock(); tc.insertImage(QLatin1String(newlineImageName)); document()->blockSignals(false); tc.insertBlock(); tc.endEditBlock(); eatevent = true; } if (eatevent) e->accept(); else QTextEdit::keyPressEvent(e);}TransEditor::TransEditor(QWidget *parent /*= 0*/) : QWidget(parent){ QVBoxLayout *lout = new QVBoxLayout(this); lout->setSpacing(2); lout->setMargin(0); m_label = new QLabel(this); lout->addWidget(m_label); m_editor = new BackTabTextEdit(this); m_label->setFocusProxy(m_editor ); setFocusProxy(m_editor); lout->addWidget(m_editor); setLayout(lout); connect(m_editor->document(), SIGNAL(contentsChanged()), this, SLOT(handleTranslationChanges())); if (parent) { QFont fnt = parent->font(); fnt.setBold(true); m_label->setFont(fnt); }}void TransEditor::gotFocusInEvent ( QFocusEvent * e){ Q_UNUSED(e); emit gotFocusIn();}void TransEditor::setLabel(const QString &text){ m_label->setText(text);}void TransEditor::handleTranslationChanges(){ calculateFieldHeight();}void TransEditor::calculateFieldHeight(){ QTextEdit *field = m_editor; int contentsHeight = qRound(field->document()->documentLayout()->documentSize().height()); if (contentsHeight != field->height()) { int oldHeight = field->height(); if(contentsHeight < 30) contentsHeight = 30; resize(width(), m_label->height() + 6 + 2 + contentsHeight); emit heightUpdated(height() + (field->height() - oldHeight)); }}QString TransEditor::translation() const { QString plain; QTextBlock tb = m_editor->document()->begin(); for (int b = 0; b < m_editor->document()->blockCount(); ++b) { QTextBlock::iterator it = tb.begin(); if (it.atEnd()) { plain += tb.text(); } else { while ( !it.atEnd() ) { QTextCharFormat fmt = it.fragment().charFormat(); if (fmt.isImageFormat()) { QTextImageFormat tif = fmt.toImageFormat(); if (tif.name() == QLatin1String(tabImageName)) plain += QLatin1Char('\t'); else if (tif.name() == QLatin1String(newlineImageName)) plain += QLatin1Char('\n'); } else { plain += it.fragment().text(); } ++it; } } tb = tb.next(); } return plain;}void MessageEditor::visualizeBackTabs(const QString &text, QTextEdit *te){ te->clear(); QTextCursor tc(te->textCursor()); QTextCharFormat blueFormat = defFormat; blueFormat.setForeground(QBrush(Qt::blue)); blueFormat.setFontItalic(true); blueFormat.setProperty(QTextFormat::UserProperty, -1); QString plainText; for (int i = 0; i < (int) text.length(); ++i) { int ch = text[i].unicode(); if (ch < 0x20) { if (!plainText.isEmpty()) { tc.insertText(plainText, defFormat); plainText.clear(); } const char *p = strchr(backTab, ch); // store the character in the user format property // in the first '(' in the phrase blueFormat.setProperty(QTextFormat::UserProperty, ch); tc.insertText(QString("("), blueFormat); blueFormat.setProperty(QTextFormat::UserProperty, -1); if (p == 0) { tc.insertText(QString::number(ch, 16) + ")", blueFormat); } else { tc.insertText(MessageEditor::tr(friendlyBackTab[p - backTab]) + ")", blueFormat); if (backTab[p - backTab] == '\n') tc.insertBlock(); } } // if a space is by itself, at the end, or beside other spaces else if (ch == ' ') { if (i == 0 || i == text.length() - 1 || text[i - 1].isSpace() || text[i + 1].isSpace()) { tc.insertText(plainText, defFormat); plainText.clear(); blueFormat.setProperty(QTextFormat::UserProperty, ch); tc.insertText(QString("("), blueFormat); blueFormat.setProperty(QTextFormat::UserProperty, -1); tc.insertText(MessageEditor::tr("sp)"), blueFormat); } else { plainText += ' '; } } else { plainText += QString(ch); } } tc.insertText(plainText, defFormat);}SourceTextEdit::SourceTextEdit(QWidget *parent) : QTextEdit(parent){ srcmenu = 0; actCopy = new QAction(tr("&Copy"), this); actCopy->setShortcut(QKeySequence(tr("Ctrl+C"))); actSelect = new QAction(tr("Select &All"), this); actSelect->setShortcut(QKeySequence(tr("Ctrl+A"))); connect(actCopy, SIGNAL(triggered()), this, SLOT(copySelection())); connect(actSelect, SIGNAL(triggered()), this, SLOT(selectAll()));}void SourceTextEdit::copySelection(){ QTextDocumentFragment tdf = textCursor().selection(); QTextDocument td; QTextCursor tc(&td); tc.insertFragment(tdf); int ch; tc.movePosition(QTextCursor::Start); while(!tc.atEnd()) { tc.movePosition(QTextCursor::NextCharacter); ch = tc.charFormat().intProperty(QTextFormat::UserProperty); if (ch != 0) // if wrong format { // delete char tc.deletePreviousChar(); if (ch != -1) // insert backtab tc.insertText(QString(ch)); } } QApplication::clipboard()->setText(td.toPlainText());}void SourceTextEdit::contextMenuEvent(QContextMenuEvent *e){ if (!srcmenu) { srcmenu = new QMenu(this); srcmenu->addAction(actCopy); srcmenu->addAction(actSelect); } actCopy->setEnabled(textCursor().hasSelection()); actSelect->setEnabled(!document()->isEmpty()); srcmenu->popup(e->globalPos());}/* ShadowWidget class impl. Used to create a shadow like effect for a widget*/ShadowWidget::ShadowWidget(QWidget *parent) : QWidget(parent), sWidth(10), wMargin(3), childWgt(0){}ShadowWidget::ShadowWidget(QWidget *child, QWidget *parent) : QWidget(parent), sWidth(10), wMargin(3), childWgt(0){ setWidget(child);}void ShadowWidget::setWidget(QWidget *child){ childWgt = child; if (childWgt && childWgt->parent() != this) { childWgt->setParent(this); childWgt->move(0,0); childWgt->show(); }}void ShadowWidget::resizeEvent(QResizeEvent *){ if(childWgt) { childWgt->move(wMargin, wMargin); childWgt->resize(width() - sWidth - wMargin, height() - sWidth - wMargin); }}void ShadowWidget::paintEvent(QPaintEvent *e){ QPainter p; int w = width() - sWidth; int h = height() - sWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -