void OutputCtrl::ShowLine( int line ) { // First make sure the line is not folded. EnsureVisible( line ); line = VisibleFromDocLine( line ); int firstVisible = GetFirstVisibleLine(); int lastVisible = firstVisible + ( LinesOnScreen() - 1 ); if ( line <= firstVisible ) { int lines = line - firstVisible; if ( lines < -1 ) { lines -= LinesOnScreen() / 2; } LineScroll( 0, lines ); } else if ( line >= lastVisible ) { int lines = line - lastVisible; if ( lines > 1 ) { lines += LinesOnScreen() / 2; } LineScroll( 0, lines ); } }
void CLineNumberEdit::UpdateTopAndBottom() /* ============================================================ Function : CLineNumberEdit::UpdateTopAndBottom Description : Updates the top- and bottom line number for the line number control. Return : void Parameters : none Usage : Should be called as soon as the contents of the control is changed. ============================================================*/ { CRect rect; GetClientRect( &rect ); int maxline = GetLineCount() + m_LineDelta; // Height for individual lines int lineheight = m_zero.cy; // Calculate the number of lines to draw int topline = GetFirstVisibleLine() + m_LineDelta; if( ( topline + ( rect.Height() / lineheight ) ) < maxline ) maxline = topline + ( rect.Height() / lineheight ); if ( m_maxval > 0 && maxline > m_maxval + m_LineDelta ) maxline = m_maxval + m_LineDelta; m_line.SetTopAndBottom( topline, maxline ); }
/* ================ CSyntaxRichEditCtrl::GetVisibleRange ================ */ CHARRANGE CSyntaxRichEditCtrl::GetVisibleRange(void) const { RECT rectArea; int firstLine, lastLine; CHARRANGE range; firstLine = GetFirstVisibleLine(); GetClientRect(&rectArea); lastLine = firstLine + (rectArea.bottom / (defaultCharFormat.yHeight / 20)); if (lastLine >= GetLineCount()) { lastLine = GetLineCount() - 1; } range.cpMin = LineIndex(firstLine); if (range.cpMin < 0) { range.cpMin = 0; } range.cpMax = LineIndex(lastLine); if (range.cpMax == -1) { range.cpMax = range.cpMin + LineLength(range.cpMin); } else { range.cpMax += LineLength(range.cpMax); } if (range.cpMax >= GetTextLength()) { range.cpMax = GetTextLength() - 1; } return range; }
void cbStyledTextCtrl::MakeNearbyLinesVisible(int line) { const int dist = VisibleFromDocLine(line) - GetFirstVisibleLine(); if (dist >= 0 && dist < 2) LineScroll(0, dist - 2); else if (dist >= LinesOnScreen() - 2) LineScroll(0, 3 + dist - LinesOnScreen()); }
int MiniStyledTextCtrl::GetLineFromPosition(const wxPoint &pt) { int line = GetFirstVisibleLine(); int lh = TextHeight(line); if (lh>0) line += pt.y/lh; return line; }
void GotoFileList::UpdateList(const bool reloadAll) { const FileEntry* selEntry = GetSelectedAction(); const int topLine = GetFirstVisibleLine(); int selection = -1; const unsigned int startItem = reloadAll ? 0 : m_items.size(); // Insert new items if (m_searchText.empty()) { // Copy all actions to items m_items.resize(m_actions.size()); for (unsigned int i = startItem; i < m_actions.size(); ++i) { m_items[i].file_entry = m_actions[i]; m_items[i].hlChars.clear(); } } else { // Copy matching actions to items for (unsigned int i = m_actionCount; i < m_actions.size(); ++i) { if (m_tempEntry->path.empty() || m_actions[i]->path != m_tempEntry->path) AddFileIfMatching(m_searchText, m_actions[i]); } } // Sort the items if (startItem) { sort(m_items.begin() + startItem, m_items.end()); inplace_merge(m_items.begin(), m_items.begin() + startItem, m_items.end()); } else sort(m_items.begin(), m_items.end()); // Keep same selection if (selEntry) { for (unsigned int i = 0; i < m_items.size(); ++i) { if (m_items[i].file_entry == selEntry) { selection = i; break; } } } // Refresh and redraw listCtrl Freeze(); SetItemCount(m_items.size()); SetSelection(selection); if (selection == -1) ScrollToLine(topLine); else if (!IsVisible(selection)) ScrollToLine(selection); RefreshAll(); Thaw(); m_actionCount = m_actions.size(); }
void wxVListBox::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxSize clientSize = GetClientSize(); wxAutoBufferedPaintDC dc(this); // the update rectangle wxRect rectUpdate = GetUpdateClientRect(); // fill it with background colour dc.SetBackground(GetBackgroundColour()); dc.Clear(); // the bounding rectangle of the current line wxRect rectLine; rectLine.width = clientSize.x; // iterate over all visible lines const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetFirstVisibleLine(); line < lineMax; line++ ) { const wxCoord hLine = OnGetLineHeight(line); rectLine.height = hLine; // and draw the ones which intersect the update rect if ( rectLine.Intersects(rectUpdate) ) { // don't allow drawing outside of the lines rectangle wxDCClipper clip(dc, rectLine); wxRect rect = rectLine; OnDrawBackground(dc, rect, line); OnDrawSeparator(dc, rect, line); rect.Deflate(m_ptMargins.x, m_ptMargins.y); OnDrawItem(dc, rect, line); } else // no intersection { if ( rectLine.GetTop() > rectUpdate.GetBottom() ) { // we are already below the update rect, no need to continue // further break; } //else: the next line may intersect the update rect } rectLine.y += hLine; } }
void CHTRichEditCtrl::ScrollToLastLine(bool bForceLastLineAtBottom) { if (bForceLastLineAtBottom) { int iFirstVisible = GetFirstVisibleLine(); if (iFirstVisible > 0) LineScroll(-iFirstVisible); } // WM_VSCROLL does not work correctly under Win98 (or older version of comctl.dll) SendMessage(WM_VSCROLL, SB_BOTTOM); }
/* ================ 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; } }
void CLineNumberEdit::UpdateTopAndBottom() { CRect rect; GetClientRect( &rect ); int maxline = GetLineCount() + m_LineDelta; // Height for individual lines int lineheight = m_zero.cy; // Calculate the number of lines to draw int topline = GetFirstVisibleLine() + m_LineDelta; if( ( topline + ( rect.Height() / lineheight ) ) < maxline ) maxline = topline + ( rect.Height() / lineheight ); if ( m_maxval > 0 && maxline > m_maxval + m_LineDelta ) maxline = m_maxval + m_LineDelta; m_line.SetTopAndBottom( topline, maxline ); }
void CHTRichEditCtrl::ScrollToLastLine(bool bForceLastLineAtBottom) { if (bForceLastLineAtBottom) { int iFirstVisible = GetFirstVisibleLine(); if (iFirstVisible > 0) LineScroll(-iFirstVisible); } // WM_VSCROLL does not work correctly under Win98 (or older version of comctl.dll) SendMessage(WM_VSCROLL, SB_BOTTOM); if (afxIsWin95()) { // older version of comctl.dll seem to need this to properly update the display int iPos = GetScrollPos(SB_VERT); SendMessage(WM_VSCROLL, MAKELONG(SB_THUMBPOSITION, iPos)); SendMessage(WM_VSCROLL, SB_ENDSCROLL); } }
bool wxVScrolledWindow::Layout() { if ( GetSizer() ) { // adjust the sizer dimensions/position taking into account the // virtual size and scrolled position of the window. int w = 0, h = 0; GetVirtualSize(&w, &h); // x is always 0 so no variable needed int y = -GetLinesHeight(0, GetFirstVisibleLine()); GetSizer()->SetDimension(0, y, w, h); return true; } // fall back to default for LayoutConstraints return wxPanel::Layout(); }
void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event) { // No keyboard interface for now event.Skip(); #if 0 // flags for DoHandleItemClick() int flags = ItemClick_Kbd; int currentLineNow = SymbolValueToLineNumber(m_current); int currentLine; switch ( event.GetKeyCode() ) { case WXK_HOME: currentLine = 0; break; case WXK_END: currentLine = GetLineCount() - 1; break; case WXK_DOWN: if ( currentLineNow == (int)GetLineCount() - 1 ) return; currentLine = currentLineNow + 1; break; case WXK_UP: if ( m_current == wxNOT_FOUND ) currentLine = GetLineCount() - 1; else if ( currentLineNow != 0 ) currentLine = currentLineNow - 1; else // currentLineNow == 0 return; break; case WXK_PAGEDOWN: PageDown(); currentLine = GetFirstVisibleLine(); break; case WXK_PAGEUP: if ( currentLineNow == (int)GetFirstVisibleLine() ) { PageUp(); } currentLine = GetFirstVisibleLine(); break; case WXK_SPACE: // hack: pressing space should work like a mouse click rather than // like a keyboard arrow press, so trick DoHandleItemClick() in // thinking we were clicked flags &= ~ItemClick_Kbd; currentLine = currentLineNow; break; #ifdef __WXMSW__ case WXK_TAB: // Since we are using wxWANTS_CHARS we need to send navigation // events for the tabs on MSW { wxNavigationKeyEvent ne; ne.SetDirection(!event.ShiftDown()); ne.SetCurrentFocus(this); ne.SetEventObject(this); GetParent()->GetEventHandler()->ProcessEvent(ne); } // fall through to default #endif default: event.Skip(); currentLine = 0; // just to silent the stupid compiler warnings wxUnusedVar(currentNow); return; } #if 0 if ( event.ShiftDown() ) flags |= ItemClick_Shift; if ( event.ControlDown() ) flags |= ItemClick_Ctrl; DoHandleItemClick(current, flags); #endif #endif }
void CHTRichEditCtrl::AddLine(LPCTSTR pszMsg, int iLen, bool bLink, COLORREF cr, COLORREF bk, DWORD mask) { int iMsgLen = (iLen == -1) ? _tcslen(pszMsg) : iLen; if (iMsgLen == 0) return; #ifdef _DEBUG // if (pszMsg[iMsgLen - 1] == _T('\n')) // ASSERT( iMsgLen >= 2 && pszMsg[iMsgLen - 2] == _T('\r') ); #endif // Get Edit contents dimensions and cursor position long lStartChar, lEndChar; GetSel(lStartChar, lEndChar); int iSize = GetWindowTextLength(); if (lStartChar == iSize && iSize == lEndChar) { // The cursor resides at the end of text SCROLLINFO si; si.cbSize = sizeof si; si.fMask = SIF_ALL; if (m_bAutoScroll && GetScrollInfo(SB_VERT, &si) && si.nPos >= (int)(si.nMax - si.nPage + 1)) { // Not scrolled away SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask); if (m_bAutoScroll && !IsWindowVisible()) ScrollToLastLine(); } else { // Reduce flicker by ignoring WM_PAINT m_bNoPaint = true; BOOL bIsVisible = IsWindowVisible(); if (bIsVisible) SetRedraw(FALSE); // Remember where we are int iFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0; // Select at the end of text and replace the selection // This is a very fast way to add text to an edit control SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask); //if (m_bAutoScroll && lStartChar == lEndChar) // lStartChar = lEndChar = -1; SetSel(lStartChar, lEndChar); // Restore our previous selection if (!m_bAutoScroll) LineScroll(iFirstLine - GetFirstVisibleLine()); else ScrollToLastLine(); m_bNoPaint = false; if (bIsVisible){ SetRedraw(); if (m_bRichEdit) Invalidate(); } } } else { // We should add the text anyway... // Reduce flicker by ignoring WM_PAINT m_bNoPaint = true; BOOL bIsVisible = IsWindowVisible(); if (bIsVisible) SetRedraw(FALSE); // Remember where we are int iFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0; // Very annoying problems with EM_GETSCROLLPOS/EM_SETSCROLLPOS. Depending // on the amount of data in the control, the control may start to scroll up // by itself(!!) -- obviously because of some internal rounding errors.. // // Using 'LineScroll' also gives glitches (also depending on the amount of // data stored in the control), but at least it doesn't start to show some 'life' /*POINT ptScrollPos; if (!m_bAutoScroll) SendMessage(EM_GETSCROLLPOS, 0, (LPARAM)&ptScrollPos);*/ if (lStartChar != lEndChar) { // If we are currently selecting some text, we have to find out // if the caret is near the beginning of this block or near the end. // Note that this does not always work. Because of the EM_CHARFROMPOS // message returning only 16 bits this will fail if the user has selected // a block with a length dividable by 64k. // NOTE: This may cause a lot of terrible CRASHES within the RichEdit control when used for a RichEdit control!? // To reproduce the crash: click in the RE control while it's drawing a line and start a selection! if (!m_bRichEdit){ CPoint pt; ::GetCaretPos(&pt); int iCaretPos = CharFromPos(pt); if (abs((lStartChar % 0xffff - iCaretPos)) < abs((lEndChar % 0xffff - iCaretPos))) { iCaretPos = lStartChar; lStartChar = lEndChar; lEndChar = iCaretPos; } } } // Note: This will flicker, if someone has a good idea how to prevent this - let me know // Select at the end of text and replace the selection // This is a very fast way to add text to an edit control SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask); //if (m_bAutoScroll && lStartChar == lEndChar) // lStartChar = lEndChar = -1; SetSel(lStartChar, lEndChar); // Restore our previous selection if (!m_bAutoScroll){ LineScroll(iFirstLine - GetFirstVisibleLine()); //SendMessage(EM_SETSCROLLPOS, 0, (LPARAM)&ptScrollPos); } else ScrollToLastLine(); m_bNoPaint = false; if (bIsVisible){ SetRedraw(); if (m_bRichEdit) Invalidate(); } } }
void wxSymbolListCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { // If size is larger, recalculate double buffer bitmap wxSize clientSize = GetClientSize(); if ( !m_doubleBuffer || clientSize.x > m_doubleBuffer->GetWidth() || clientSize.y > m_doubleBuffer->GetHeight() ) { delete m_doubleBuffer; m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25); } wxBufferedPaintDC dc(this,*m_doubleBuffer); // the update rectangle wxRect rectUpdate = GetUpdateClientRect(); // fill it with background colour dc.SetBackground(GetBackgroundColour()); dc.Clear(); // set the font to be displayed dc.SetFont(GetFont()); // the bounding rectangle of the current line wxRect rectLine; rectLine.width = clientSize.x; dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.SetBackgroundMode(wxTRANSPARENT); // iterate over all visible lines const size_t lineMax = GetVisibleEnd(); for ( size_t line = GetFirstVisibleLine(); line < lineMax; line++ ) { const wxCoord hLine = OnGetLineHeight(line); rectLine.height = hLine; // and draw the ones which intersect the update rect if ( rectLine.Intersects(rectUpdate) ) { // don't allow drawing outside of the lines rectangle wxDCClipper clip(dc, rectLine); wxRect rect = rectLine; rect.Deflate(m_ptMargins.x, m_ptMargins.y); OnDrawItem(dc, rect, line); } else // no intersection { if ( rectLine.GetTop() > rectUpdate.GetBottom() ) { // we are already below the update rect, no need to continue // further break; } //else: the next line may intersect the update rect } rectLine.y += hLine; } }
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; }
void CUrlRichEditCtrl::ParseAndFormatText(BOOL bForceReformat) { KillTimer(TIMER_REPARSE); AF_NOREENTRANT // prevent reentrancy // parse the control content CString sText; GetWindowText(sText); // richedit2 uses '\r\n' whereas richedit uses just '\n' if (!CWinClasses::IsClass(*this, WC_RICHEDIT)) sText.Replace(_T("\r\n"), _T("\n")); // parse the text into an array of URLPOS CUrlArray aUrls; LPCTSTR szText = sText; BOOL bPrevDelim = TRUE; int nPos = 0; BOOL bBracedFile = FALSE; while (*szText) { // if nChar < 0 then its a multibyte char and can't be part // of a url, so we bump the text buffer by 2 but the pos by 1 #ifndef _UNICODE TCHAR nChar = *szText; if (IsDBCSLeadByte(nChar)) { szText++; szText++; nPos++; continue; } #endif // if the previous item was not a delimiter then there's no // point checking for a protocol match so we just update the // value of bPrevDelim for the current char if (!bPrevDelim) { bPrevDelim = IsDelim(szText); szText++; nPos++; continue; } // if the current char is a delim then this can't be the start // of a url either else if (IsDelim(szText)) { bPrevDelim = TRUE; szText++; nPos++; continue; } // now check for a protocol int nProt = MatchProtocol(szText); // if no match then increment pos and go to next char if (nProt == -1) { bPrevDelim = FALSE; szText++; nPos++; continue; } // check for braces (<...>) if (nPos > 0) bBracedFile = (szText[-1] == '<'); else bBracedFile = FALSE; // find the end of the url (URLDELIMS) int nLen = 0; LPCTSTR szStart = szText; if (bBracedFile) { while (*szText && *szText != '>') { szText++; nLen++; } } else { while (!IsDelim(szText)) { szText++; nLen++; } } bPrevDelim = TRUE; // save the result URLITEM urli; urli.cr.cpMin = nPos; urli.cr.cpMax = urli.cr.cpMin + nLen; nPos += nLen; // make sure the url does not end in a punctuation mark while (ENDPUNCTUATION.Find(szStart[nLen - 1]) != -1) { nLen--; urli.cr.cpMax--; } // Only save if the link is more than just the protocol if (nLen > m_aProtocols[nProt].sProtocol.GetLength()) { urli.sUrl = CString(szStart, nLen); urli.bWantNotify = m_aProtocols[nProt].bWantNotify; InsertInOrder(urli, aUrls); } } // compare aUrls with m_aUrls to see if anything has changed BOOL bReformat = !sText.IsEmpty() && (bForceReformat || !UrlsMatch(aUrls)); // then overwrite (always) m_aUrls.Copy(aUrls); if (bReformat) { BOOL bVisible = IsWindowVisible(); CRePauseUndo rep(*this); if (bVisible) SetRedraw(FALSE); // save current selection CHARRANGE crSel; GetSel(crSel); // and first line int nFirstLine = GetFirstVisibleLine(); // save/reset event mask DWORD dwEventMask = SetEventMask(0); // retrieve default character attribs CHARFORMAT cf; cf.cbSize = sizeof(cf); cf.dwMask = CFM_LINK; // format urls int nUrls = aUrls.GetSize(); CHARRANGE cr = { 0, 0 }; for (int nUrl = 0; nUrl < nUrls; nUrl++) { // clear formatting from the end of the previous // url to the start of this url cr.cpMax = aUrls[nUrl].cr.cpMin; cf.dwEffects = 0; SetSel(cr); SetSelectionCharFormat(cf); // update for next url cr.cpMin = aUrls[nUrl].cr.cpMax; // then format url cf.dwEffects = CFM_LINK; SetSel(aUrls[nUrl].cr); SetSelectionCharFormat(cf); } // clear formatting for whatever's left cr.cpMax = -1; cf.dwEffects = 0; SetSel(cr); SetSelectionCharFormat(cf); // restore selection SetSel(crSel); // and first line SetFirstVisibleLine(nFirstLine); // restore event mask SetEventMask(dwEventMask); if (bVisible) { SetRedraw(TRUE); Invalidate(FALSE); } } }
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); } } }
/** * Style needed */ void FbEditor::onStyleNeeded(wxStyledTextEvent & event) { // startint position auto startPos = GetEndStyled(); auto startLine = LineFromPosition(startPos); startPos = PositionFromLine(startLine); // end position int lastPos = event.GetPosition(); int lastLine = std::max(LineFromPosition(lastPos), std::min(GetLineCount(), GetFirstVisibleLine() + LinesOnScreen())); lastPos = GetLineEndPosition(lastLine); // get token auto token = m_srcCtx->getLine(startLine, lastLine); // set stylling position StartStyling(startPos, INT_MAX); // clear indicatirs SetIndicatorCurrent(ErrorIndicator); IndicatorClearRange(startPos, lastPos - startPos); // no token? just colour to default if (!token) { style(lastPos - startPos, TokenStyle::Default); return; } // style the tokens int line = startLine; int col = 0; while (token && line <= lastLine) { // end of the line? if (token->getKind() == TokenKind::EndOfLine) { token = token->getNext(); continue; } // token line int tline = token->getLine(); // token started before current line if (line > tline) { int start = PositionFromLine(line); int end = PositionFromLine(token->getEndLine()) + token->getEndCol(); style(end - start, token); // end on line and column col = token->getEndCol(); line = token->getEndLine(); // get next token and continue token = token->getNext(); continue; } // empty lines before next token? if (line < tline) { int start = PositionFromLine(line) + col; int end = PositionFromLine(tline) + token->getCol(); style(end - start, TokenStyle::Default); // end on line and column line = token->getLine(); col = token->getCol(); continue; } // started on the current line if (line == tline) { // empty space ? if (token->getCol() > col) { style(token->getCol() - col, TokenStyle::Default); } // style the token style(token->getLength(), token); col = token->getEndCol(); line = token->getEndLine(); // advance to the next one token = token->getNext(); continue; } // some empty space till end of the line int length = GetLineLength(line); if (col < length) { style(length - col, TokenStyle::Default); } // incement line line++; col = 0; } }
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; }
////////////////////////////////////////////////////////////////////////////// // This function is based on Daniel Lohmann's article "CEditLog - fast logging // into an edit control with cout" at http://www.codeproject.com void CLogEditCtrl::AddLine(LPCTSTR pszMsg, int iLen) { int iMsgLen = (iLen == -1) ? _tcslen(pszMsg) : iLen; if (iMsgLen == 0) return; #ifdef _DEBUG if (pszMsg[iMsgLen - 1] == _T('\n')) ASSERT( iMsgLen >= 2 && pszMsg[iMsgLen - 2] == _T('\r') ); #endif // Get Edit contents dimensions and cursor position int iStartChar, iEndChar; GetSel(iStartChar, iEndChar); int iWndTxtLen = GetWindowTextLength(); if (iStartChar == iWndTxtLen && iWndTxtLen == iEndChar) { // The cursor resides at the end of text SCROLLINFO si; si.cbSize = sizeof si; si.fMask = SIF_ALL; if (m_bAutoScroll && GetScrollInfo(SB_VERT, &si) && si.nPos >= (int)(si.nMax - si.nPage + 1)) { // Not scrolled away SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar); if (m_bAutoScroll && !IsWindowVisible()) ScrollToLastLine(); } else { // Reduce flicker by ignoring WM_PAINT m_bNoPaint = true; BOOL bIsVisible = IsWindowVisible(); if (bIsVisible) SetRedraw(FALSE); // Remember where we are int nFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0; // Select at the end of text and replace the selection // This is a very fast way to add text to an edit control SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar); SetSel(iStartChar, iEndChar, TRUE); // Restore our previous selection if (!m_bAutoScroll) LineScroll(nFirstLine - GetFirstVisibleLine()); else ScrollToLastLine(); m_bNoPaint = false; if (bIsVisible){ SetRedraw(); if (m_bRichEdit) Invalidate(); } } } else { // We should add the text anyway... // Reduce flicker by ignoring WM_PAINT m_bNoPaint = true; BOOL bIsVisible = IsWindowVisible(); if (bIsVisible) SetRedraw(FALSE); // Remember where we are int nFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0; if (iStartChar != iEndChar) { // If we are currently selecting some text, we have to find out // if the caret is near the beginning of this block or near the end. // Note that this does not always work. Because of the EM_CHARFROMPOS // message returning only 16 bits this will fail if the user has selected // a block with a length dividable by 64k. // NOTE: This may cause a lot of terrible CRASHES within the RichEdit control when used for a RichEdit control!? // To reproduce the crash: click in the RE control while it's drawing a line an start a selection! if (!m_bRichEdit){ CPoint pt; ::GetCaretPos(&pt); int nCaretPos = CharFromPos(pt); if (abs((iStartChar % 0xffff - nCaretPos)) < abs((iEndChar % 0xffff - nCaretPos))) { nCaretPos = iStartChar; iStartChar = iEndChar; iEndChar = nCaretPos; } } } // Note: This will flicker, if someone has a good idea how to prevent this - let me know // Select at the end of text and replace the selection // This is a very fast way to add text to an edit control SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar); SetSel(iStartChar, iEndChar, TRUE); // Restore our previous selection if (!m_bAutoScroll) LineScroll(nFirstLine - GetFirstVisibleLine()); else ScrollToLastLine(); m_bNoPaint = false; if (bIsVisible){ SetRedraw(); if (m_bRichEdit) Invalidate(); } } }