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(); }
// <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); } } }
bool TextEdit::isEmpty() { if (paragraphs() < 2){ QString t = text(0); if (textFormat() == QTextEdit::RichText) t = unquoteText(t); return t.isEmpty(); } return false; }
void TextShow::searchAgain(int n) { if (n) return; if (!srchdialog) return; if (srchdialog->get_direction()){ startSearch(paragraphs(), 0); }else{ startSearch(0, 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); }
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); }
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() )); }
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; } } } }
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), ¶); setText(t); if (!CorePlugin::m_plugin->getOwnColors()) setBackground(0); if (pos == -1){ scrollToBottom(); }else{ setCursorPosition(para, pos); ensureCursorVisible(); } }
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(¶From, &indexFrom, ¶To, &indexTo); setSelection(i, 0, i, 0xFFFF); setBold(false); if ((paraFrom == -1) && (paraTo == -1)){ removeSelection(); scrollToBottom(); }else{ setSelection(paraFrom, indexFrom, paraTo, indexTo); } break; } }
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") ); } }
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; }
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]); }
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 ); } } } }
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(); } }
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(); }
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(¶From, &indexFrom, ¶To, &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), ¶); 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(¶From, &indexFrom, ¶To, &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; }
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), ¶); 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(¶From, &indexFrom, ¶To, &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(); } }
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 }
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(¶From, &indexFrom, ¶To, &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(); }
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)); } }
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(¶From, &indexFrom, ¶To, &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), ¶); 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; }
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; } }