void QsciEditor::toggleCase() { int lF, iF, lT, iT; getSelection( &lF, &iF, &lT, &iT ); if ( not hasSelectedText() ) return; QString txt = selectedText(); QString newTxt; bool caps = true; Q_FOREACH( QChar ch, txt ) if ( ch.isLetter() ) caps &= ch.isUpper(); if ( caps ) newTxt = txt.toLower(); else newTxt = txt.toUpper(); removeSelectedText(); insert( newTxt ); setSelection( lF, iF, lT, iT ); };
void QsciEditor::pasteAction() { if ( hasSelectedText() ) removeSelectedText(); SendScintilla( SCI_PASTE ); };
void TextShow::cut() { if (isReadOnly()) return; if (hasSelectedText()) { copy(); removeSelectedText(); } }
/** * Set the text on the given line, something I feel is missing from the QScintilla API. Note * that like QScintilla line numbers start from 0 * @param lineno :: A zero-based index representing the linenumber, * @param txt :: The text to insert at the given line * @param index :: The position of text in a line number,default value is zero */ void ScriptEditor::setText(int lineno, const QString& txt,int index) { int line_length = txt.length(); // Index is max of the length of current/new text setSelection(lineno, index, lineno, qMax(line_length, this->text(lineno).length())); removeSelectedText(); insertAt(txt, lineno, index); setCursorPosition(lineno, line_length); }
void TextShow::startDrag() { QDragObject *drag = new QTextDrag(selectedText(), viewport()); if ( isReadOnly() ) { drag->dragCopy(); } else { if ( drag->drag() && QDragObject::target() != this && QDragObject::target() != viewport() ) removeSelectedText(); } }
void pEditor::replace( const QString& replaceStr ) { #if USE_QSCINTILLA_SEARCH_ENGINE == 1 QsciScintilla::replace( replaceStr ); #else if ( !mSearchState.inProgress ) { return; } static QRegExp rxd( "\\$(\\d+)" ); rxd.setMinimal( true ); const bool isRE = mSearchState.flags & SCFIND_REGEXP; QRegExp& rx = mSearchState.rx; const QStringList captures = rx.capturedTexts(); QString text = replaceStr; const long start = SendScintilla( SCI_GETSELECTIONSTART ); SendScintilla( SCI_TARGETFROMSELECTION ); // remove selection removeSelectedText(); // compute replace text if ( isRE && captures.count() > 1 ) { int pos = 0; while ( ( pos = rxd.indexIn( text, pos ) ) != -1 ) { const int id = rxd.cap( 1 ).toInt(); if ( id < 0 || id >= captures.count() ) { pos += rxd.matchedLength(); continue; } // update replace text with partial occurrences text.replace( pos, rxd.matchedLength(), captures.at( id ) ); // next pos += captures.at( id ).length(); } } // insert replace text const long len = text.toUtf8().length(); // scintilla position are count from qbytearray data: ie: non ascii leter are 2 or more bits. insert( text ); // Reset the selection. SendScintilla( SCI_SETSELECTIONSTART, start ); SendScintilla( SCI_SETSELECTIONEND, start +len ); if ( mSearchState.forward ) { mSearchState.startpos = start +len; } #endif }
void QMultiLineEdit::backspace() { if ( document()->hasSelection( QTextDocument::Standard ) ) { removeSelectedText(); return; } if ( !textCursor()->paragraph()->prev() && textCursor()->atParagStart() ) return; doKeyboardAction( ActionBackspace ); }
void SciDoc::replaceSelectedText(const QString& text, bool cursorToTheEnd) { if ( int_->curEdit_ == NULL ) return; int line1, col1, line2, col2; if ( !int_->curEdit_->hasSelectedText() ) { // no selected text - just insert the text we have if ( !text.isEmpty() ) { getCursorPos(line1, col1); int_->curEdit_->beginUndoAction(); insertText(text); if ( cursorToTheEnd ) { moveCursorToTheEnd(line1, col1, text); } int_->curEdit_->endUndoAction(); } } else { int_->curEdit_->getSelection(&line1, &col1, &line2, &col2); int_->curEdit_->beginUndoAction(); // hack! hack! hack! disconnect(int_->edit1_, SIGNAL(textChanged()), this, SIGNAL(textChanged())); removeSelectedText(); // hack! hack! hack! connect(int_->edit1_, SIGNAL(textChanged()), this, SIGNAL(textChanged())); if ( text.isEmpty() ) { // need to emit the signal manually emit textChanged(); } else { insertText(text); } if ( cursorToTheEnd ) { moveCursorToTheEnd(line1, col1, text); } else { int_->curEdit_->setCursorPosition(line1, col1); } int_->curEdit_->endUndoAction(); } }
void SqlEditorWidget::keyPressEvent(QKeyEvent * e) { // handle editor shortcuts with TAB // It uses qscintilla lowlevel API to handle "word unde cursor" if (m_prefs->useShortcuts() && e->key() == Qt::Key_Tab) { int pos = SendScintilla(SCI_GETCURRENTPOS); int start = SendScintilla(SCI_WORDSTARTPOSITION, pos,true); int end = SendScintilla(SCI_WORDENDPOSITION, pos, true); SendScintilla(SCI_SETSELECTIONSTART, start, true); SendScintilla(SCI_SETSELECTIONEND, end, true); QString key(selectedText()); bool done = false; if (m_prefs->shortcuts().contains(key)) { removeSelectedText(); insert(m_prefs->shortcuts().value(key).toString()); SendScintilla(SCI_SETCURRENTPOS, SendScintilla(SCI_GETCURRENTPOS) + m_prefs->shortcuts().value(key).toString().length()); done = true; } pos = SendScintilla(SCI_GETCURRENTPOS); SendScintilla(SCI_SETSELECTIONSTART, pos,true); SendScintilla(SCI_SETSELECTIONEND, pos, true); if (done) return; } // Manual popup with code completion if (m_prefs->codeCompletion() && (e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space) { autoCompleteFromAll(); return; } QsciScintilla::keyPressEvent(e); }
//need to use pos for insert, not cur, so forget cur altogether void KEdit::corrected (const QString &originalword, const QString &newword, unsigned int pos) { //we'll reselect the original word in case the user has played with //the selection in eframe or the word was auto-replaced unsigned int l = 0; unsigned int cnt = 0; if( newword != originalword ) { posToRowCol (pos, l, cnt); setSelection(l, cnt, l, cnt+originalword.length()); setReadOnly ( false ); removeSelectedText(); insert(newword); setReadOnly ( true ); } else { deselect(); } }
void QsciEditor::deleteAction() { if ( hasSelectedText() ) removeSelectedText(); };
template<> void QConsoleWidget::_pf<void, SetToCommand>( QConsoleWidget * thisp,QList<QConsoleWidgetCommand> command ) { //TODO: ... auto tc = thisp->textCursor(); tc.setPosition( thisp->promptEndPos_); tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor,0); thisp->setTextCursor( tc ); if ( command.empty() ) { tc.removeSelectedText(); thisp->setTextCursor(tc); return ; } auto tryAddReturn = [](const QString & str)->QString { if (str.isEmpty()) { return str; } if (str.endsWith("\n")) { return str; } return (str + "\n"); }; if (command.size()==1 ) { thisp->insertPlainText( command.begin()->command ); } else if (command.size() == 2) { auto b0 = command.begin(); auto b1 = b0 + 1; if (b1->command.isEmpty()) { thisp->insertPlainText(b0->command); } else { thisp->insertPlainText(tryAddReturn(b0->command)); thisp->insertPlainText(b1->command); } } else { auto b = command.begin(); auto e = command.end() - 2; for (;b!=e;++b ) { const QString & temp = tryAddReturn( b->command ); if (temp.isEmpty() == false) { thisp->insertPlainText(temp); } } b = e; e = e + 1; if (e->command.isEmpty()) { thisp->insertPlainText(b->command); } else { thisp->insertPlainText(tryAddReturn(b->command)); thisp->insertPlainText(e->command); } } }
template<> void QConsoleWidget::_pf<void, InitActions>( QConsoleWidget * thisp) { //TODO: inin mouse actions static const QString cut_ = trUtf8(u8"剪贴"); static const QString paste_ = trUtf8(u8"粘贴"); static const QString delect_ = trUtf8(u8"删除"); auto & mas_ = thisp->mouseActions; mas_[INDEX_SELECT_COPY] = new QAction(trUtf8(u8"复制"),thisp); mas_[INDEX_SELECT_ALL] = new QAction(trUtf8(u8"全选"), thisp); mas_[INDEX_SELECT_DELET] = new QAction(delect_, thisp); mas_[INDEX_SELECT_CUT] = new QAction(cut_, thisp); mas_[INDEX_SELECT_PASTE] = new QAction(paste_, thisp); mas_[INDEX_ASELECT_DELET] = new QAction(delect_, thisp); mas_[INDEX_ASELECT_CUT] = new QAction(cut_, thisp); mas_[INDEX_ASELECT_PASTE] = new QAction(paste_, thisp); typedef void(QAction::*AT)(bool); mas_[INDEX_SELECT_ALL]->connect( mas_[INDEX_SELECT_ALL], AT(&QAction::triggered), [thisp](bool) {thisp->selectAll(); } ); mas_[INDEX_SELECT_COPY]->connect( mas_[INDEX_SELECT_COPY], AT(&QAction::triggered), [thisp](bool) {thisp->copy(); } ); mas_[INDEX_SELECT_DELET]->connect( mas_[INDEX_SELECT_DELET], AT(&QAction::triggered), [thisp](bool) { auto tc = thisp->textCursor(); tc.removeSelectedText(); thisp->setTextCursor(tc); } ); mas_[INDEX_SELECT_CUT]->connect( mas_[INDEX_SELECT_CUT], AT(&QAction::triggered), [thisp](bool) {thisp->cut(); } ); mas_[INDEX_SELECT_PASTE]->connect( mas_[INDEX_SELECT_PASTE], AT(&QAction::triggered), [thisp](bool) {thisp->paste(); } ); mas_[INDEX_ASELECT_DELET]->connect( mas_[INDEX_ASELECT_DELET], AT(&QAction::triggered), [thisp](bool) { _pf<void, ResetSelect>(thisp); auto tc = thisp->textCursor(); tc.removeSelectedText(); thisp->setTextCursor(tc); } ); mas_[INDEX_ASELECT_CUT]->connect( mas_[INDEX_ASELECT_CUT], AT(&QAction::triggered), [thisp](bool) { _pf<void, ResetSelect>(thisp); thisp->cut(); } ); mas_[INDEX_ASELECT_PASTE]->connect( mas_[INDEX_ASELECT_PASTE], AT(&QAction::triggered), [thisp](bool) { _pf<void, ResetSelect>(thisp); thisp->paste(); } ); }
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 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 *MsgViewBase::processEvent(Event *e) { 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; s = s.left(n); unsigned id = atol(getToken(s, ',').latin1()); if (id != msg->id()) continue; getToken(s, ','); if (s != msg->client()) continue; unsigned j; for (j = i + 1; j < (unsigned)paragraphs(); j++){ QString s = text(j); if (s.find(MSG_ANCHOR) >= 0) break; } int paraFrom, indexFrom; int paraTo, indexTo; getSelection(¶From, &indexFrom, ¶To, &indexTo); setSelection(i, 0, j - 1, 0xFFFF); setReadOnly(false); removeSelectedText(); setReadOnly(true); if ((paraFrom == -1) && (paraTo == -1)){ scrollToBottom(); }else{ setSelection(paraFrom, indexFrom, paraTo, indexTo); } break; } return NULL; } 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_ANCHOR); if (n < 0) continue; s = s.mid(n + strlen(MSG_ANCHOR)); 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_ANCHOR); if (n < 0) continue; s = s.mid(n + strlen(MSG_ANCHOR)); 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, 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(); } } 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; if (msg->getFlags() & MESSAGE_RECEIVED){ unsigned type = msg->baseType(); CommandDef *msgCmd = CorePlugin::m_plugin->messageTypes.find(type); if (msgCmd ) mdef = (MessageDef*)(msgCmd->param); } 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){ 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); 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; }