Logo Search packages:      
Sourcecode: cb2bib version File versions

c2bTextEdit.cpp

/***************************************************************************
 *   Copyright (C) 2004-2009 by Pere Constans
 *   constans@molspaces.com
 *   cb2Bib version 1.3.0. Licensed under the GNU GPL version 3.
 *   See the LICENSE file that comes with this distribution.
 ***************************************************************************/
#include "c2bTextEdit.h"

#include "c2bSettings.h"
#include "c2bUtils.h"

#include <QKeyEvent>
#include <QList>
#include <QMenu>
#include <QPainter>
#include <QScrollBar>
#include <QTextBlock>
#include <QTextCursor>


c2bTextEdit::c2bTextEdit(QWidget* parentw) : QPlainTextEdit(parentw)
{
    setFrameShape(QPlainTextEdit::StyledPanel);
    setFrameShadow(QPlainTextEdit::Raised);
    settings = c2bSettingsP;
    connect(settings, SIGNAL(newSettings()), this, SLOT(loadSettings()));

    _line_number_area = new LineNumberArea(this);
    _line_number_area_color = palette().color(QPalette::Active, QPalette::Base).darker(110);
    _line_number_color_p = &settings->colors.comment_color;
    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth()));
    connect(this, SIGNAL(updateRequest(const QRect&, int)), this, SLOT(updateLineNumberArea(const QRect&, int)));
    updateLineNumberAreaWidth();

    c2bUtils::addSeparator(this);
    wordWrapAction = new QAction(this);
    addAction(wordWrapAction);
    wordWrapAction->setText(tr("Wrap Text"));
    wordWrapAction->setStatusTip(tr("Wrap Text"));
    connect(wordWrapAction, SIGNAL(triggered()), this, SLOT(wordWrap()));

    wordUnWrapAction = new QAction(this);
    addAction(wordUnWrapAction);
    wordUnWrapAction->setText(tr("Unwrap Text"));
    wordUnWrapAction->setStatusTip(tr("Unwrap Text"));
    connect(wordUnWrapAction, SIGNAL(triggered()), this, SLOT(wordUnWrap()));

    if (settings->value("c2bTextEdit/WrapMode", false).toBool())
        wordWrap();
    else
        wordUnWrap();
}

c2bTextEdit::~c2bTextEdit()
{
    settings->setValue("c2bTextEdit/WrapMode", lineWrapMode() == QPlainTextEdit::WidgetWidth);
}


void c2bTextEdit::setBibTeXActions()
{
    c2bUtils::addSeparator(this);
    pasteCurrentBibTeXAction = new QAction(this);
    addAction(pasteCurrentBibTeXAction);
    pasteCurrentBibTeXAction->setShortcut(tr("Shift+Ins"));
    pasteCurrentBibTeXAction->setText(tr("Paste Current BibTeX"));
    pasteCurrentBibTeXAction->setStatusTip(tr("Paste Current BibTeX"));

    c2bUtils::addSeparator(this);
    convertSelection2LaTeXAction = new QAction(this);
    addAction(convertSelection2LaTeXAction);
    convertSelection2LaTeXAction->setText(tr("Selection to LaTeX"));
    convertSelection2LaTeXAction->setStatusTip(tr("Selection to LaTeX"));
    connect(convertSelection2LaTeXAction, SIGNAL(triggered()), this, SLOT(convert2LaTeX()));
    convertSelection2LaTeXAction->setEnabled(false);
    connect(this, SIGNAL(copyAvailable(bool)), convertSelection2LaTeXAction, SLOT(setEnabled(bool)));
    convertSelection2UnicodeAction = new QAction(this);
    addAction(convertSelection2UnicodeAction);
    convertSelection2UnicodeAction->setText(tr("Selection to Unicode"));
    convertSelection2UnicodeAction->setStatusTip(tr("Selection to Unicode"));
    connect(convertSelection2UnicodeAction, SIGNAL(triggered()), this, SLOT(convert2Unicode()));
    convertSelection2UnicodeAction->setEnabled(false);
    connect(this, SIGNAL(copyAvailable(bool)), convertSelection2UnicodeAction, SLOT(setEnabled(bool)));

    c2bUtils::addSeparator(this);
    journalsToFullAction = new QAction(this);
    addAction(journalsToFullAction);
    journalsToFullAction->setText(tr("Set Journals to Full Name"));
    journalsToFullAction->setStatusTip(tr("Set Journals to Full Name"));
    journalsToAbbreviatedAction = new QAction(this);
    addAction(journalsToAbbreviatedAction);
    journalsToAbbreviatedAction->setText(tr("Set Journals to Abbreviated Name"));
    journalsToAbbreviatedAction->setStatusTip(tr("Set Journals to Abbreviated Name"));

    c2bUtils::addSeparator(this);
    updateMetadataAction = new QAction(this);
    addAction(updateMetadataAction);
    updateMetadataAction->setText(tr("Update Documents Metadata"));
    updateMetadataAction->setStatusTip(tr("Update Documents Metadata"));
}

void c2bTextEdit::contextMenuEvent(QContextMenuEvent* qevent)
{
    QMenu* menu = createStandardContextMenu();
    QList<QAction*> acts = actions();
    for (int i = 0; i < acts.count(); ++i)
        menu->addAction(acts.at(i));
    menu->exec(qevent->globalPos());
    delete menu;
}

void c2bTextEdit::keyPressEvent(QKeyEvent* qevent)
{
    QPlainTextEdit::keyPressEvent(qevent);
    if (qevent->key() == Qt::Key_Insert)
    {
        setOverwriteMode(!overwriteMode());
        emit overwriteModeChanged();
    }
}

void c2bTextEdit::wordWrap()
{
    setLineWrapMode(QPlainTextEdit::WidgetWidth);
    wordWrapAction->setEnabled(false);
    wordUnWrapAction->setEnabled(true);
}

void c2bTextEdit::wordUnWrap()
{
    setLineWrapMode(QPlainTextEdit::NoWrap);
    wordWrapAction->setEnabled(true);
    wordUnWrapAction->setEnabled(false);
}

void c2bTextEdit::updatePlainText(const QString& newText)
{
    int scrollPosition = verticalScrollBar()->value();
    int cursorBlock = textCursor().blockNumber();
    int cursorColumn = textCursor().columnNumber();
    setPlainText(newText);

    QTextBlock p = document()->begin();
    int i = 0;
    while (p.isValid())
    {
        if (cursorBlock == i)
            break;
        i++;
        p = p.next();
    }
    QTextCursor tcursor = textCursor();
    tcursor.setPosition(p.position() + cursorColumn, QTextCursor::MoveAnchor);
    setTextCursor(tcursor);
    verticalScrollBar()->setValue(scrollPosition);
}

void c2bTextEdit::convert2LaTeX()
{
    QString txt = textCursor().selectedText();
    // Better do the long way: Convert anything to c2b, and then
    // translate to TeX
    c2bUtils::fullBibToC2b(txt);
    insertPlainText(c2bUtils::c2bToBib(txt));
}

void c2bTextEdit::convert2Unicode()
{
    QString txt = textCursor().selectedText();
    // Strictly, this should be bibToC2b; but convert also
    // possible PNAS like, and, for consistency, HTML sub
    // and superscripts to TeX
    insertPlainText(c2bUtils::fullBibToC2b(txt));
}

void c2bTextEdit::loadSettings()
{
    if (font() != settings->c2bMonoFont)
    {
        setFont(settings->c2bMonoFont);
        updateLineNumberAreaWidth();
    }
    _line_number_area->update(); // Update, otherwise number colors might not follow apply button
}


/***************************************************************************
 *  Line number area (From CodeEditor Qt's example)
 ***************************************************************************/

int c2bTextEdit::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10)
    {
        max /= 10;
        ++digits;
    }
    const int space = 5 + fontMetrics().width(QLatin1Char('9')) * digits;
    return space;
}

void c2bTextEdit::updateLineNumberAreaWidth()
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void c2bTextEdit::updateLineNumberArea(const QRect& qrect, int dy)
{
    if (dy)
        _line_number_area->scroll(0, dy);
    else
        _line_number_area->update(0, qrect.y(), _line_number_area->width(), qrect.height());
    if (qrect.contains(viewport()->rect()))
        updateLineNumberAreaWidth();
}

void c2bTextEdit::resizeEvent(QResizeEvent* qevent)
{
    QPlainTextEdit::resizeEvent(qevent);
    QRect cr = contentsRect();
    _line_number_area->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void c2bTextEdit::lineNumberAreaPaintEvent(QPaintEvent* qevent)
{
    QPainter painter(_line_number_area);
    painter.fillRect(qevent->rect(), _line_number_area_color);
    painter.setPen(*_line_number_color_p);
    QFont f = font();
    f.setPointSize(qMax(0, f.pointSize() - 3));
    painter.setFont(f);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int)blockBoundingRect(block).height();

    while (block.isValid() && top <= qevent->rect().bottom())
    {
        if (block.isVisible() && bottom >= qevent->rect().top())
        {
            const QString number = QString::number(blockNumber + 1);
            painter.drawText(5, top + 2, _line_number_area->width(), fontMetrics().height(), Qt::AlignLeft, number);
        }
        block = block.next();
        top = bottom;
        bottom = top + (int)blockBoundingRect(block).height();
        ++blockNumber;
    }
}

Generated by  Doxygen 1.6.0   Back to index