Пример #1
0
int MsgView::setMsgBgColor(unsigned long uin, unsigned long id, unsigned long rgb, int start)
{
    QString pat;
    pat.sprintf("<a href=\"msg://%lu.%lu", uin, id);
    for (int n = start; n < paragraphs(); n++){
        if (text(n).find(pat) < 0) continue;
        pat = "<a href=\"msg://";
        for (n++; n < paragraphs(); n++){
            if (text(n).isEmpty()) break;
            if (text(n).find(pat) >= 0) break;
            setParagraphBackgroundColor(n, QColor(rgb));
        }
        return n;
    }
    log(L_WARN, "Message bg color not found");
    return paragraphs();
}
Пример #2
0
// <hack>
// We have to use this function since Qt has no tag to set background color per-paragraph
// from within HTML. See matching hack in MsgViewBase::messageText.
void MsgViewBase::setBackground(unsigned n)
{
    QColor bgcolor;
    bool bInMsg = false;
    bool bSet   = false;

    QString sAnchor = QString::fromLatin1(MSG_ANCHOR),
                      sBegin = QString::fromLatin1(MSG_BEGIN);

    int i;
    for (i = n; i >= 0; i--){
        QString s = text(i);
        if (s.find(sAnchor) >= 0)
            break;
    }
    for (; i < paragraphs(); i++){
        QString s = text(i);
        int anchorPos = s.find(sAnchor);
        if (anchorPos >= 0)
        {
            bInMsg = false;
            bSet   = false;

            // This code could be a bit faster by making assumptions.
            // However, I prefer to be correct HTML-parser-wise.

            int idStart = anchorPos + sAnchor.length();
            int idEnd = s.find('\"', idStart);
            if ((idStart >= 0) && (idEnd >= 0))
            {
                QString id = s.mid(idStart, idEnd - idStart);

                // Parse the message id (msgId,backgroundColor,...)
                int bgcolorStart = id.find(',');
                if (bgcolorStart >= 0)
                {
                    QString sBgcolor = id.mid(bgcolorStart + 1);
                    int bgcolorEnd = sBgcolor.find(',');
                    if (bgcolorEnd > 0)
                        sBgcolor = sBgcolor.left(bgcolorEnd);
                    if (!sBgcolor.isEmpty())
                        bgcolor = QColor(sBgcolor.toULong(&bSet));
                }
            }
        }
        if (s.find(sBegin) >= 0)
            bInMsg = true;

        if (bInMsg && bSet){
            setParagraphBackgroundColor(i, bgcolor);
        }else{
            clearParagraphBackground(i);
        }
    }

}
Пример #3
0
bool TextEdit::isEmpty()
{
    if (paragraphs() < 2){
        QString t = text(0);
        if (textFormat() == QTextEdit::RichText)
            t = unquoteText(t);
        return t.isEmpty();
    }
    return false;
}
Пример #4
0
void TextShow::searchAgain(int n)
{
    if (n) return;
    if (!srchdialog) return;
    if (srchdialog->get_direction()){
        startSearch(paragraphs(), 0);
    }else{
        startSearch(0, 0);
    }
}
Пример #5
0
void MsgViewBase::addMessage(Message *msg, bool bUnread, bool bSync)
{
    unsigned n = paragraphs();
    if (n > 0)
        n--;
    append(messageText(msg, bUnread));
    if (!CorePlugin::m_plugin->getOwnColors())
        setBackground(n);
    if (bSync)
        sync(n);
}
Пример #6
0
void TextEdit::setTextFormat(QTextEdit::TextFormat format)
{
    if (format == textFormat())
        return;
    if (format == RichText){
        QTextEdit::setTextFormat(format);
        return;
    }
    QString t = plainText(0, paragraphs(), 0, 0);
    QTextEdit::setTextFormat(format);
    setText(t);
}
Пример #7
0
QRect MultilineTextEdit::mapToView(int para,int index)
{
    if( para < 0 || para > paragraphs() ||
        index < 0 || index > paragraphLength(para) )
            return QRect(); //invalid rectangle

    const QFontMetrics& fm = fontMetrics();
    const QString& paratext = text(para);

    // Find index of the first character on the same line as parameter
    // 'index' using binary search. Very fast, even for long texts.
    int linestart = 0;
    int indexline = lineOfChar( para, index );
    if ( indexline > 0 )
    {
        int min = 0, max = index;
        int i = (min + max)/2;
        int iline = lineOfChar( para, i );
        while ( iline != indexline-1 ||
                lineOfChar( para, i+1 ) != indexline )
        {
            Q_ASSERT( min != max && min != i && max != i );
            if ( iline < indexline )
                min = i;
            else
                max = i;
            i = (min + max)/2;
            iline = lineOfChar( para, i );
        }
        linestart = i+1;
    }
    Q_ASSERT( linestart >= 0 );

    int linewidth = fm.size(ExpandTabs, paratext.mid( linestart, index-linestart )).width();
    int linewidth2 = fm.size(ExpandTabs, paratext.mid( linestart, index-linestart+1 )).width();

    // FIXME as soon as it's possible to ask real margins from QTextEdit:
    const int left_margin = 4;
    // const int top_margin = 4;

    QPainter painter( viewport());
    const QRect& linerect = paragraphRect(para);

    return QRect(
        contentsToViewport( QPoint(
            left_margin + linerect.left() + linewidth ,
            /*top_margin + */linerect.top() + indexline * fm.lineSpacing() + fm.leading())),
        QSize(
            linewidth2-linewidth,
            fm.lineSpacing()
        ));
}
Пример #8
0
void MsgView::deleteUser(unsigned long uin)
{
    QString pat;
    pat.sprintf("<a href=\"msg://%lu.", uin);
    for (int i = 0; i < paragraphs();){
        if (text(i).find(pat) < 0){
            for (i++; i < paragraphs(); i++)
                if (text(i).find("<a href=\"msg://") >= 0) break;
            continue;
        }
        removeParagraph(i);
        for (; i < paragraphs(); ){
            if (text(i).find("<a href=\"msg://") >= 0) break;
            unsigned n = paragraphs();
            removeParagraph(i);
            if (n == paragraphs()){
                i++;
                break;
            }
        }
    }
}
Пример #9
0
void MsgViewBase::reload()
{
    QString t;
    vector<Msg_Id> msgs;
    unsigned i;
    for (i = 0; i < (unsigned)paragraphs(); i++){
        QString s = text(i);
        int n = s.find(MSG_ANCHOR);
        if (n < 0)
            continue;
        s = s.mid(n + strlen(MSG_ANCHOR));
        n = s.find("\"");
        if (n < 0)
            continue;
        string client;
        Msg_Id id;
        id.id = messageId(s.left(n), client);
        id.client = client;
        unsigned nn;
        for (nn = 0; nn < msgs.size(); nn++){
            if ((msgs[nn].id == id.id) && (msgs[nn].client == id.client))
                break;
        }
        if (nn >= msgs.size())
            msgs.push_back(id);
    }
    for (i = 0; i < msgs.size(); i++){
        Message *msg = History::load(msgs[i].id, msgs[i].client.c_str(), m_id);
        if (msg == NULL)
            continue;
        t += messageText(msg, false);
        delete msg;
    }
    QPoint p = QPoint(0, height());
    p = mapToGlobal(p);
    p = viewport()->mapFromGlobal(p);
    int x, y;
    viewportToContents(p.x(), p.y(), x, y);
    int para;
    int pos = charAt(QPoint(x, y), &para);
    setText(t);
    if (!CorePlugin::m_plugin->getOwnColors())
        setBackground(0);
    if (pos == -1){
        scrollToBottom();
    }else{
        setCursorPosition(para, pos);
        ensureCursorVisible();
    }
}
Пример #10
0
void MsgView::messageRead(ICQMessage *msg)
{
    QString pat;
    pat.sprintf("<a href=\"msg://%lu.%lu", msg->getUin(), msg->Id);
    for (int i = 0; i < paragraphs();){
        if (text(i).find(pat) < 0){
            for (i++; i < paragraphs(); i++)
                if (text(i).find("<a href=\"msg://") >= 0) break;
            continue;
        }
        int paraFrom, indexFrom;
        int paraTo, indexTo;
        getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
        setSelection(i, 0, i, 0xFFFF);
        setBold(false);
        if ((paraFrom == -1) && (paraTo == -1)){
            removeSelection();
            scrollToBottom();
        }else{
            setSelection(paraFrom, indexFrom, paraTo, indexTo);
        }
        break;
    }
}
Пример #11
0
void KDiffTextEdit::saveAs()
{
  QString fName = KFileDialog::getSaveFileName();
  if ( fName.isEmpty() )
    return;

  QFile f( fName );
  if ( f.open( IO_WriteOnly ) ) {
    QTextStream stream( &f );
    int pCount = paragraphs();
    for ( int i = 0; i < pCount; ++i )
      stream << text( i ) << "\n";
    f.close();
  } else {
    KMessageBox::sorry( 0, i18n("Unable to open file."), i18n("Diff Frontend") );
  }
}
Пример #12
0
bool DisassembleWidget::displayCurrent()
{
    Q_ASSERT(address_ >= lower_ || address_ <= upper_);

    int line;
    for (line=0; line < paragraphs(); line++)
    {
        unsigned long address = strtoul(text(line).latin1(), 0, 0);
        if (address == address_)
        {
            // put cursor at start of line and highlight the line
            setCursorPosition(line, 0);
            setSelection(line,0,line+1,0,0);
            return true;
        }
    }

    return false;
}
Пример #13
0
void QIMessageBox::setDetailsText(const QString &strText)
{
    /* Make sure details-text is NOT empty: */
    AssertReturnVoid(!strText.isEmpty());

    /* Split details into paragraphs: */
    QStringList paragraphs(strText.split("<!--EOP-->", QString::SkipEmptyParts));
    /* Make sure details-text has at least one paragraph: */
    AssertReturnVoid(!paragraphs.isEmpty());

    /* Enumerate all the paragraphs: */
    QStringPairList details;
    foreach (const QString &strParagraph, paragraphs)
    {
        /* Split each paragraph into pairs: */
        QStringList parts(strParagraph.split("<!--EOM-->", QString::KeepEmptyParts));
        /* Make sure each paragraph consist of 2 parts: */
        AssertReturnVoid(parts.size() == 2);
        /* Append each pair into details-list: */
        details << QStringPair(parts[0], parts[1]);
    }
Пример #14
0
void KDiffTextEdit::applySyntaxHighlight()
{
  // the diff has been loaded so we apply a simple highlighting
  static QColor cAdded( 190, 190, 237);
  static QColor cRemoved( 190, 237, 190 );

  if ( !_highlight )
    return;

  int paragCount = paragraphs();
  for ( int i = 0; i < paragCount; ++i ) {
    QString txt = text( i );
    if ( txt.length() > 0 ) {
      if ( txt.startsWith( "+" ) || txt.startsWith( ">" ) ) {
        setParagraphBackgroundColor( i, cAdded );
      } else if ( txt.startsWith( "-" ) || txt.startsWith( "<" ) ) {
        setParagraphBackgroundColor( i, cRemoved );
      }
    }
  }
}
Пример #15
0
void KJotsEdit::print(TQString title)
{
    KPrinter printer;
    printer.setDocName(title);
    printer.setFullPage(false);
    printer.setCreator("KJots");

    if (printer.setup(this))
    {
        TQFont printFont = font();
        TQPainter painter( &printer );
        TQPaintDeviceMetrics metrics( &printer );
        int y = 0;
        int maxWidth = metrics.width();
        int maxHeight = metrics.height();
        TQString currentParagraph;

        for (int paragraphCount = 0; paragraphCount < paragraphs(); ++paragraphCount )
        {
            currentParagraph = text(paragraphCount);
            TQRect r = painter.boundingRect(0, y, maxWidth, maxHeight,
                    TQPainter::ExpandTabs | TQPainter::WordBreak,
                    currentParagraph);

            if ((y + r.height()) > maxHeight)
            {
                printer.newPage();
                y = 0;
            }

            painter.drawText(0, y, maxWidth, maxHeight - y,
                    TQPainter::ExpandTabs | TQPainter::WordBreak,
                    currentParagraph);
            y += r.height();
        }
        painter.end();
    }
}
Пример #16
0
void InsetCaption::getArgument(otexstream & os,
			OutputParams const & runparams) const
{
	InsetLayout const & il = getLayout();

	if (!il.leftdelim().empty())
		os << il.leftdelim();
  
	OutputParams rp = runparams;
	if (isPassThru())
		rp.pass_thru = true;
	if (il.isNeedProtect())
		rp.moving_arg = true;
	rp.par_begin = 0;
	rp.par_end = paragraphs().size();

	// Output the contents of the inset
	latexParagraphs(buffer(), text(), os, rp);
	runparams.encoding = rp.encoding;

	if (!il.rightdelim().empty())
		os << il.rightdelim();
}
Пример #17
0
void *MsgViewBase::processEvent(Event *e)
{
    if ((e->type() == EventRewriteMessage) || (e->type() == EventMessageRead)){
        Message *msg = (Message*)(e->param());
        if (msg->contact() != m_id)
            return NULL;
        unsigned i;
        for (i = 0; i < (unsigned)paragraphs(); i++){
            QString s = text(i);
            int n = s.find(MSG_ANCHOR);
            if (n < 0)
                continue;
            s = s.mid(n + strlen(MSG_ANCHOR));
            n = s.find("\"");
            if (n < 0)
                continue;
            string client;
            if ((messageId(s.left(n), client) == msg->id()) && (client == msg->client()))
                break;
        }
        if (i >= (unsigned)paragraphs())
            return NULL;
        Msg_Id id;
        id.id     = msg->id();
        id.client = msg->client();
        m_updated.push_back(id);
        QTimer::singleShot(0, this, SLOT(update()));
        return NULL;
    }
    if (e->type() == EventCutHistory){
        CutHistory *ch = (CutHistory*)(e->param());
        if (ch->contact != m_id)
            return NULL;

        bool bDelete = false;
        vector<unsigned> start_pos;
        vector<unsigned> end_pos;
        for (unsigned i = 0; i < (unsigned)paragraphs(); i++){
            QString s = text(i);
            int n = s.find(MSG_ANCHOR);
            if (n < 0)
                continue;
            s = s.mid(n + strlen(MSG_ANCHOR));
            n = s.find("\"");
            if (n < 0)
                continue;
            string client;
            unsigned id = messageId(s.left(n), client);
            if ((client == ch->client) && (id >= ch->from) && (id < ch->from + ch->size)){
                if (!bDelete){
                    bDelete = true;
                    start_pos.push_back(i);
                }
            }else{
                if (bDelete){
                    bDelete = false;
                    end_pos.push_back(i);
                }
            }
        }
        if (bDelete)
            end_pos.push_back(paragraphs());
        if (start_pos.size()){
            int paraFrom, indexFrom;
            int paraTo, indexTo;
            getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
            QPoint p = QPoint(0, 0);
            p = mapToGlobal(p);
            p = viewport()->mapFromGlobal(p);
            int x, y;
            viewportToContents(p.x(), p.y(), x, y);
            int para;
            int pos = charAt(QPoint(x, y), &para);
            setReadOnly(false);
            for (unsigned i = 0; i < start_pos.size(); i++){
                setSelection(start_pos[i], 0, end_pos[i], 0);
                removeSelectedText();
                if ((unsigned)pos >= start_pos[i])
                    pos = end_pos[i] - start_pos[i];
            }
            if ((paraFrom == -1) && (paraTo == -1)){
                if (pos == -1){
                    scrollToBottom();
                }else{
                    setCursorPosition(para, pos);
                    ensureCursorVisible();
                }
            }else{
                setSelection(paraFrom, indexFrom, paraTo, indexTo);
            }
            setReadOnly(true);
            repaint();
        }
        m_cut.push_back(*ch);
        return NULL;
    }
    if (e->type() == EventMessageDeleted){
        Message *msg = (Message*)(e->param());
        if (msg->contact() != m_id)
            return NULL;
        for (unsigned i = 0; i < (unsigned)paragraphs(); i++){
            QString s = text(i);
            int n = s.find(MSG_ANCHOR);
            if (n < 0)
                continue;
            s = s.mid(n + strlen(MSG_ANCHOR));
            n = s.find("\"");
            if (n < 0)
                continue;
            string client;
            if ((messageId(s.left(n), client) != msg->id()) || (client != msg->client()))
                continue;
            string ss;
            ss = text(i).local8Bit();
            log(L_DEBUG, "?: %s", ss.c_str());

            unsigned j;
            for (j = i + 1; j < (unsigned)paragraphs(); j++){
                QString s = text(j);
                ss = text(j).local8Bit();
                log(L_DEBUG, ">: %s", ss.c_str());
                int n = s.find(MSG_ANCHOR);
                if (n < 0)
                    continue;
                s = s.mid(n + strlen(MSG_ANCHOR));
                n = s.find("\"");
                if (n < 0)
                    continue;
                string client;
                if ((messageId(s.left(n), client) != msg->id()) || (client != msg->client()))
                    break;
            }
            int paraFrom, indexFrom;
            int paraTo, indexTo;
            getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
            unsigned pos = 0xFFFF;
            if (j == (unsigned)paragraphs()){
                j++;
                pos = 0;
            }
            setSelection(i, 0, j - 1, pos);
            setReadOnly(false);
            removeSelectedText();
            setReadOnly(true);
            if ((paraFrom == -1) && (paraTo == -1)){
                scrollToBottom();
            }else{
                setSelection(paraFrom, indexFrom, paraTo, indexTo);
            }
            break;
        }
        return NULL;
    }
    if (e->type() == EventHistoryConfig){
        unsigned id = (unsigned)(e->param());
        if (id && (id != m_id))
            return NULL;
        reload();
    }
    if (e->type() == EventHistoryColors)
        setColors();
    if (e->type() == EventCheckState){
        CommandDef *cmd = (CommandDef*)(e->param());
        if ((cmd->param != this) || (cmd->menu_id != MenuMsgView))
            return NULL;
        Message *msg;
        switch (cmd->id){
        case CmdCopy:
            cmd->flags &= ~(COMMAND_DISABLED | COMMAND_CHECKED);
            if (!hasSelectedText())
                cmd->flags |= COMMAND_DISABLED;
            return e->param();
        case CmdMsgOpen:
            msg = currentMessage();
            if (msg){
                unsigned type = msg->baseType();
                delete msg;
                CommandDef *def = CorePlugin::m_plugin->messageTypes.find(type);
                if (def == NULL)
                    return NULL;
                cmd->icon = def->icon;
                cmd->flags &= ~COMMAND_CHECKED;
                return e->param();
            }
            return NULL;
        case CmdMsgSpecial:
            msg = currentMessage();
            if (msg){
                Event eMenu(EventGetMenuDef, (void*)MenuMsgCommand);
                CommandsDef *cmdsMsg = (CommandsDef*)(eMenu.process());

                unsigned n = 0;
                MessageDef *mdef = NULL;
                unsigned type = msg->baseType();
                const CommandDef *cmdsSpecial = NULL;
                CommandDef *msgCmd = CorePlugin::m_plugin->messageTypes.find(type);
                if (msgCmd)
                    mdef = (MessageDef*)(msgCmd->param);

                if (mdef){
                    if (msg->getFlags() & MESSAGE_RECEIVED){
                        cmdsSpecial = mdef->cmdReceived;
                    }else{
                        cmdsSpecial = mdef->cmdSent;
                    }
                    if (cmdsSpecial)
                        for (const CommandDef *d = cmdsSpecial; d->text; d++)
                            n++;
                }

                {
                    CommandsList it(*cmdsMsg, true);
                    while (++it)
                        n++;
                }
                if (n == 0)
                    return NULL;

                n++;
                CommandDef *cmds = new CommandDef[n];
                memset(cmds, 0, sizeof(CommandDef) * n);
                n = 0;
                if (cmdsSpecial){
                    for (const CommandDef *d = cmdsSpecial; d->text; d++){
                        cmds[n] = *d;
                        cmds[n].id = CmdMsgSpecial + n;
                        n++;
                    }
                }
                CommandDef *c;
                CommandsList it(*cmdsMsg, true);
                while ((c = ++it) != NULL){
                    CommandDef cmd = *c;
                    cmd.menu_id = MenuMsgCommand;
                    cmd.param   = msg;
                    Event e(EventCheckState, &cmd);
                    if (!e.process())
                        continue;
                    cmd.flags &= ~COMMAND_CHECK_STATE;
                    cmds[n++] = cmd;
                }
                cmd->param = cmds;
                cmd->flags |= COMMAND_RECURSIVE;
                delete msg;
                return e->param();
            }
            return NULL;
        }
    }
    if (e->type() == EventCommandExec){
        CommandDef *cmd = (CommandDef*)(e->param());
        if ((cmd->param != this) || (cmd->menu_id != MenuMsgView))
            return NULL;
        Message *msg;
        switch (cmd->id){
        case CmdCutHistory:
            msg = currentMessage();
            if (msg){
                History::cut(msg, 0, 0);
                delete msg;
                return e->param();
            }
            return NULL;
        case CmdDeleteMessage:
            msg = currentMessage();
            if (msg){
                History::del(msg);
                delete msg;
                return e->param();
            }
            return NULL;
        case CmdCopy:
            copy();
            return e->param();
        case CmdMsgOpen:
            msg = currentMessage();
            if (msg){
                msg->setFlags(msg->getFlags() | MESSAGE_OPEN);
                Event eOpen(EventOpenMessage, &msg);
                eOpen.process();
                delete msg;
                return e->param();
            }
            return NULL;
        default:
            msg = currentMessage();
            if (msg){
                if (cmd->id >= CmdMsgSpecial){
                    MessageDef *mdef = NULL;
                    unsigned type = msg->baseType();
                    CommandDef *msgCmd = CorePlugin::m_plugin->messageTypes.find(type);
                    if (msgCmd)
                        mdef = (MessageDef*)(msgCmd->param);
                    const CommandDef *cmds = NULL;
                    if (mdef){
                        if (msg->getFlags() & MESSAGE_RECEIVED){
                            cmds = mdef->cmdReceived;
                        }else{
                            cmds = mdef->cmdSent;
                        }
                    }

                    if (cmds){
                        unsigned n = cmd->id - CmdMsgSpecial;
                        for (const CommandDef *d = cmds; d->text; d++){
                            if (n-- == 0){
                                CommandDef cmd = *d;
                                cmd.param = msg;
                                Event eCmd(EventCommandExec, &cmd);
                                eCmd.process();
                                return e->param();
                            }
                        }
                    }
                }
                Command c;
                c->id = cmd->id;
                c->menu_id = MenuMsgCommand;
                c->param = msg;
                Event e(EventCommandExec, c);
                void *res = e.process();
                delete msg;
                return res;
            }
            return NULL;
        }
    }
    return NULL;
}
Пример #18
0
void MsgViewBase::update()
{
    if (m_updated.empty())
        return;
    unsigned i;
    for (i = 0; i < (unsigned)paragraphs(); i++){
        QString s = text(i);
        int n = s.find(MSG_ANCHOR);
        if (n < 0)
            continue;
        s = s.mid(n + strlen(MSG_ANCHOR));
        n = s.find("\"");
        if (n < 0)
            continue;
        string client;
        unsigned id = messageId(s.left(n), client);
        list<Msg_Id>::iterator it;
        for (it = m_updated.begin(); it != m_updated.end(); ++it){
            if (((*it).id == id) && ((*it).client == client))
                break;
        }
        if (it != m_updated.end())
            break;
    }
    m_updated.clear();
    if (i >= (unsigned)paragraphs())
        return;
    QPoint p = QPoint(0, 0);
    p = mapToGlobal(p);
    p = viewport()->mapFromGlobal(p);
    int x, y;
    viewportToContents(p.x(), p.y(), x, y);
    int para;
    int pos = charAt(QPoint(x, y), &para);
    p = QPoint(0, viewport()->height());
    p = viewport()->mapToGlobal(p);
    p = mapFromGlobal(p);
    if (p.y() + 2 == height())
        pos = -1;
    unsigned start = i;
    list<Msg_Id> msgs;
    for (; i < (unsigned)paragraphs(); i++){
        QString s = text(i);
        int n = s.find(MSG_ANCHOR);
        if (n < 0)
            continue;
        s = s.mid(n + strlen(MSG_ANCHOR));
        n = s.find("\"");
        if (n < 0)
            continue;
        string client;
        unsigned id = messageId(s.left(n), client);
        list<Msg_Id>::iterator it;
        for (it = msgs.begin(); it != msgs.end(); ++it){
            if (((*it).id == id) && ((*it).client == client))
                break;
        }
        if (it != msgs.end())
            continue;
        Msg_Id m_id;
        m_id.id     = id;
        m_id.client = client;
        msgs.push_back(m_id);
    }
    int paraFrom, indexFrom;
    int paraTo, indexTo;
    getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
    setReadOnly(false);
    setSelection(start, 0, paragraphs() - 1, 0xFFFF);
    removeSelectedText();
    setReadOnly(true);
    QString text;
    for (list<Msg_Id>::iterator it = msgs.begin(); it != msgs.end(); ++it){
        Message *msg = History::load((*it).id, (*it).client.c_str(), m_id);
        if (msg == NULL)
            continue;
        bool bUnread = false;
        for (list<msg_id>::iterator itu = CorePlugin::m_plugin->unread.begin(); itu != CorePlugin::m_plugin->unread.end(); ++itu){
            msg_id &m = (*itu);
            if ((m.contact == msg->contact()) &&
                    (m.id == msg->id()) &&
                    (m.client == msg->client())){
                bUnread = true;
                break;
            }
        }
        text += messageText(msg, bUnread);
    }
    append(text);
    if (!CorePlugin::m_plugin->getOwnColors())
        setBackground(0);
    if ((paraFrom != paraTo) || (indexFrom != indexTo))
        setSelection(paraFrom, indexFrom, paraTo, indexTo);
    if (pos == -1){
        scrollToBottom();
    }else{
        setCursorPosition(para, pos);
        ensureCursorVisible();
    }
}
Пример #19
0
void MultilineTextEdit::drawWhitespaces()
{
  // prepare a rectangle to store the width of the whitespace found
  QRect space;
  // get the painter for the text area
  QPainter pa(viewport());

  // get a sane color
  QColor col=colorGroup().link();
  // and a brush of the same color
  QBrush fillBrush(col);
  // use it for line drawing
  pa.setPen(col);
  // and for filling
  pa.setBrush(fillBrush);

  // prepare the carriage return coordinates array
  QPointArray cr(4);
  // and the tabulator arrow coordinate array
  QPointArray tab(7);

  // whitespace expression
  QRegExp regex("\\s");

  // line buffer
  QString line;

  int x,y,pos,paragraph;
  // start looking in every paragraph
  for(paragraph=0;paragraph<paragraphs();paragraph++)
  {
    // get paragraph text
    line=text(paragraph);
    // start looking for whitespaces from the beginning
    pos=0;
    while((pos=line.find(regex,pos))!=-1)
    {
      // whitespace found is not the carriage return at the end of the line?
      if(pos<((int)line.length()-1))
      {
        // get whitespace rectangle
        space=mapToView(paragraph,pos);
        // extract x/y coordinates
        x=space.width()/2-1+space.x();
        y=space.height()/2-1+space.y();

        // if it was a regular blank ...
        if(regex.cap(0)==" ")
        {
          // dras a simple small square
          pa.drawRect(x-1,y,2,2);
        }
        // if it was a tabulator
        else if(regex.cap(0)=="\t")
        {
          // calculate arrow points and draw them filled
          tab.putPoints(0,7, x-5,y-1, x,y-1, x,y-3, x+3,y, x,y+3, x,y+1, x-5,y+1);
          pa.drawPolygon(tab);
        }
      }
      // go to next position and resume looking for more whitespaces
      pos++;
    } // while

    // end of line, get carriage return position
    space=mapToView(paragraph,line.length()-1);
    // extract x/y positions
    x=space.width()/2-1+space.x();
    y=space.height()/2-1+space.y();
    // calculate carriage return triangle coordinates and draw them filled
    cr.putPoints(0,4, x,y, x,y+1, x+4, y+5, x+4, y-4);
    pa.drawPolygon(cr);
  } // for
}
Пример #20
0
void MsgViewBase::update()
{
    if (m_updated.empty())
        return;
    unsigned i;
    for (i = 0; i < (unsigned)paragraphs(); i++){
        QString s = text(i);
        int n = s.find(MSG_ANCHOR);
        if (n < 0)
            continue;
        s = s.mid(n + strlen(MSG_ANCHOR));
        n = s.find("\"");
        if (n < 0)
            continue;
        string client;
        unsigned id = messageId(s.left(n), client);
        list<Msg_Id>::iterator it;
        for (it = m_updated.begin(); it != m_updated.end(); ++it){
            if (((*it).id == id) && ((*it).client == client))
                break;
        }
        if (it != m_updated.end())
            break;
    }
    m_updated.clear();
    if (i >= (unsigned)paragraphs())
        return;
    int x = contentsX();
    int y = contentsY();
    viewport()->setUpdatesEnabled(false);

    unsigned start = i;
    list<Msg_Id> msgs;
    for (; i < (unsigned)paragraphs(); i++){
        QString s = text(i);
        int n = s.find(MSG_ANCHOR);
        if (n < 0)
            continue;
        s = s.mid(n + strlen(MSG_ANCHOR));
        n = s.find("\"");
        if (n < 0)
            continue;
        string client;
        unsigned id = messageId(s.left(n), client);
        list<Msg_Id>::iterator it;
        for (it = msgs.begin(); it != msgs.end(); ++it){
            if (((*it).id == id) && ((*it).client == client))
                break;
        }
        if (it != msgs.end())
            continue;
        Msg_Id m_id;
        m_id.id     = id;
        m_id.client = client;
        msgs.push_back(m_id);
    }
    int paraFrom, indexFrom;
    int paraTo, indexTo;
    getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
    setReadOnly(false);
    setSelection(start, 0, paragraphs() - 1, 0xFFFF, 0);
    removeSelectedText();
    setReadOnly(true);
    QString text;
    for (list<Msg_Id>::iterator it = msgs.begin(); it != msgs.end(); ++it){
        Message *msg = History::load((*it).id, (*it).client.c_str(), m_id);
        if (msg == NULL)
            continue;
        bool bUnread = false;
        for (list<msg_id>::iterator itu = CorePlugin::m_plugin->unread.begin(); itu != CorePlugin::m_plugin->unread.end(); ++itu){
            msg_id &m = (*itu);
            if ((m.contact == msg->contact()) &&
                    (m.id == msg->id()) &&
                    (m.client == msg->client())){
                bUnread = true;
                break;
            }
        }
        text += messageText(msg, bUnread);
    }
    viewport()->setUpdatesEnabled(true);
    append(text);
    if (!CorePlugin::m_plugin->getOwnColors())
        setBackground(i);
    if ((paraFrom != paraTo) || (indexFrom != indexTo))
        setSelection(paraFrom, indexFrom, paraTo, indexTo, 0);
    TextShow::sync();
    setContentsPos(x, y);
    viewport()->repaint();
}
Пример #21
0
void InsetListings::latex(otexstream & os, OutputParams const & runparams) const
{
	string param_string = params().params();
	// NOTE: I use {} to quote text, which is an experimental feature
	// of the listings package (see page 25 of the manual)
	bool const isInline = params().isInline();
	// get the paragraphs. We can not output them directly to given odocstream
	// because we can not yet determine the delimiter character of \lstinline
	docstring code;
	docstring uncodable;
	ParagraphList::const_iterator par = paragraphs().begin();
	ParagraphList::const_iterator end = paragraphs().end();

	bool encoding_switched = false;
	Encoding const * const save_enc = runparams.encoding;

	if (!runparams.isFullUnicode()
	    && !runparams.encoding->hasFixedWidth()) {
		// We need to switch to a singlebyte encoding, since the
		// listings package cannot deal with multi-byte-encoded
		// glyphs (not needed with full-unicode aware backends
		// such as XeTeX).
		Language const * const outer_language =
			(runparams.local_font != 0) ?
				runparams.local_font->language()
				: buffer().params().language;
		// We try if there's a singlebyte encoding for the current
		// language; if not, fall back to latin1.
		Encoding const * const lstenc =
			(outer_language->encoding()->hasFixedWidth()) ?
				outer_language->encoding() 
				: encodings.fromLyXName("iso8859-1");
		switchEncoding(os.os(), buffer().params(), runparams, *lstenc, true);
		runparams.encoding = lstenc;
		encoding_switched = true;
	}

	while (par != end) {
		pos_type siz = par->size();
		bool captionline = false;
		for (pos_type i = 0; i < siz; ++i) {
			if (i == 0 && par->isInset(i) && i + 1 == siz)
				captionline = true;
			// ignore all struck out text and (caption) insets
			if (par->isDeleted(i) || par->isInset(i))
				continue;
			char_type c = par->getChar(i);
			// we can only output characters covered by the current
			// encoding!
			try {
				if (runparams.encoding->encodable(c))
					code += c;
				else if (runparams.dryrun) {
					code += "<" + _("LyX Warning: ")
					   + _("uncodable character") + " '";
					code += docstring(1, c);
					code += "'>";
 				} else
					uncodable += c;
			} catch (EncodingException & /* e */) {
 				if (runparams.dryrun) {
					code += "<" + _("LyX Warning: ")
					   + _("uncodable character") + " '";
					code += docstring(1, c);
					code += "'>";
 				} else
					uncodable += c;
			}
		}
		++par;
		// for the inline case, if there are multiple paragraphs
		// they are simply joined. Otherwise, expect latex errors.
		if (par != end && !isInline && !captionline)
			code += "\n";
	}
	if (isInline) {
		char const * delimiter = lstinline_delimiters;
		for (; delimiter != '\0'; ++delimiter)
			if (!contains(code, *delimiter))
				break;
		// This code piece contains all possible special character? !!!
		// Replace ! with a warning message and use ! as delimiter.
		if (*delimiter == '\0') {
			docstring delim_error = "<" + _("LyX Warning: ")
				+ _("no more lstline delimiters available") + ">";
			code = subst(code, from_ascii("!"), delim_error);
			delimiter = lstinline_delimiters;
			if (!runparams.dryrun) {
				// FIXME: warning should be passed to the error dialog
				frontend::Alert::warning(_("Running out of delimiters"),
				_("For inline program listings, one character must be reserved\n"
				  "as a delimiter. One of the listings, however, uses all available\n"
				  "characters, so none is left for delimiting purposes.\n"
				  "For the time being, I have replaced '!' by a warning, but you\n"
				  "must investigate!"));
			}
		}
		if (param_string.empty())
			os << "\\lstinline" << *delimiter;
		else
			os << "\\lstinline[" << from_utf8(param_string) << "]" << *delimiter;
                os << code
                   << *delimiter;
	} else {
		OutputParams rp = runparams;
		rp.moving_arg = true;
		docstring const caption = getCaption(rp);
		if (param_string.empty() && caption.empty())
			os << breakln << "\\begin{lstlisting}\n";
		else {
			os << breakln << "\\begin{lstlisting}[";
			if (!caption.empty()) {
				os << "caption={" << caption << '}';
				if (!param_string.empty())
					os << ',';
			}
			os << from_utf8(param_string) << "]\n";
		}
		os << code << breakln << "\\end{lstlisting}\n";
	}

	if (encoding_switched){
		// Switch back
		switchEncoding(os.os(), buffer().params(), runparams, *save_enc, true);
		runparams.encoding = save_enc;
	}

	if (!uncodable.empty()) {
		// issue a warning about omitted characters
		// FIXME: should be passed to the error dialog
		frontend::Alert::warning(_("Uncodable characters in listings inset"),
			bformat(_("The following characters in one of the program listings are\n"
				  "not representable in the current encoding and have been omitted:\n%1$s."),
			uncodable));
	}
}
Пример #22
0
void *MsgViewBase::processEvent(Event *e)
{
    if (e->type() == EventMessageRead){
        Message *msg = (Message*)(e->param());
        if (msg->contact() != m_id)
            return NULL;
        for (unsigned i = 0; i < (unsigned)paragraphs(); i++){
            QString s = text(i);
            int n = s.find(MSG_HREF);
            if (n < 0)
                continue;
            s = s.mid(n + strlen(MSG_HREF));
            n = s.find("\"");
            if (n < 0)
                continue;
            s = s.left(n);
            unsigned id = atol(getToken(s, ',').latin1());
            if (id != msg->id())
                continue;
            getToken(s, ',');
            if (s != msg->client())
                continue;
            int paraFrom, indexFrom;
            int paraTo, indexTo;
            getSelection(&paraFrom, &indexFrom, &paraTo, &indexTo);
            setSelection(i, 0, i, 0xFFFF);
            setBold(false);
            if ((paraFrom == -1) && (paraTo == -1)){
                removeSelection();
                scrollToBottom();
            }else{
                setSelection(paraFrom, indexFrom, paraTo, indexTo);
            }
            break;
        }
        return NULL;
    }
    if (e->type() == EventHistoryConfig){
        unsigned id = (unsigned)(e->param());
        if (id && (id != m_id))
            return NULL;
        QString t;
        for (unsigned i = 0; i < (unsigned)paragraphs(); i++){
            QString s = text(i);
            int n = s.find(MSG_HREF);
            if (n < 0)
                continue;
            s = s.mid(n + strlen(MSG_HREF));
            n = s.find("\"");
            if (n < 0)
                continue;
            s = s.left(n);
            unsigned id = atol(getToken(s, ',').latin1());
            getToken(s, ',');
            Message *msg = History::load(id, s.utf8(), m_id);
            if (msg == NULL)
                continue;
            t += messageText(msg);
            delete msg;
        }
        QPoint p = QPoint(0, height());
        p = mapToGlobal(p);
        p = viewport()->mapFromGlobal(p);
        int x, y;
        viewportToContents(p.x(), p.y(), x, y);
        int para;
        int pos = charAt(QPoint(x, y), &para);
        setText(t);
        setBackground(0);
        if (pos == -1){
            scrollToBottom();
        }else{
            setCursorPosition(para, pos);
            ensureCursorVisible();
        }
    }
    if (e->type() == EventCheckState){
        CommandDef *cmd = (CommandDef*)(e->param());
        if ((cmd->param != this) || (cmd->menu_id != MenuMsgView))
            return NULL;
        Message *msg;
        switch (cmd->id){
        case CmdCopy:
            cmd->flags &= ~(COMMAND_DISABLED | COMMAND_CHECKED);
            if (!hasSelectedText())
                cmd->flags |= COMMAND_DISABLED;
            return e->param();
        case CmdMsgOpen:
            msg = currentMessage();
            if (msg){
                unsigned type = msg->type();
                delete msg;
                for (;;){
                    CommandDef *def = CorePlugin::m_plugin->messageTypes.find(type);
                    if (def == NULL){
                        return NULL;
                    }
                    MessageDef *mdef = (MessageDef*)(def->param);
                    if (mdef->base_type){
                        type = mdef->base_type;
                        continue;
                    }
                    cmd->icon = def->icon;
                    cmd->flags &= ~COMMAND_CHECKED;
                    return e->param();
                }
            }
            return NULL;
        case CmdMsgSpecial:
            msg = currentMessage();
            if (msg){
                Event eMenu(EventGetMenuDef, (void*)MenuMsgCommand);
                CommandsDef *cmdsMsg = (CommandsDef*)(eMenu.process());

                unsigned n = 0;
                MessageDef *mdef = NULL;
                if (msg->getFlags() & MESSAGE_RECEIVED){
                    unsigned type = msg->type();
                    for (;;){
                        CommandDef *msgCmd = CorePlugin::m_plugin->messageTypes.find(type);
                        if (msgCmd == NULL)
                            break;
                        mdef = (MessageDef*)(msgCmd->param);
                        if (mdef->base_type == 0)
                            break;
                        type = mdef->base_type;
                    }
                }
                if (mdef && mdef->cmd){
                    for (const CommandDef *d = mdef->cmd; d->text; d++)
                        n++;
                }

                {
                    CommandsList it(*cmdsMsg, true);
                    while (++it)
                        n++;
                }
                if (n == 0)
                    return NULL;

                n++;
                CommandDef *cmds = new CommandDef[n];
                memset(cmds, 0, sizeof(CommandDef) * n);
                n = 0;
                if (mdef && mdef->cmd){
                    for (const CommandDef *d = mdef->cmd; d->text; d++){
                        cmds[n] = *d;
                        cmds[n].id = CmdMsgSpecial + n;
                        n++;
                    }
                }
                CommandDef *c;
                CommandsList it(*cmdsMsg, true);
                while ((c = ++it) != NULL){
                    CommandDef cmd = *c;
                    cmd.menu_id = MenuMsgCommand;
                    cmd.param   = msg;
                    Event e(EventCheckState, &cmd);
                    if (!e.process())
                        continue;
                    cmd.flags &= ~COMMAND_CHECK_STATE;
                    cmds[n++] = cmd;
                }
                cmd->param = cmds;
                cmd->flags |= COMMAND_RECURSIVE;
                delete msg;
                return e->param();
            }
            return NULL;
        }
    }
    if (e->type() == EventCommandExec){
        CommandDef *cmd = (CommandDef*)(e->param());
        if ((cmd->param != this) || (cmd->menu_id != MenuMsgView))
            return NULL;
        Message *msg;
        switch (cmd->id){
        case CmdCopy:
            copy();
            return e->param();
        case CmdMsgOpen:
            msg = currentMessage();
            if (msg){
                Event eOpen(EventOpenMessage, msg);
                eOpen.process();
                delete msg;
                return e->param();
            }
            return NULL;
        default:
            msg = currentMessage();
            if (msg){
                if (cmd->id >= CmdMsgSpecial){
                    MessageDef *mdef = NULL;
                    unsigned type = msg->type();
                    for (;;){
                        CommandDef *msgCmd = CorePlugin::m_plugin->messageTypes.find(type);
                        if (msgCmd == NULL)
                            break;
                        mdef = (MessageDef*)(msgCmd->param);
                        if (mdef->base_type == 0)
                            break;
                        type = mdef->base_type;
                    }
                    if (mdef && mdef->cmd){
                        unsigned n = cmd->id - CmdMsgSpecial;
                        for (const CommandDef *d = mdef->cmd; d->text; d++){
                            if (n-- == 0){
                                CommandDef cmd = *d;
                                cmd.param = msg;
                                Event eCmd(EventCommandExec, &cmd);
                                eCmd.process();
                                return e->param();
                            }
                        }
                    }
                }
                Command c;
                c->id = cmd->id;
                c->menu_id = MenuMsgCommand;
                c->param = msg;
                Event e(EventCommandExec, c);
                void *res = e.process();
                delete msg;
                return res;
            }
            return NULL;
        }
    }
    return NULL;
}
Пример #23
0
void InsetInfo::updateInfo()
{
	BufferParams const & bp = buffer().params();	

	switch (type_) {
	case UNKNOWN_INFO:
		error("Unknown Info: %1$s");
		break;
	case SHORTCUT_INFO:
	case SHORTCUTS_INFO: {
		FuncRequest const func = lyxaction.lookupFunc(name_);
		if (func.action() == LFUN_UNKNOWN_ACTION) {
			error("Unknown action %1$s");
			break;
		}
		KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(func);
		if (bindings.empty()) {
			// It is impropriate to use error() for undefined shortcut
			setText(_("undefined"));
			break;
		}
		if (type_ == SHORTCUT_INFO)
			setText(bindings.begin()->print(KeySequence::Portable));
		else
			setText(theTopLevelKeymap().printBindings(func, KeySequence::Portable));
		break;
	}
	case LYXRC_INFO: {
		ostringstream oss;
		if (name_.empty()) {
			setText(_("undefined"));
			break;
		}
		lyxrc.write(oss, true, name_);
		string result = oss.str();
		if (result.size() < 2) {
			setText(_("undefined"));
			break;
		}
		string::size_type loc = result.rfind("\n", result.size() - 2);
		loc = loc == string::npos ? 0 : loc + 1;
		if (result.size() < loc + name_.size() + 1
			  || result.substr(loc + 1, name_.size()) != name_) {
			setText(_("undefined"));
			break;
		}
		// remove leading comments and \\name and space
		result = result.substr(loc + name_.size() + 2);
		
		// remove \n and ""
		result = rtrim(result, "\n");
		result = trim(result, "\"");
		setText(from_utf8(result));
		break;
	}
	case PACKAGE_INFO:
		// check in packages.lst
		setText(LaTeXFeatures::isAvailable(name_) ? _("yes") : _("no"));
		break;

	case TEXTCLASS_INFO: {
		// name_ is the class name
		LayoutFileList const & list = LayoutFileList::get();
		bool available = false;
		if (list.haveClass(name_))
			available = list[name_].isTeXClassAvailable();
		setText(available ? _("yes") : _("no"));
		break;
	}
	case MENU_INFO: {
		docstring_list names;
		FuncRequest const func = lyxaction.lookupFunc(name_);
		if (func.action() == LFUN_UNKNOWN_ACTION) {
			error("Unknown action %1$s");
			break;
		}
		// iterate through the menubackend to find it
		if (!theApp()->searchMenu(func, names)) {
			error("No menu entry for action %1$s");
			break;
		}
		// if found, return its path.
		clear();
		Paragraph & par = paragraphs().front();
		Font const f(inherit_font, buffer().params().language);
		//Font fu = f;
		//fu.fontInfo().setUnderbar(FONT_ON);
		docstring_list::const_iterator beg = names.begin();
		docstring_list::const_iterator end = names.end();
		for (docstring_list::const_iterator it = beg ; 
		     it != end ; ++it) {
			// do not insert > for the top level menu item
			if (it != beg)
				par.insertInset(par.size(), new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR),
						Change(Change::UNCHANGED));
			//FIXME: add proper underlines here. This
			// involves rewriting searchMenu used above to
			// return a vector of menus. If we do not do
			// that, we might as well use below
			// Paragraph::insert on each string (JMarc)
			for (size_type i = 0; i != it->length(); ++i)
				par.insertChar(par.size(), (*it)[i], 
					       f, Change(Change::UNCHANGED));
		}
		break;
	}
	case ICON_INFO: {
		FuncRequest func = lyxaction.lookupFunc(name_);
		docstring icon_name = theApp()->iconName(func, true);
		//FIXME: We should use the icon directly instead of
		// going through FileName. The code below won't work
		// if the icon is embedded in the executable through
		// the Qt resource system.
		FileName file(to_utf8(icon_name));
		if (!file.exists())
			break;
		InsetGraphics * inset = new InsetGraphics(buffer_);
		InsetGraphicsParams igp;
		igp.filename = file;
		inset->setParams(igp);
		clear();
		paragraphs().front().insertInset(0, inset, 
						 Change(Change::UNCHANGED));
		break;
	}
	case BUFFER_INFO: {
		if (name_ == "name") {
			setText(from_utf8(buffer().fileName().onlyFileName()));
			break;
		}
		if (name_ == "path") {
			setText(from_utf8(buffer().filePath()));
			break;
		}
		if (name_ == "class") {
			setText(from_utf8(bp.documentClass().name()));
			break;
		}
		
		// everything that follows is for version control.
		// nothing that isn't version control should go below this line.
		if (!buffer().lyxvc().inUse()) {
			setText(_("No version control"));
			break;
		}
		LyXVC::RevisionInfo itype = LyXVC::Unknown;
		if (name_ == "vcs-revision")
			itype = LyXVC::File;
		else if (name_ == "vcs-tree-revision")
			itype = LyXVC::Tree;
		else if (name_ == "vcs-author")
			itype = LyXVC::Author;
		else if (name_ == "vcs-time")
			itype = LyXVC::Time;
		else if (name_ == "vcs-date")
			itype = LyXVC::Date;
		string binfo = buffer().lyxvc().revisionInfo(itype);
		if (binfo.empty())
			setText(bformat(_("[[%1$s unknown]]"), from_utf8(name_)));
		else
			setText(from_utf8(binfo));
		break;
	}
	case LYX_INFO:
		if (name_ == "version")
			setText(from_ascii(PACKAGE_VERSION));
		break;
	}
}