/* ================ CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs ================ */ void CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs(void) { int line, lineIndex, length, column, numTabs, i; char buffer[1024]; idStr text; line = LineFromChar(bracedSection[0]); length = GetLine(line, buffer, sizeof(buffer)); for (numTabs = 0; numTabs < length; numTabs++) { if (!idStr::CharIsTab(buffer[numTabs])) { break; } text.Append('\t'); } line = LineFromChar(bracedSection[1]); lineIndex = LineIndex(line); length = GetLine(line, buffer, sizeof(buffer)); column = bracedSection[1] - lineIndex; for (i = 0; i < column; i++) { if (charType[buffer[i]] != CT_WHITESPACE) { return; } } ReplaceText(lineIndex, lineIndex + column, text); bracedSection[1] += numTabs - column; SetSel(bracedSection[1]+1, bracedSection[1]+1); }
void CTWScriptEdit::FormatTextLines(int nLineStart, int nLineEnd) { long nStart = LineIndex(LineFromChar(nLineStart)); long nEnd = LineIndex(LineFromChar(nLineEnd)); nEnd += LineLength(nLineEnd); FormatTextRange(nStart, nEnd); }
void CEmoticonRichEditCtrl::FormatTextLines(int nLineStart, int nLineEnd) { long nStart = LineIndex(LineFromChar(nLineStart)); long nEnd = LineIndex(LineFromChar(nLineEnd)); nEnd += LineLength(nLineEnd); FormatTextRange(nStart, nEnd); }
int JHCEdit::SetSelFullLines(void) { int s, e, sl, el; GetSel(s, e); if (e < 0) return 0; sl = LineFromChar(s); el = LineFromChar(e); s = LineIndex(sl); if (e > LineIndex(el)) e = LineIndex(el) + LineLength(e); else e = LineIndex(el) + LineLength(LineIndex(el)); SetSel(s, e); return (el - sl + 1); }
/* ================ CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection ================ */ bool CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection(CString &name, int &charIndex) const { long selStart, selEnd; int line, column, length; char buffer[1024]; GetSel(selStart, selEnd); charIndex = selStart; line = LineFromChar(selStart); length = GetLine(line, buffer, sizeof(buffer)); column = selStart - LineIndex(line) - 1; do { buffer[column--] = '\0'; } while (charType[buffer[column]] == CT_WHITESPACE); for (length = 0; length < column; length++) { if (charType[buffer[column-length-1]] != CT_NAME) { break; } } if (length > 0) { name = buffer + column - length; return true; } return false; }
int CxEdit::GetCol(void) const { int begin = 0, end = 0; GetSel(begin, end); int nRow = LineFromChar(); int nCol = begin - LineIndex(nRow); return nCol; }
void JHCEdit::SetSelStartLine(int line) { int lc, i; lc = GetLineCount(); if (line < 0) i = lc + line + 1; else i = line; if ((i < 0) || (i > lc)) return; i--; if (i < 0) i = LineFromChar(); i = LineIndex(i); SetSel(i, i); }
void CEditExtn::OnSetFocus(CWnd* pOldWnd) { m_bIsFocused = TRUE; CEdit::OnSetFocus(pOldWnd); if (m_lastposition >= 0) { int iLine = LineFromChar(m_lastposition); LineScroll(iLine); SetSel(m_nStartChar, m_nEndChar); } Invalidate(TRUE); }
int JHCEdit::GetLine(CString& str, int line) { int n, lc, i; lc = GetLineCount(); if (line < 0) i = lc + line + 1; else i = line; if ((i < 0) || (i > lc)) return 0; i--; if (i < 0) i = LineFromChar(); n = LineLength(LineIndex(i)); CEdit::GetLine(i, str.GetBuffer(n+1), n); str.ReleaseBuffer(n); return n; }
void CRichEditExtn::OnSetFocus(CWnd* pOldWnd) { m_bIsFocused = TRUE; CRichEditCtrl::OnSetFocus(pOldWnd); if (m_lastposition >= 0) { int iLine = LineFromChar(m_lastposition); LineScroll(iLine); SetSel(m_nStartChar, m_nEndChar); } SetBackgroundColor(FALSE, m_crefInFocus); Invalidate(TRUE); }
int JHCEdit::GetString(CString& str, int start, int end) { int s, e, ls, le, n; CString ss; if (start < 0) GetSel(s, e); else {s = start; e = end;} if (e < s) e = s; ls = LineFromChar(s); le = LineFromChar(e); str = CString(""); for (int i = ls; (i <= le); i++) { n = LineLength(LineIndex(i)); CEdit::GetLine(i, ss.GetBuffer(n+1), n); ss.ReleaseBuffer(n); if (i == ls) ss = ss.Mid(s - LineIndex(i)); else str += CString("\r\n"); if (i == le) { n = e - (s + str.GetLength()); ss = ss.Left(n); } str += ss; } return str.GetLength(); }
void JHCEdit::DeleteLine(int line) { int n, lc, i; lc = GetLineCount(); if (line < 0) i = lc + line + 1; else i = line; if ((i < 0) || (i > lc)) return; i--; if (i < 0) i = LineFromChar(); i = LineIndex(i); n = LineLength(i); SetSel(i, i + n + 1); ReplaceSel(CString(""), TRUE); n = LineLength(i); SetSel(i, i); }
tstring ChatCtrl::LineFromPos(const POINT& p) const { int iCharPos = CharFromPos(p); int len = LineLength(iCharPos); if(len < 3) { return Util::emptyStringT; } tstring tmp; tmp.resize(len); GetLine(LineFromChar(iCharPos), &tmp[0], len); return tmp; }
/* ================ CSyntaxRichEditCtrl::GetCursorPos ================ */ void CSyntaxRichEditCtrl::GetCursorPos( int &line, int &column, int &character ) const { long start, end; char buffer[MAX_STRING_CHARS]; GetSel( start, end ); line = LineFromChar( start ); start -= LineIndex( line ); GetLine( line, buffer, sizeof( buffer ) ); for ( column = 1, character = 0; character < start; character++ ) { if ( idStr::CharIsTab( buffer[character] ) ) { column += TAB_SIZE; column -= column % TAB_SIZE; } else { column++; } } character++; }
/* ================ CSyntaxRichEditCtrl::FindNext ================ */ bool CSyntaxRichEditCtrl::FindNext(const char *find, bool matchCase, bool matchWholeWords, bool searchForward) { long selStart, selEnd, flags, search, length, start; tom::ITextRange *range; if (find[0] == '\0') { return false; } GetSel(selStart, selEnd); flags = 0; flags |= matchCase ? tom::tomMatchCase : 0; flags |= matchWholeWords ? tom::tomMatchWord : 0; if (searchForward) { m_TextDoc->Range(selEnd, GetTextLength(), &range); search = GetTextLength() - selEnd; } else { m_TextDoc->Range(0, selStart, &range); search = -selStart; } if (range->FindShit(A2BSTR(find), search, flags, &length) == S_OK) { m_TextDoc->Freeze(NULL); range->get_Start(&start); range->Release(); SetSel(start, start + length); int line = Max((int) LineFromChar(start) - 5, 0); LineScroll(line - GetFirstVisibleLine(), 0); UpdateVisibleRange(); m_TextDoc->Unfreeze(NULL); return true; } else { range->Release(); return false; } }
const TCHAR* CCustRichEdit::GetCurLineText (CString& Buffer) { int LineSize; int LineIndex; TCHAR* pBuffer; /* Get the current line text buffer */ LineIndex = LineFromChar(-1); LineSize = LineLength(-1); if (LineSize > 0) { pBuffer = Buffer.GetBuffer(LineSize+4); GetLine(LineIndex, pBuffer, LineSize+4); pBuffer[LineSize] = NULL_CHAR; Buffer.ReleaseBuffer(LineSize); } else { Buffer.Empty(); } return (const TCHAR*) (Buffer); }
int JHCEdit::DeleteChar(int count) { if (count == 0) return 0; int s, e, ls, le; GetSel(s, e); ls = LineIndex(LineFromChar(s)); le = ls + LineLength(ls); if (count > 0) { e = s + count; if (e > le) e = le; } else { e = s; s = s + count; if (s < ls) s = ls; } SetSel(s, e); Clear(); return e - s + 1; }
LRESULT CScriptEditView::OnKey( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& ) { LRESULT lRet = DefWindowProc( uMsg, wParam, lParam ); //if( uMsg == WM_KEYDOWN && wParam == VK_INSERT ) //{ // bool bOn = ((GetKeyState(VK_INSERT) & 1) == 1); // if( bOn ) // CreateSolidCaret( 10, 10 ); // else // CreateSolidCaret( 2, 10 ); //} // calc caret position long nStartPos, nEndPos; GetSel( nStartPos, nEndPos ); int nRow = LineFromChar( nEndPos ); int nCol = 0; int nChar = nEndPos - LineIndex(); if( nChar > 0 ) { // min = WORD for length LPTSTR lpstrLine = (LPTSTR)_alloca( (nChar + 2) * sizeof(TCHAR) ); nChar = GetLine( nRow, lpstrLine, nChar ); for( int i = 0; i < nChar; i++ ) { if(lpstrLine[i] == _T('\t')) nCol = ((nCol / m_nTabStop) + 1) * m_nTabStop; else nCol++; } } WtlGetMainWnd().UndateRowCol( nRow + 1, nCol + 1 ); return lRet; }
/* ================ CSyntaxRichEditCtrl::OnChar ================ */ void CSyntaxRichEditCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if (nChar == VK_TAB) { return; // tab is handle in OnKeyDown } CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags); // if the auto-complete list box is up if (autoCompleteStart >= 0) { long selStart, selEnd; if (charType[nChar] == CT_NAME) { AutoCompleteUpdate(); return; } else if (nChar == VK_BACK) { GetSel(selStart, selEnd); if (selStart > autoCompleteStart) { AutoCompleteUpdate(); } else { AutoCompleteHide(); } return; } else { AutoCompleteHide(); } } // if the function parameter tool tip is up if (funcParmToolTipStart >= 0) { long selStart, selEnd; if (nChar == ')' || nChar == VK_ESCAPE) { ToolTipHide(); } else if (nChar == VK_BACK) { GetSel(selStart, selEnd); if (selStart < funcParmToolTipStart) { ToolTipHide(); } } } // show keyword auto-completion if (keyWordAutoCompletion && charType[nChar] == CT_NAME && funcParmToolTipStart < 0) { long selStart, selEnd; int line, column, length, i; char buffer[1024]; GetSel(selStart, selEnd); line = LineFromChar(selStart); length = GetLine(line, buffer, sizeof(buffer)); column = selStart - LineIndex(line); if (column <= 1 || charType[buffer[column-2]] == CT_WHITESPACE) { if (column >= length-1 || charType[buffer[column]] == CT_WHITESPACE) { autoCompleteListBox.ResetContent(); for (i = 0; keyWords[i].keyWord; i++) { autoCompleteListBox.AddString(keyWords[i].keyWord); } AutoCompleteShow(selStart - 1); } } return; } // highlight braced sections if (nChar == '{') { BracedSectionStart('{', '}'); } else if (nChar == '}') { BracedSectionEnd('{', '}'); } else if (nChar == '(') { BracedSectionStart('(', ')'); } else if (nChar == ')') { BracedSectionEnd('(', ')'); } else if (nChar == '[') { BracedSectionStart('[', ']'); } else if (nChar == ']') { BracedSectionEnd('[', ']'); } else if (nChar == '<') { BracedSectionStart('<', '>'); } else if (nChar == '>') { BracedSectionEnd('<', '>'); } // show object member auto-completion if (nChar == '.' && GetObjectMembers && funcParmToolTipStart < 0) { int charIndex; CString name; if (GetNameBeforeCurrentSelection(name, charIndex)) { autoCompleteListBox.ResetContent(); if (GetObjectMembers(name, autoCompleteListBox)) { AutoCompleteShow(charIndex); } } return; } // show function parameter tool tip if (nChar == '(' && GetFunctionParms) { int charIndex; CString name; if (GetNameBeforeCurrentSelection(name, charIndex)) { CString parmString; if (GetFunctionParms(name, parmString)) { ToolTipShow(charIndex, parmString); } } return; } }
/* ================ CSyntaxRichEditCtrl::OnKeyDown ================ */ void CSyntaxRichEditCtrl::OnKeyDown(UINT nKey, UINT nRepCnt, UINT nFlags) { if (m_TextDoc == NULL) { return; } if (autoCompleteStart >= 0) { int sel; switch (nKey) { case VK_UP: { // up arrow sel = Max(0, autoCompleteListBox.GetCurSel() - 1); autoCompleteListBox.SetCurSel(sel); return; } case VK_DOWN: { // down arrow sel = Min(autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 1); autoCompleteListBox.SetCurSel(sel); return; } case VK_PRIOR: { // page up key sel = Max(0, autoCompleteListBox.GetCurSel() - 10); autoCompleteListBox.SetCurSel(sel); return; } case VK_NEXT: { // page down key sel = Min(autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 10); autoCompleteListBox.SetCurSel(sel); return; } case VK_HOME: { // home key autoCompleteListBox.SetCurSel(0); return; } case VK_END: { autoCompleteListBox.SetCurSel(autoCompleteListBox.GetCount() - 1); return; } case VK_RETURN: // enter key case VK_TAB: { // tab key AutoCompleteInsertText(); AutoCompleteHide(); return; } case VK_LEFT: // left arrow case VK_RIGHT: // right arrow case VK_INSERT: // insert key case VK_DELETE: { // delete key return; } } } BracedSectionHide(); switch (nKey) { case VK_TAB: { // multi-line tabs long selStart, selEnd; GetSel(selStart, selEnd); // if multiple lines are selected add tabs to, or remove tabs from all of them if (selEnd > selStart) { CString text; text = GetSelText(); if (GetAsyncKeyState(VK_SHIFT) & 0x8000) { if (idStr::CharIsTab(text[0])) { text.Delete(0, 1); } for (int i = 0; i < text.GetLength() - 2; i++) { if (idStr::CharIsNewLine(text[i])) { do { i++; } while (idStr::CharIsNewLine(text[i])); if (idStr::CharIsTab(text[i])) { text.Delete(i, 1); } } } } else { text.Insert(0, '\t'); for (int i = 0; i < text.GetLength() - 1; i++) { if (idStr::CharIsNewLine(text[i])) { do { i++; } while (idStr::CharIsNewLine(text[i])); text.Insert(i, '\t'); } } } ReplaceSel(text, TRUE); SetSel(selStart, selStart + text.GetLength()); } else { ReplaceSel("\t", TRUE); } return; } case VK_RETURN: { // auto-indentation long selStart, selEnd; int line, length, numTabs, i; char buffer[1024]; idStr text; GetSel(selStart, selEnd); line = LineFromChar(selStart); length = GetLine(line, buffer, sizeof(buffer)); for (numTabs = 0; numTabs < length; numTabs++) { if (!idStr::CharIsTab(buffer[numTabs])) { break; } } bool first = true; for (i = numTabs; i < length; i++) { if (buffer[i] == '{') { numTabs++; first = false; } else if (buffer[i] == '}' && !first) { numTabs--; } } text = "\r\n"; for (i = 0; i < numTabs; i++) { text.Append('\t'); } ReplaceSel(text, TRUE); return; } } m_TextDoc->Freeze(NULL); CRichEditCtrl::OnKeyDown(nKey, nRepCnt, nFlags); UpdateVisibleRange(); m_TextDoc->Unfreeze(NULL); }
bool CFulEditCtrl::AddLine(const tstring & line, bool aTimeStamps) { bool noScroll = false; matchedTab = false; timeStamps = aTimeStamps; tstring aLine = Util::replace(line, _T("\r\n"), _T("\r")); if(GetWindowTextLength() > SETTING(CHATBUFFERSIZE)) { SetRedraw(FALSE); int ch = LineIndex(LineFromChar(2000)); SetSel(0, ch); ReplaceSel(_T("")); UpdateUrlRanges(ch); SetSel(GetTextLengthEx(GTL_NUMCHARS), GetTextLengthEx(GTL_NUMCHARS)); ScrollCaret(); SetRedraw(TRUE); } if(Util::strnicmp(_T("<") + nick + _T(">"), aLine, nick.length() + 2) == 0) skipLog = true; if(isSet(STRIP_ISP) && aLine[0] == _T('<')) { tstring::size_type end = aLine.find(_T(">")); if( end != tstring::npos ) { tstring::size_type pos = aLine.rfind(_T("]"), end); if( end > 0 && (end-1) == pos ) pos = aLine.rfind(_T("]"), pos-1); if(pos != string::npos) aLine = _T("<") + aLine.substr(pos+1); } } tstring::size_type pos = aLine.find(_T("> /me ")); if( pos != tstring::npos) aLine = _T("** ") + aLine.substr(1, pos-1) + aLine.substr(pos+5, aLine.length()); if(timeStamps) aLine = _T("[") + Util::getShortTimeString() + _T("] ") + aLine; SetRedraw(FALSE); //Get the pos of the last char POINT pt = PosFromChar(GetTextLengthEx(GTL_NUMCHARS)); CRect rc; GetClientRect(&rc); int l = -1; //check if the last char is visible, if not then save the //scrollbar position if(rc.PtInRect(pt)){ noScroll = false; } else { noScroll = true; l = GetFirstVisibleLine(); } AddInternalLine(aLine); //restore the scrollbar position if(noScroll) { LineScroll(l - GetFirstVisibleLine()); } SetRedraw(); Invalidate(); UpdateWindow(); return matchedTab; }
void CStatusCtrl::ShowStatus(CString status, int nType) { USES_CONVERSION; CString rtfstr = m_RTFHeader; status.Replace(_T("\\"), _T("\\\\")); status.Replace(_T("{"), _T("\\{")); status.Replace(_T("}"), _T("\\}")); status.Replace(_T("\r"), _T("")); status.Replace(_T("\n"), _T("\\status")); CString str; switch (nType) { case FZ_LOG_STATUS: //str.LoadString(IDS_STATUSMSG_PREFIX); str += "\\cf2"; break; case FZ_LOG_ERROR: //str.LoadString(IDS_ERRORMSG_PREFIX); str="\\cf5"; break; case FZ_LOG_COMMAND: //str.LoadString(IDS_COMMANDMSG_PREFIX); str="\\cf3"; break; case FZ_LOG_REPLY: //str.LoadString(IDS_RESPONSEMSG_PREFIX); str="\\cf4"; break; case FZ_LOG_LIST: //str.LoadString(IDS_TRACEMSG_TRACE); str="\\cf11"; break; case FZ_LOG_APIERROR: case FZ_LOG_WARNING: case FZ_LOG_INFO: case FZ_LOG_DEBUG: //str.LoadString(IDS_TRACEMSG_TRACE); str="\\cf7"; break; } CString tmp; tmp += str; tmp += "\\tab "; tmp += status; status = tmp; if (!m_bEmpty){ rtfstr += "\\par "; rtfstr += status; }else { m_bEmpty = FALSE; rtfstr += status; } rtfstr += "} "; EDITSTREAM es; string s = Util::ws2s(wstring(rtfstr)); es.dwCookie = (DWORD)&s; // Pass a pointer to the string to the callback function es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function. CWnd *pFocusWnd = GetFocus(); if (pFocusWnd && pFocusWnd == this) AfxGetMainWnd()->SetFocus(); long nStart, nEnd; GetSel(nStart, nEnd); BOOL nScrollToEnd = FALSE; int num = 0; //this is the number of visible lines CRect rect; GetRect(rect); int height = rect.Height(); for (int i = GetFirstVisibleLine(); i < GetLineCount() && GetCharPos(LineIndex(i)).y < height; i++) num++; if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount()) nScrollToEnd = TRUE; HideSelection(TRUE, FALSE); SetSel(-1, -1); StreamIn(SF_RTF | SFF_SELECTION, es); // Perform the streaming if (GetLineCount() > 1000) { nStart -= LineLength(0) + 2; nEnd -= LineLength(0) + 2; if (nStart < 0) nEnd = 0; if (nEnd < 0) nEnd = 0; SetSel(0, LineLength(0) + 2); ReplaceSel(_T("")); } SetSel(nStart, nEnd); if (pFocusWnd && pFocusWnd == this) SetFocus(); HideSelection(FALSE, FALSE); if (nScrollToEnd) { if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num || LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num)) LineScroll(1); else { m_nMoveToBottom++; if (!m_nTimerID) m_nTimerID = SetTimer(654, 25, NULL); } } }
void CStatusCtrl::ShowStatus(CString status, int nType) { USES_CONVERSION; CString rtfstr = m_RTFHeader; status.Replace(_T("\\"), _T("\\\\")); status.Replace(_T("{"), _T("\\{")); status.Replace(_T("}"), _T("\\}")); status.Replace(_T("\r"), _T("")); status.Replace(_T("\n"), _T("\\status")); CString str; switch (nType) { case 0: str = "\\cf2"; break; case 1: str = "\\cf5"; break; case 2: str = "\\cf3"; break; case 3: str = "\\cf4"; break; } status = str + status; if (!m_bEmpty) rtfstr += "\\par " + status; else { m_bEmpty = FALSE; rtfstr += status; } rtfstr += "} "; char *buffer = new char[rtfstr.GetLength() + 5]; //Make it large enough to hold unicode data strcpy(buffer + 4, T2CA(rtfstr)); *(int *)buffer = 0; EDITSTREAM es; es.dwCookie = (DWORD)buffer; // Pass a pointer to the CString to the callback function es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function. CWnd *pFocusWnd = GetFocus(); if (pFocusWnd && pFocusWnd == this) AfxGetMainWnd()->SetFocus(); long nStart, nEnd; GetSel(nStart, nEnd); BOOL nScrollToEnd = FALSE; int num = 0; //this is the number of visible lines CRect rect; GetRect(rect); int height = rect.Height(); for (int i = GetFirstVisibleLine(); i < GetLineCount() && GetCharPos(LineIndex(i)).y < height; i++) num++; if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount()) nScrollToEnd = TRUE; HideSelection(TRUE, FALSE); SetSel(-1, -1); StreamIn(SF_RTF | SFF_SELECTION, es); // Perform the streaming if (GetLineCount() > 1000) { nStart -= LineLength(0) + 2; nEnd -= LineLength(0) + 2; if (nStart < 0) nEnd = 0; if (nEnd < 0) nEnd = 0; SetSel(0, LineLength(0) + 2); ReplaceSel(_T("")); } SetSel(nStart, nEnd); if (pFocusWnd && pFocusWnd == this) SetFocus(); HideSelection(FALSE, FALSE); if (nScrollToEnd) { if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num || LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num)) LineScroll(1); else { m_nMoveToBottom++; if (!m_nTimerID) m_nTimerID = SetTimer(654, 25, NULL); } } delete [] buffer; }
int CxEdit::GotoEnd(BOOL bScroll /*= TRUE*/) { const int length = GetWindowTextLength(); SetSel(length, length, !bScroll); // end of edit text return LineFromChar(length); }
void ChatCtrl::AppendText(const Identity& i, const tstring& sMyNick, const tstring& sTime, tstring sMsg, CHARFORMAT2& cf, bool bUseEmo/* = true*/) { SetRedraw(FALSE); SCROLLINFO si = { 0 }; POINT pt = { 0 }; si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; GetScrollInfo(SB_VERT, &si); GetScrollPos(&pt); LONG lSelBegin = 0, lSelEnd = 0, lTextLimit = 0, lNewTextLen = 0; LONG lSelBeginSaved, lSelEndSaved; // Unify line endings tstring::size_type j = 0; while((j = sMsg.find(_T("\r"), j)) != tstring::npos) sMsg.erase(j, 1); GetSel(lSelBeginSaved, lSelEndSaved); lSelEnd = lSelBegin = GetTextLengthEx(GTL_NUMCHARS); bool isMyMessage = i.getUser() == ClientManager::getInstance()->getMe(); tstring sLine = sTime + sMsg; // Remove old chat if size exceeds lNewTextLen = sLine.size(); lTextLimit = GetLimitText(); if(lSelEnd + lNewTextLen > lTextLimit) { LONG lRemoveChars = 0; int multiplier = 1; if(lNewTextLen >= lTextLimit) { lRemoveChars = lSelEnd; magnets.clear(); } else { while(lRemoveChars < lNewTextLen) lRemoveChars = LineIndex(LineFromChar(multiplier++ * lTextLimit / 10)); } if(magnets.size()) { tstring buf; buf.resize(lRemoveChars); GetTextRange(0, lRemoveChars, &buf[0]); CHARFORMAT2 cfSel; cfSel.cbSize = sizeof(CHARFORMAT2); for(TStringMap::iterator i = magnets.begin(); i != magnets.end();) { tstring::size_type j = 0; while((j = buf.find(i->first, j)) != tstring::npos) { SetSel(j, j + i->first.size()); GetSelectionCharFormat(cfSel); if(cfSel.dwEffects & CFE_LINK) { magnets.erase(i++); break; } j += i->first.size(); } if(j == tstring::npos) { ++i; } } } // Update selection ranges lSelEnd = lSelBegin -= lRemoveChars; lSelEndSaved -= lRemoveChars; lSelBeginSaved -= lRemoveChars; // ...and the scroll position pt.y -= PosFromChar(lRemoveChars).y; SetSel(0, lRemoveChars); ReplaceSel(_T("")); } // Add to the end SetSel(lSelBegin, lSelEnd); setText(sLine); CHARFORMAT2 enc; enc.bCharSet = RUSSIAN_CHARSET; enc.dwMask = CFM_CHARSET; SetSel(0, sLine.length()); SetSelectionCharFormat(enc); // Format TimeStamp if(!sTime.empty()) { lSelEnd += sTime.size(); SetSel(lSelBegin, lSelEnd - 1); SetSelectionCharFormat(WinUtil::m_TextStyleTimestamp); PARAFORMAT2 pf; memzero(&pf, sizeof(PARAFORMAT2)); pf.dwMask = PFM_STARTINDENT; pf.dxStartIndent = 0; SetParaFormat(pf); } // Authors nick tstring sAuthor = Text::toT(i.getNick()); if(!sAuthor.empty()) { LONG iLen = (sMsg[0] == _T('*')) ? 1 : 0; LONG iAuthorLen = sAuthor.size() + 1; sMsg.erase(0, iAuthorLen + iLen); lSelBegin = lSelEnd; lSelEnd += iAuthorLen + iLen; if(isMyMessage) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(WinUtil::m_ChatTextMyOwn); SetSel(lSelBegin + iLen + 1, lSelBegin + iLen + iAuthorLen); SetSelectionCharFormat(WinUtil::m_TextStyleMyNick); } else { bool isFavorite = FavoriteManager::getInstance()->isFavoriteUser(i.getUser()); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || i.isOp()) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + iLen + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(i.isOp()) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } else { bool thirdPerson = false; switch(sMsg[0]) { case _T('*'): if(sMsg[1] != _T(' ')) break; thirdPerson = true; case _T('<'): tstring::size_type iAuthorLen = sMsg.find(thirdPerson ? _T(' ') : _T('>'), thirdPerson ? 2 : 1); if(iAuthorLen != tstring::npos) { bool isOp = false, isFavorite = false; if(client != NULL) { tstring nick(sMsg.c_str() + 1); nick.erase(iAuthorLen - 1); const OnlineUserPtr ou = client->findUser(Text::fromT(nick)); if(ou != NULL) { isFavorite = FavoriteManager::getInstance()->isFavoriteUser(ou->getUser()); isOp = ou->getIdentity().isOp(); } } lSelBegin = lSelEnd; lSelEnd += iAuthorLen; sMsg.erase(0, iAuthorLen); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || isOp) { SetSel(lSelBegin, lSelBegin + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(isOp) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } } // Format the message part FormatChatLine(sMyNick, sMsg, cf, isMyMessage, sAuthor, lSelEnd, bUseEmo); SetSel(lSelBeginSaved, lSelEndSaved); if( isMyMessage || ((si.nPage == 0 || (size_t)si.nPos >= (size_t)si.nMax - si.nPage - 5) && (lSelBeginSaved == lSelEndSaved || !selectedUser.empty() || !selectedIP.empty() || !selectedURL.empty()))) { PostMessage(EM_SCROLL, SB_BOTTOM, 0); } else { SetScrollPos(&pt); } // Force window to redraw SetRedraw(TRUE); InvalidateRect(NULL); }
bool ChatCtrl::HitNick(const POINT& p, tstring& sNick, int& iBegin, int& iEnd) { if(client == NULL) return false; int iCharPos = CharFromPos(p), line = LineFromChar(iCharPos), len = LineLength(iCharPos) + 1; long lSelBegin = 0, lSelEnd = 0; if(len < 3) return false; // Metoda FindWordBreak nestaci, protoze v nicku mohou byt znaky povazovane za konec slova int iFindBegin = LineIndex(line), iEnd1 = LineIndex(line) + LineLength(iCharPos); for(lSelBegin = iCharPos; lSelBegin >= iFindBegin; lSelBegin--) { if(FindWordBreak(WB_ISDELIMITER, lSelBegin)) break; } lSelBegin++; for(lSelEnd = iCharPos; lSelEnd < iEnd1; lSelEnd++) { if(FindWordBreak(WB_ISDELIMITER, lSelEnd)) break; } len = lSelEnd - lSelBegin; if(len <= 0) return false; tstring sText; sText.resize(len); GetTextRange(lSelBegin, lSelEnd, &sText[0]); size_t iLeft = 0, iRight = 0, iCRLF = sText.size(), iPos = sText.find(_T('<')); if(iPos != tstring::npos) { iLeft = iPos + 1; iPos = sText.find(_T('>'), iLeft); if(iPos == tstring::npos) return false; iRight = iPos - 1; iCRLF = iRight - iLeft + 1; } else { iLeft = 0; } tstring sN = sText.substr(iLeft, iCRLF); if(sN.empty()) return false; if(client->findUser(Text::fromT(sN)) != NULL) { sNick = sN; iBegin = lSelBegin + iLeft; iEnd = lSelBegin + iLeft + iCRLF; return true; } // Jeste pokus odmazat eventualni koncovou ':' nebo '>' // Nebo pro obecnost posledni znak // A taky prvni znak // A pak prvni i posledni :-) if(iCRLF > 1) { sN = sText.substr(iLeft, iCRLF - 1); if(client->findUser(Text::fromT(sN)) != NULL) { sNick = sN; iBegin = lSelBegin + iLeft; iEnd = lSelBegin + iLeft + iCRLF - 1; return true; } sN = sText.substr(iLeft + 1, iCRLF - 1); if(client->findUser(Text::fromT(sN)) != NULL) { sNick = sN; iBegin = lSelBegin + iLeft + 1; iEnd = lSelBegin + iLeft + iCRLF; return true; } sN = sText.substr(iLeft + 1, iCRLF - 2); if(client->findUser(Text::fromT(sN)) != NULL) { sNick = sN; iBegin = lSelBegin + iLeft + 1; iEnd = lSelBegin + iLeft + iCRLF - 1; return true; } } return false; }
/*---------------------------------------------------------------------------------------------- This processes Windows messages on the window. In general, it normally calls the appropriate method on the edit class. ----------------------------------------------------------------------------------------------*/ bool TssEdit::FWndProc(uint wm, WPARAM wp, LPARAM lp, long & lnRet) { bool fRet; switch (wm) { case WM_GETDLGCODE: // This is essential when embedded in a dialog to tell the dialog manager that it // wants to get key strokes. (We could try DLGC_WANTALLKEYS but I think we would then // get the Tab and Return keys...we may get them anyway with this combination...) // The last value tells Windows that when tabbing to this control we should use // EM_SETSEL to select all the text. lnRet = DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL; return true; case EM_GETLINE: // Use FW_EM_GETLINE. case EM_REPLACESEL: // Use FW_EM_REPLACESEL. // We don't support these methods. Use the replacement TsString versions instead. Assert(false); lnRet = LB_ERR; return true; // NOTE: DO NOT send this message to a TssEdit if you want the actual text. Send the // FW_EM_GETTEXT message instead. This method is required for TssEdit controls on a // dialog because Windows will send the message to the control anytime the user hits a // key. case WM_GETTEXT: { ITsStringPtr qtss; GetText(&qtss); const wchar * pwrgch; int cch; HRESULT hr; IgnoreHr(hr = qtss->LockText(&pwrgch, &cch)); if (FAILED(hr)) return true; StrApp str(pwrgch, cch); qtss->UnlockText(pwrgch); lnRet = Min(cch + 1, (int)wp); achar * psz = reinterpret_cast<achar *>(lp); StrCpyN(psz, str.Chars(), lnRet); } return true; // NOTE: You should be sending an FW_EM_SETTEXT message instead of this. case WM_SETTEXT: { achar * psz = reinterpret_cast<achar *>(lp); StrUni stu(psz); ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); ITsStringPtr qtss; CheckHr(qtsf->MakeStringRgch(stu.Chars(), stu.Length(), m_wsBase, &qtss)); SetText(qtss); } return true; case EM_CANUNDO: case EM_CHARFROMPOS: case EM_EMPTYUNDOBUFFER: case EM_FMTLINES: case EM_GETFIRSTVISIBLELINE: case EM_GETHANDLE: case EM_GETMODIFY: case EM_GETPASSWORDCHAR: case EM_GETRECT: case EM_GETTHUMB: case EM_GETWORDBREAKPROC: case EM_POSFROMCHAR: case EM_SETHANDLE: case EM_SETMODIFY: case EM_SETPASSWORDCHAR: case EM_SETRECT: case EM_SETRECTNP: case EM_SETTABSTOPS: case EM_SETWORDBREAKPROC: case EM_UNDO: case WM_GETFONT: case WM_SETFONT: // We don't support these methods. Assert(false); lnRet = LB_ERR; return true; case EM_GETLIMITTEXT: lnRet = GetLimitText(); return true; case FW_EM_GETLINE: lnRet = GetLine(wp, (ITsString **)lp); return true; case EM_GETLINECOUNT: lnRet = GetLineCount(); return true; case EM_GETMARGINS: lnRet = GetMargins(); return true; case FW_EM_GETSTYLE: GetStyle((StrUni *)lp, (COLORREF *)wp); return true; case EM_GETSEL: lnRet = GetSel((int *)wp, (int *)lp); return true; case EM_LINEFROMCHAR: lnRet = LineFromChar(wp); return true; case EM_LINEINDEX: lnRet = LineIndex(wp); return true; case EM_LINELENGTH: lnRet = LineLength(wp); return true; case EM_LINESCROLL: LineScroll(lp, wp); return true; case FW_EM_REPLACESEL: ReplaceSel((ITsString *)lp); return true; case EM_SCROLL: lnRet = ::SendMessage(m_hwnd, WM_VSCROLL, LOWORD(wp), 0); return true; case EM_SCROLLCARET: ScrollCaret(); return true; case EM_SETLIMITTEXT: SetLimitText(wp); return true; case EM_SETMARGINS: SetMargins(wp, LOWORD(lp), HIWORD(lp)); return true; case EM_SETREADONLY: SetReadOnly(wp); return true; case EM_SETSEL: SetSel(wp, lp); return true; case FW_EM_SETSTYLE: SetStyle((StrUni *)lp, (COLORREF)wp); return true; case WM_GETTEXTLENGTH: lnRet = GetTextLength(); return true; case FW_EM_GETTEXT: GetText((ITsString **)lp); return true; case FW_EM_SETTEXT: SetText((ITsString *)lp); return true; case WM_COPY: Copy(); return true; case WM_CUT: Cut(); return true; case WM_PASTE: Paste(); return true; case WM_HSCROLL: if (!OnHScroll(LOWORD(wp), HIWORD(wp), (HWND)lp)) { ::SendMessage(::GetParent(m_hwnd), WM_COMMAND, MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_HSCROLL), (LPARAM)m_hwnd); } return true; case WM_VSCROLL: if (!OnVScroll(LOWORD(wp), HIWORD(wp), (HWND)lp)) { ::SendMessage(::GetParent(m_hwnd), WM_COMMAND, MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_VSCROLL), (LPARAM)m_hwnd); } return true; case WM_KILLFOCUS: if (!OnKillFocus((HWND)wp)) { ::SendMessage(::GetParent(m_hwnd), WM_COMMAND, MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_KILLFOCUS), (LPARAM)m_hwnd); } return true; case WM_SETFOCUS: if (!OnSetFocus((HWND)wp)) { ::SendMessage(::GetParent(m_hwnd), WM_COMMAND, MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_SETFOCUS), (LPARAM)m_hwnd); } return true; // Calling SuperClass here causes two OnSetFocus calls for each OnKillFocus. //return SuperClass::FWndProc(wm, wp, lp, lnRet); case WM_CHAR: fRet = false; if (wp == VK_TAB) // '\t' { fRet = OnCharTab(); } else if (wp == VK_RETURN) // '\r' { fRet = OnCharEnter(); } else if (wp == VK_ESCAPE) // '\33' { fRet = OnCharEscape(); } if (fRet) return fRet; else return SuperClass::FWndProc(wm, wp, lp, lnRet); case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MOUSEMOVE: if (HasToolTip()) { // Notify the tooltip belonging to the parent toolbar of the mouse message. Assert(m_hwndToolTip); MSG msg; msg.hwnd = m_hwnd; // ::GetParent(m_hwnd); msg.message = wm; msg.wParam = wp; msg.lParam = lp; ::SendMessage(m_hwndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg); } break; default: break; } return SuperClass::FWndProc(wm, wp, lp, lnRet); }
void CTabPersistPosEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { //Retrieve the TAB-key and insert tabs if (nChar == VK_TAB) { //NOTE: We totally ignore the nRepCnt, // because it is too difficult to implement // in the case of removing tabs. // However, for inserting it would be easy. // But lets stay consistent. //Undo the automatic loosing of the focus. SetFocus(); //Insert or deleted trailing tabs? // - Get key state of Shift key (MSB == 0/1) bool bInsertTabs = (GetKeyState(VK_SHIFT) >= 0); //Get Selection int SelStart = 0; int SelEnd = 0; GetSel(SelStart, SelEnd); ASSERT(SelStart <= SelEnd); //Lines that contribute to the selection - at least partly int LineSelStart = LineFromChar(SelStart); int LineSelEnd = LineFromChar(SelEnd); ASSERT(LineSelStart <= LineSelEnd); int nLines = LineSelEnd - LineSelStart + 1; //If we have just some selected chars in one line, // then we replace the current selection. // //But not, if this line is fully selected. // bool bOneLineFullySelected = (LineIndex(LineSelStart) == SelStart) // && (LineIndex(LineSelStart) + LineLength(SelStart) == SelEnd) // && (SelStart != SelEnd); if (nLines == 1)// && !bOneLineFullySelected) { if (bInsertTabs) ReplaceSel(_T("\t"), true); return; } //Is the end of the selection at the start of a new line? //In this case, we do not treat the last line as being selected. if (LineIndex(LineSelEnd) == SelEnd) { --nLines; --LineSelEnd; } //If we have more selected lines, /*or one fully selected line*/ // then we intend all those lines and grow the selection. //So lets retrieve the text and add some tabs. CString Text; GetWindowText(Text); // - Insert/delete the tabs at the beginning of each line. int nTabsRemoved = 0; for (int i = 0; i < nLines; i++) { //Insert or delete? if (bInsertTabs) { Text.Insert(LineIndex(LineSelStart + i) + i, _T('\t')); } else { //Do we have tabs at the beginning? if (Text[LineIndex(LineSelStart + i) - nTabsRemoved] == _T('\t')) { Text.Delete(LineIndex(LineSelStart + i) - nTabsRemoved); nTabsRemoved++; } } } // - Set the new text and make a good selection SetWindowText(Text); SetSel(LineIndex(LineSelStart), LineIndex(LineSelEnd) + LineLength(LineIndex(LineSelEnd)) + 2); return; } CPersistPosEdit::OnChar(nChar, nRepCnt, nFlags); }