*
* @brief Implementation of the CCrystalTextView class
*/
-// ID line follows -- this is updated by SVN
-// $Id: ccrystaltextview.cpp 7117 2010-02-01 14:24:51Z sdottaka $
#include "StdAfx.h"
-#include <vector>
-#include <algorithm>
-#include <malloc.h>
-#include <imm.h> /* IME */
+#include "ccrystaltextview.h"
#include "editcmd.h"
#include "editreg.h"
-#include "ccrystaltextview.h"
#include "ccrystaltextbuffer.h"
#include "ccrystaltextmarkers.h"
#include "ViewableWhitespace.h"
#include "dialogs/gotodlg.h"
#include "utils/fpattern.h"
#include "utils/filesup.h"
-#include "utils/registry.h"
#include "utils/string_util.h"
#include "utils/wcwidth.h"
#include "utils/icu.hpp"
+#include <vector>
+#include <algorithm>
+#include <numeric>
+#include <malloc.h>
+#include <imm.h> /* IME */
using std::vector;
using CrystalLineParser::TEXTBLOCK;
/** @brief Width of revision marks. */
const UINT MARGIN_REV_WIDTH = 3;
-/** @brief Width of icons printed in the margin. */
-const UINT MARGIN_ICON_WIDTH = 12;
-/** @brief Height of icons printed in the margin. */
-const UINT MARGIN_ICON_HEIGHT = 12;
/** @brief Color of unsaved line revision mark (dark yellow). */
-const COLORREF UNSAVED_REVMARK_CLR = RGB(0xD7, 0xD7, 0x00);
+const CEColor UNSAVED_REVMARK_CLR{ 0xD7, 0xD7, 0x00 };
/** @brief Color of saved line revision mark (green). */
-const COLORREF SAVED_REVMARK_CLR = RGB(0x00, 0xFF, 0x00);
+const CEColor SAVED_REVMARK_CLR{ 0x00, 0xFF, 0x00 };
#define SMOOTH_SCROLL_FACTOR 6
IMPLEMENT_DYNCREATE (CCrystalTextView, CView)
HINSTANCE CCrystalTextView::s_hResourceInst = nullptr;
-CCrystalTextView::RENDERING_MODE CCrystalTextView::s_nRenderingModeDefault = RENDERING_MODE_GDI;
-
-static ptrdiff_t FindStringHelper(LPCTSTR pszLineBegin, size_t nLineLength, LPCTSTR pszFindWhere, LPCTSTR pszFindWhat, DWORD dwFlags, int &nLen, RxNode *&rxnode, RxMatchRes *rxmatch);
+CCrystalTextView::RENDERING_MODE CCrystalTextView::s_nRenderingModeDefault = RENDERING_MODE::GDI;
BEGIN_MESSAGE_MAP (CCrystalTextView, CView)
//{{AFX_MSG_MAP(CCrystalTextView)
ON_COMMAND (ID_EDIT_GOTO, OnEditGoTo)
ON_UPDATE_COMMAND_UI (ID_VIEW_TOGGLE_SRC_HDR, OnUpdateToggleSourceHeader)
ON_COMMAND (ID_VIEW_TOGGLE_SRC_HDR, OnToggleSourceHeader)
+ON_UPDATE_COMMAND_UI (ID_VIEW_TOPMARGIN, OnUpdateTopMargin)
+ON_COMMAND (ID_VIEW_TOPMARGIN, OnTopMargin)
ON_UPDATE_COMMAND_UI (ID_VIEW_SELMARGIN, OnUpdateSelMargin)
ON_COMMAND (ID_VIEW_SELMARGIN, OnSelMargin)
ON_UPDATE_COMMAND_UI (ID_VIEW_WORDWRAP, OnUpdateWordWrap)
ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_INCREMENTAL_FORWARD, OnUpdateEditFindIncrementalForward)
ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_INCREMENTAL_BACKWARD, OnUpdateEditFindIncrementalBackward)
//END SW
-ON_COMMAND (ID_EDIT_TOGGLE_COLUMNSELECTION, OnToggleColumnSelection)
+ ON_COMMAND (ID_EDIT_TOGGLE_COLUMNSELECTION, OnToggleColumnSelection)
END_MESSAGE_MAP ()
#define EXPAND_PRIMITIVE(impl, func) \
-void CCrystalTextView::On##func() { m_bColumnSelection = false; impl(false); } \
+void CCrystalTextView::On##func() { m_bRectangularSelection = false; impl(false); } \
void CCrystalTextView::OnExt##func() { impl(true); }
EXPAND_PRIMITIVE (MoveLeft, CharLeft)
EXPAND_PRIMITIVE (MoveRight, CharRight)
EXPAND_PRIMITIVE (MoveCtrlEnd, TextEnd)
#undef EXPAND_PRIMITIVE
-// Tabsize is commented out since we have only GUI setting for it now.
-// Not removed because we may later want to have per-filetype settings again.
-// See ccrystaltextview.h for table declaration.
-CCrystalTextView::TextDefinition CCrystalTextView::m_SourceDefs[] =
- {
- CCrystalTextView::SRC_PLAIN, _T ("Plain"), _T ("txt,doc,diz"), &CrystalLineParser::ParseLinePlain, SRCOPT_AUTOINDENT, /*4,*/ _T (""), _T (""), _T (""), (DWORD)-1,
- CCrystalTextView::SRC_ASP, _T ("ASP"), _T ("asp,ascx"), &CrystalLineParser::ParseLineAsp, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T (""), _T (""), _T ("'"), (DWORD)-1,
- CCrystalTextView::SRC_BASIC, _T ("Basic"), _T ("bas,vb,vbs,frm,dsm,cls,ctl,pag,dsr"), &CrystalLineParser::ParseLineBasic, SRCOPT_AUTOINDENT, /*4,*/ _T (""), _T (""), _T ("\'"), (DWORD)-1,
- CCrystalTextView::SRC_BATCH, _T ("Batch"), _T ("bat,btm,cmd"), &CrystalLineParser::ParseLineBatch, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT, /*4,*/ _T (""), _T (""), _T ("rem "), (DWORD)-1,
- CCrystalTextView::SRC_C, _T ("C"), _T ("c,cc,cpp,cxx,h,hpp,hxx,hm,inl,rh,tlh,tli,xs"), &CrystalLineParser::ParseLineC, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_CSHARP, _T ("C#"), _T ("cs"), &CrystalLineParser::ParseLineCSharp, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_CSS, _T ("CSS"), _T ("css"), &CrystalLineParser::ParseLineCss, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T (""), (DWORD)-1,
- CCrystalTextView::SRC_DCL, _T ("DCL"), _T ("dcl,dcc"), &CrystalLineParser::ParseLineDcl, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_FORTRAN, _T ("Fortran"), _T ("f,f90,f9p,fpp,for,f77"), &CrystalLineParser::ParseLineFortran, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT, /*8,*/ _T (""), _T (""), _T ("!"), (DWORD)-1,
- CCrystalTextView::SRC_GO, _T ("Go"), _T ("go"), &CrystalLineParser::ParseLineGo, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_HTML, _T ("HTML"), _T ("html,htm,shtml,ihtml,ssi,stm,stml,jsp"), &CrystalLineParser::ParseLineHtml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("<!--"), _T ("-->"), _T (""), (DWORD)-1,
- CCrystalTextView::SRC_INI, _T ("INI"), _T ("ini,reg,vbp,isl"), &CrystalLineParser::ParseLineIni, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU|SRCOPT_EOLNUNIX, /*2,*/ _T (""), _T (""), _T (";"), (DWORD)-1,
- CCrystalTextView::SRC_INNOSETUP, _T ("InnoSetup"), _T ("iss"), &CrystalLineParser::ParseLineInnoSetup, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("{"), _T ("}"), _T (";"), (DWORD)-1,
- CCrystalTextView::SRC_INSTALLSHIELD, _T ("InstallShield"), _T ("rul"), &CrystalLineParser::ParseLineIS, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_JAVA, _T ("Java"), _T ("java,jav,js"), &CrystalLineParser::ParseLineJava, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_LISP, _T ("AutoLISP"), _T ("lsp,dsl"), &CrystalLineParser::ParseLineLisp, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T (";|"), _T ("|;"), _T (";"), (DWORD)-1,
- CCrystalTextView::SRC_LUA, _T ("Lua"), _T ("lua"), &CrystalLineParser::ParseLineLua, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("--[["), _T ("]]"), _T ("--"), (DWORD)-1,
- CCrystalTextView::SRC_NSIS, _T ("NSIS"), _T ("nsi,nsh"), &CrystalLineParser::ParseLineNsis, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T (";"), (DWORD)-1,
- CCrystalTextView::SRC_PASCAL, _T ("Pascal"), _T ("pas"), &CrystalLineParser::ParseLinePascal, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("{"), _T ("}"), _T (""), (DWORD)-1,
- CCrystalTextView::SRC_PERL, _T ("Perl"), _T ("pl,pm,plx"), &CrystalLineParser::ParseLinePerl, SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, /*4,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_PHP, _T ("PHP"), _T ("php,php3,php4,php5,phtml"), &CrystalLineParser::ParseLinePhp, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_PO, _T ("PO"), _T ("po,pot"), &CrystalLineParser::ParseLinePo, SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, /*4,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_POWERSHELL, _T ("PowerShell"), _T ("ps1"), &CrystalLineParser::ParseLinePowerShell, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_PYTHON, _T ("Python"), _T ("py"), &CrystalLineParser::ParseLinePython, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_REXX, _T ("REXX"), _T ("rex,rexx"), &CrystalLineParser::ParseLineRexx, SRCOPT_AUTOINDENT, /*4,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_RSRC, _T ("Resources"), _T ("rc,dlg,r16,r32,rc2"), &CrystalLineParser::ParseLineRsrc, SRCOPT_AUTOINDENT, /*4,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_RUBY, _T ("Ruby"), _T ("rb,rbw,rake,gemspec"), &CrystalLineParser::ParseLineRuby, SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, /*4,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_RUST, _T ("Rust"), _T ("rs"), &CrystalLineParser::ParseLineRust, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_SGML, _T ("Sgml"), _T ("sgml"), &CrystalLineParser::ParseLineSgml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("<!--"), _T ("-->"), _T (""), (DWORD)-1,
- CCrystalTextView::SRC_SH, _T ("Shell"), _T ("sh,conf"), &CrystalLineParser::ParseLineSh, SRCOPT_INSERTTABS|SRCOPT_AUTOINDENT|SRCOPT_EOLNUNIX, /*4,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_SIOD, _T ("SIOD"), _T ("scm"), &CrystalLineParser::ParseLineSiod, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU, /*2,*/ _T (";|"), _T ("|;"), _T (";"), (DWORD)-1,
- CCrystalTextView::SRC_SQL, _T ("SQL"), _T ("sql"), &CrystalLineParser::ParseLineSql, SRCOPT_AUTOINDENT, /*4,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_TCL, _T ("TCL"), _T ("tcl"), &CrystalLineParser::ParseLineTcl, SRCOPT_AUTOINDENT|SRCOPT_BRACEGNU|SRCOPT_EOLNUNIX, /*2,*/ _T (""), _T (""), _T ("#"), (DWORD)-1,
- CCrystalTextView::SRC_TEX, _T ("TEX"), _T ("tex,sty,clo,ltx,fd,dtx"), &CrystalLineParser::ParseLineTex, SRCOPT_AUTOINDENT, /*4,*/ _T (""), _T (""), _T ("%"), (DWORD)-1,
- CCrystalTextView::SRC_VERILOG, _T ("Verilog"), _T ("v,vh"), &CrystalLineParser::ParseLineVerilog, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("/*"), _T ("*/"), _T ("//"), (DWORD)-1,
- CCrystalTextView::SRC_VHDL, _T ("VHDL"), _T ("vhd,vhdl,vho"), &CrystalLineParser::ParseLineVhdl, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T (""), _T (""), _T ("--"), (DWORD)-1,
- CCrystalTextView::SRC_XML, _T ("XML"), _T ("xml"), &CrystalLineParser::ParseLineXml, SRCOPT_AUTOINDENT|SRCOPT_BRACEANSI, /*2,*/ _T ("<!--"), _T ("-->"), _T (""), (DWORD)-1
- };
-
/////////////////////////////////////////////////////////////////////////////
// CCrystalTextView construction/destruction
-bool
-MatchType (CString pattern, LPCTSTR lpszExt)
-{
- CString part;
- int pos, len = pattern.GetLength ();
-
- while ((pos = pattern.Find (_T (','))) != -1)
- {
- part = pattern.Left (pos);
- if (!part.IsEmpty () && fpattern_isvalid (part))
- {
- if (fpattern_matchn (part, lpszExt))
- {
- return true;
- }
- }
- len -= pos + 1;
- pattern = pattern.Right (len);
- }
- if (!pattern.IsEmpty () && fpattern_isvalid (pattern))
- {
- if (fpattern_matchn (pattern, lpszExt))
- {
- return true;
- }
- }
- return false;
-}
-
bool CCrystalTextView::
-DoSetTextType (TextDefinition *def)
+DoSetTextType (CrystalLineParser::TextDefinition *def)
{
m_CurSourceDef = def;
SetFlags (def->flags);
return true;
}
-CCrystalTextView::TextDefinition* CCrystalTextView::
-GetTextType (LPCTSTR pszExt)
-{
- TextDefinition *def;
- CString sExt = pszExt;
-
- def = CCrystalTextView::m_SourceDefs;
- sExt.MakeLower ();
- for (int i = 0; i < _countof (CCrystalTextView::m_SourceDefs); i++, def++)
- if (MatchType (def->exts, sExt))
- return def;
- return nullptr;
-}
-
bool CCrystalTextView::
-SetTextType (LPCTSTR pszExt)
+SetTextType (const tchar_t* pszExt)
{
- m_CurSourceDef = m_SourceDefs;
+ m_CurSourceDef = CrystalLineParser::m_SourceDefs;
- TextDefinition *def = GetTextType (pszExt);
+ CrystalLineParser::TextDefinition *def = CrystalLineParser::GetTextType (pszExt);
return SetTextType (def);
}
bool CCrystalTextView::
-SetTextType (CCrystalTextView::TextType enuType)
+SetTextType (CrystalLineParser::TextType enuType)
{
- TextDefinition *def;
+ CrystalLineParser::TextDefinition *def;
- m_CurSourceDef = def = m_SourceDefs;
- for (int i = 0; i < _countof (m_SourceDefs); i++, def++)
+ m_CurSourceDef = def = CrystalLineParser::m_SourceDefs;
+ for (int i = 0; i < _countof (CrystalLineParser::m_SourceDefs); i++, def++)
{
if (def->type == enuType)
{
}
bool CCrystalTextView::
-SetTextType (CCrystalTextView::TextDefinition *def)
+SetTextType (CrystalLineParser::TextDefinition *def)
{
if (def)
if (m_CurSourceDef != def)
return false;
}
-void CCrystalTextView::
-LoadSettings ()
-{
- TextDefinition *def = m_SourceDefs;
- bool bFontLoaded;
- CReg reg;
- if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ))
- {
- reg.LoadNumber (_T ("DefaultEncoding"), (DWORD*) &CCrystalTextBuffer::m_nDefaultEncoding);
- for (int i = 0; i < _countof (m_SourceDefs); i++, def++)
- {
- CReg reg1;
- if (reg1.Open (reg.hKey, def->name, KEY_READ))
- {
- reg1.LoadString (_T ("Extensions"), def->exts, _countof (def->exts));
- reg1.LoadNumber (_T ("Flags"), &def->flags);
-// reg1.LoadNumber (_T ("TabSize"), &def->tabsize);
- reg1.LoadString (_T ("OpenComment"), def->opencomment, _countof (def->opencomment));
- reg1.LoadString (_T ("CloseComment"), def->closecomment, _countof (def->closecomment));
- reg1.LoadString (_T ("CommentLine"), def->commentline, _countof (def->commentline));
- reg1.LoadNumber (_T ("DefaultEncoding"), &def->encoding);
- }
- }
- bFontLoaded = reg.LoadBinary (_T ("LogFont"), (LPBYTE) &m_LogFont, sizeof (m_LogFont));
- }
- else
- bFontLoaded = false;
- if (!bFontLoaded)
- {
- CWindowDC dc (CWnd::GetDesktopWindow ());
- NONCLIENTMETRICS info;
- info.cbSize = sizeof(info);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
- memcpy (&m_LogFont, &info.lfMessageFont, sizeof (LOGFONT));
- m_LogFont.lfHeight = -MulDiv (11, dc.GetDeviceCaps (LOGPIXELSY), 72);
- m_LogFont.lfWeight = FW_NORMAL;
- m_LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
- m_LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- m_LogFont.lfQuality = DEFAULT_QUALITY;
- m_LogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
- _tcscpy_s (m_LogFont.lfFaceName, _T ("Courier New"));
- }
-}
-
-void CCrystalTextView::
-SaveSettings ()
-{
- TextDefinition *def = m_SourceDefs;
- CReg reg;
- if (reg.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE))
- {
- VERIFY (reg.SaveNumber (_T ("DefaultEncoding"), (DWORD) CCrystalTextBuffer::m_nDefaultEncoding));
- for (int i = 0; i < _countof (m_SourceDefs); i++, def++)
- {
- CReg reg1;
- if (reg1.Create (reg.hKey, def->name, KEY_WRITE))
- {
- VERIFY (reg1.SaveString (_T ("Extensions"), def->exts));
- VERIFY (reg1.SaveNumber (_T ("Flags"), def->flags));
-// VERIFY (reg1.SaveNumber (_T ("TabSize"), def->tabsize));
- VERIFY (reg1.SaveString (_T ("OpenComment"), def->opencomment));
- VERIFY (reg1.SaveString (_T ("CloseComment"), def->closecomment));
- VERIFY (reg1.SaveString (_T ("CommentLine"), def->commentline));
- VERIFY (reg1.SaveNumber (_T ("DefaultEncoding"), def->encoding));
- }
- }
- VERIFY (reg.SaveBinary (_T ("LogFont"), (LPBYTE) &m_LogFont, sizeof (m_LogFont)));
- }
-}
-
CCrystalTextView::CCrystalTextView ()
: m_nScreenChars(-1)
, m_pFindTextDlg(nullptr)
, m_CurSourceDef(nullptr)
, m_dwLastDblClickTime(0)
-, m_iterWord(UBRK_WORD, "en", nullptr, 0)
, m_rxnode(nullptr)
, m_pszMatched(nullptr)
+, m_bTopMargin(false)
, m_bSelMargin(true)
, m_bViewLineNumbers(false)
, m_bWordWrap(false)
, m_bLastSearch(false)
, m_bBookmarkExist(false)
, m_bSingle(false) // needed to be set in descendat classes
-, m_bRememberLastPos(false)
, m_pColors(nullptr)
, m_nLastLineIndexCalculatedSubLineIndex(-1)
, m_hAccel(nullptr)
, m_dwFlags(0)
, m_nScreenLines(0)
, m_pMarkers(nullptr)
-, m_panSubLines(new CArray<int, int>())
-, m_panSubLineIndexCache(new CArray<int, int>())
+, m_panSubLines(new std::vector<int>())
+, m_panSubLineIndexCache(new std::vector<int>())
, m_pstrIncrementalSearchString(new CString)
, m_pstrIncrementalSearchStringOld(new CString)
-, m_ParseCookies(new vector<DWORD>)
+, m_ParseCookies(new vector<uint32_t>)
, m_pnActualLineLength(new vector<int>)
, m_nIdealCharPos(0)
, m_bFocused(false)
, m_bDragSelection(false)
, m_bWordSelection(false)
, m_bLineSelection(false)
+, m_bRectangularSelection(false)
, m_bColumnSelection(false)
, m_nDragSelTimer(0)
-, m_bOverrideCaret(false)
+, m_bOvrMode(false)
, m_nLastFindWhatLen(0)
, m_nPrintPages(0)
, m_nPrintLineHeight(0)
, m_rxmatch{}
, m_nRenderingMode(s_nRenderingModeDefault)
, m_pCrystalRendererSaved(nullptr)
+, m_nColumnResizing(-1)
+, m_nLineNumberUsedAsHeaders(-1)
{
#ifdef _WIN64
- if (m_nRenderingMode == RENDERING_MODE_GDI)
+ if (m_nRenderingMode == RENDERING_MODE::GDI)
m_pCrystalRenderer.reset(new CCrystalRendererGDI());
else
- m_pCrystalRenderer.reset(new CCrystalRendererDirectWrite(m_nRenderingMode));
+ m_pCrystalRenderer.reset(new CCrystalRendererDirectWrite(static_cast<int>(m_nRenderingMode)));
#else
m_pCrystalRenderer.reset(new CCrystalRendererGDI());
#endif
- m_panSubLines->SetSize( 0, 4096 );
- m_panSubLineIndexCache->SetSize( 0, 4096 );
+ m_panSubLines->reserve(4096);
+ m_panSubLines->resize(0);
+ m_panSubLineIndexCache->reserve (4096);
+ m_panSubLineIndexCache->resize ( 0);
//END SW
CCrystalTextView::ResetView ();
- SetTextType (SRC_PLAIN);
+ SetTextType (CrystalLineParser::SRC_PLAIN);
}
CCrystalTextView::~CCrystalTextView ()
RxFree (m_rxnode);
m_rxnode = nullptr;
- free(m_pszMatched); // Allocated by _tcsdup()
+ free(m_pszMatched); // Allocated by tc::tcsdup()
m_pszMatched = nullptr;
//BEGIN SW
delete m_pnActualLineLength;
m_pnActualLineLength = nullptr;
if (m_pMarkers != nullptr)
- m_pMarkers->DeleteView(this);
+ m_pMarkers->DeleteView(this);
}
BOOL CCrystalTextView::
{
// View must always create its own scrollbars,
// if only it's not used within splitter
- //BEGIN SW
- if( m_bWordWrap )
- // we do not need a horizontal scroll bar, if we wrap the lines
- cs.style|= WS_VSCROLL;
- else
+ //BEGIN SW
+ if( GetTextLayoutMode () == TEXTLAYOUT_WORDWRAP )
+ // we do not need a horizontal scroll bar, if we wrap the lines
+ cs.style|= WS_VSCROLL;
+ else
+ cs.style |= (WS_HSCROLL | WS_VSCROLL);
+ /*ORIGINAL
cs.style |= (WS_HSCROLL | WS_VSCROLL);
- /*ORIGINAL
- cs.style |= (WS_HSCROLL | WS_VSCROLL);
- */
- //END SW
+ */
+ //END SW
}
cs.lpszClass = AfxRegisterWndClass (CS_DBLCLKS);
return CView::PreCreateWindow (cs);
/////////////////////////////////////////////////////////////////////////////
// CCrystalTextView drawing
-void CCrystalTextView::
-GetSelection (CPoint & ptStart, CPoint & ptEnd)
+std::pair<CEPoint, CEPoint> CCrystalTextView::
+GetSelection ()
{
PrepareSelBounds ();
- ptStart = m_ptDrawSelStart;
- ptEnd = m_ptDrawSelEnd;
+ return { m_ptDrawSelStart, m_ptDrawSelEnd };
}
bool CCrystalTextView::
void CCrystalTextView::
GetFullySelectedLines(int & firstLine, int & lastLine)
{
- CPoint ptStart;
- CPoint ptEnd;
- GetSelection(ptStart, ptEnd);
+ auto [ptStart, ptEnd] = GetSelection ();
if (ptStart.x == 0)
firstLine = ptStart.y;
}
if ((*m_pnActualLineLength)[nLineIndex] != - 1)
- return (*m_pnActualLineLength)[nLineIndex];
+ return (*m_pnActualLineLength)[nLineIndex];
// Actual line length is not determined yet, let's calculate a little
int nActualLength = 0;
int nLength = GetLineLength (nLineIndex);
if (nLength > 0)
{
- LPCTSTR pszChars = GetLineChars (nLineIndex);
+ const tchar_t* pszChars = GetLineChars (nLineIndex);
const int nTabSize = GetTabSize ();
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszChars, nLength);
- for (int i = 0; i < nLength; i = pIterChar->next())
+ switch ( GetTextLayoutMode ())
{
- TCHAR c = pszChars[i];
- if (c == _T('\t'))
- nActualLength += (nTabSize - nActualLength % nTabSize);
- else
- nActualLength += GetCharCellCountFromChar(pszChars + i);
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
+ case TEXTLAYOUT_TABLE_WORDWRAP:
+ {
+ int nColumnCount = m_pTextBuffer->GetColumnCount (nLineIndex);
+ int nColumnTotalWidth = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ for (int i = 0, nColumn = 0; i < nLength; i = pIterChar->next())
+ {
+ tchar_t c = pszChars[i];
+ if (!bInQuote && c == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nActualLength = nColumnTotalWidth;
+ }
+ else
+ {
+ if (c == quote)
+ bInQuote = !bInQuote;
+ if (c == '\t')
+ nActualLength ++;
+ else
+ nActualLength += GetCharCellCountFromChar (pszChars + i);
+ if (nColumn < nColumnCount && nActualLength > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nActualLength = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn);
+ }
+ }
+ }
+ break;
+ default:
+ {
+ for (int i = 0; i < nLength; i = pIterChar->next())
+ {
+ tchar_t c = pszChars[i];
+ if (c == _T('\t'))
+ nActualLength += (nTabSize - nActualLength % nTabSize);
+ else
+ nActualLength += GetCharCellCountFromChar(pszChars + i);
+ }
+ }
}
}
}
void CCrystalTextView::
-ScrollToChar (int nNewOffsetChar, bool bNoSmoothScroll /*= false*/ , bool bTrackScrollBar /*= true*/ )
+ScrollToChar (int nNewOffsetChar, bool bNoSmoothScroll /*= false*/, bool bTrackScrollBar /*= true*/ )
{
//BEGIN SW
// no horizontal scrolling, when word wrapping is enabled
- if( m_bWordWrap )
+ if (GetTextLayoutMode () == TEXTLAYOUT_WORDWRAP)
return;
//END SW
CRect rcScroll;
GetClientRect (&rcScroll);
rcScroll.left += GetMarginWidth ();
+ CRect rcTopMargin(rcScroll.left, rcScroll.top, rcScroll.right, GetTopMarginHeight());
+ InvalidateRect (&rcTopMargin); // Make sure the ruler is drawn correctly when scrolling horizontally
ScrollWindow (nScrollChars * GetCharWidth (), 0, &rcScroll, &rcScroll);
UpdateWindow ();
if (bTrackScrollBar)
{
if (m_nTopSubLine != nNewTopSubLine)
{
+ CRect rcScroll;
+ GetClientRect (&rcScroll);
+
+ if (m_pTextBuffer->GetTableEditing () &&
+ ((m_nTopSubLine > 0 && nNewTopSubLine == 0) || (m_nTopSubLine == 0 && nNewTopSubLine > 0)))
+ {
+ CRect rcTopMargin(rcScroll.left, rcScroll.top, rcScroll.right, GetTopMarginHeight ());
+ InvalidateRect (&rcTopMargin);
+ }
+
+ rcScroll.top += GetTopMarginHeight ();
+
if (bNoSmoothScroll || ! m_bSmoothScroll)
{
// Limit scrolling so that we show one empty line at end of file
// OnDraw() uses m_nTopLine to determine topline
int dummy;
GetLineBySubLine(m_nTopSubLine, m_nTopLine, dummy);
- ScrollWindow(0, nScrollLines * GetLineHeight());
+ ScrollWindow(0, nScrollLines * GetLineHeight(), rcScroll, rcScroll);
UpdateWindow();
if (bTrackScrollBar)
{
RecalcVertScrollBar(true);
- RecalcHorzScrollBar();
+ InvalidateHorzScrollBar ();
}
}
else
nTopSubLine = nNewTopSubLine;
const int nScrollLines = nTopSubLine - m_nTopSubLine;
m_nTopSubLine = nTopSubLine;
- ScrollWindow(0, - nLineHeight * nScrollLines);
+ ScrollWindow(0, - nLineHeight * nScrollLines, rcScroll, rcScroll);
UpdateWindow();
if (bTrackScrollBar)
{
RecalcVertScrollBar(true);
- RecalcHorzScrollBar();
+ InvalidateHorzScrollBar ();
}
}
}
nTopSubLine = nNewTopSubLine;
const int nScrollLines = nTopSubLine - m_nTopSubLine;
m_nTopSubLine = nTopSubLine;
- ScrollWindow(0, - nLineHeight * nScrollLines);
+ ScrollWindow(0, - nLineHeight * nScrollLines, rcScroll, rcScroll);
UpdateWindow();
if (bTrackScrollBar)
{
RecalcVertScrollBar(true);
- RecalcHorzScrollBar();
+ InvalidateHorzScrollBar ();
}
}
}
}
void CCrystalTextView::
-ScrollToLine (int nNewTopLine, bool bNoSmoothScroll /*= false*/ , bool bTrackScrollBar /*= true*/ )
+ScrollToLine (int nNewTopLine, bool bNoSmoothScroll /*= false*/, bool bTrackScrollBar /*= true*/ )
{
if( m_nTopLine != nNewTopLine )
ScrollToSubLine( GetSubLineIndex( nNewTopLine ), bNoSmoothScroll, bTrackScrollBar );
}
/** Append szadd to string str, and advance position curpos */
-static void AppendStringAdv(CString & str, int & curpos, LPCTSTR szadd)
+static void AppendStringAdv(CString & str, int & curpos, const tchar_t* szadd)
{
str += szadd;
- curpos += (int) _tcslen(szadd);
+ curpos += (int) tc::tcslen(szadd);
}
/** Append escaped control char to string str, and advance position curpos */
-static void AppendEscapeAdv(CString & str, int & curpos, TCHAR c)
+static void AppendEscapeAdv(CString & str, int & curpos, tchar_t c)
{
int curlen = str.GetLength();
- LPTSTR szadd = str.GetBufferSetLength(curlen + 3) + curlen;
+ tchar_t* szadd = str.GetBufferSetLength(curlen + 3) + curlen;
curpos += wsprintf(szadd, _T("\t%02X"), static_cast<int>(c));
}
int CCrystalTextView::
-ExpandChars (LPCTSTR pszChars, int nOffset, int nCount, CString & line, int nActualOffset)
+ExpandChars (int nLineIndex, int nOffset, int nCount, CString & line, int nActualOffset)
{
line.Empty();
// Request whitespace characters for codepage ACP
// because that is the codepage used by ExtTextOut
- const ViewableWhitespaceChars * lpspc = GetViewableWhitespaceChars(GetACP(), m_nRenderingMode != RENDERING_MODE_GDI);
+ const ViewableWhitespaceChars * lpspc = GetViewableWhitespaceChars(GetACP(), m_nRenderingMode != RENDERING_MODE::GDI);
if (nCount <= 0)
{
const int nTabSize = GetTabSize ();
+ const tchar_t* pszChars = GetLineChars(nLineIndex);
pszChars += nOffset;
int nLength = nCount;
for (int i = 0; i < nLength; i++)
{
- TCHAR c = pszChars[i];
+ tchar_t c = pszChars[i];
if (c == _T('\t'))
nCount += nTabSize - 1;
else if (c >= _T('\x00') && c <= _T('\x1F') && c != _T('\r') && c != _T('\n'))
line.GetBuffer(nCount + 1); // at least this many characters
line.ReleaseBuffer(0);
int nCurPos = 0;
+ const bool bTableEditing = m_pTextBuffer->GetTableEditing ();
if (nCount > nLength || m_bViewTabs || m_bViewEols)
{
next = pIterChar->next();
if (pszChars[i] == _T('\t'))
{
- int nSpaces = nTabSize - (nActualOffset + nCurPos) % nTabSize;
+ int nSpaces = bTableEditing ? 1 : (nTabSize - (nActualOffset + nCurPos) % nTabSize);
if (m_bViewTabs)
{
AppendStringAdv(line, nCurPos, lpspc->c_tab);
}
else
{
- if (pszChars[i] == '\r' && i < nLength - 1 && pszChars[i+1] == '\n' && m_bDistinguishEols)
+ if (i < nLength - 1 && pszChars[i] == '\r' && pszChars[i+1] == '\n' && m_bDistinguishEols)
{
AppendStringAdv(line, nCurPos, lpspc->c_eol);
i++;
AppendStringAdv(line, nCurPos, lpspc->c_eol);
}
}
- }
+ }
}
else if (pszChars[i] >= _T('\x00') && pszChars[i] <= _T('\x1F'))
{
{
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszChars, nLength);
for (int i1=0, next=0; i1<nLength; i1 = next)
- {
- next = pIterChar->next();
- nCurPos += GetCharCellCountFromChar(pszChars + i1);
- for (; i1 < next; ++i1)
- line += pszChars[i1];
- }
+ {
+ next = pIterChar->next();
+ nCurPos += GetCharCellCountFromChar(pszChars + i1);
+ for (; i1 < next; ++i1)
+ line += pszChars[i1];
+ }
}
return nCurPos;
}
+int CCrystalTextView::
+ExpandCharsTableEditingNoWrap(int nLineIndex, int nOffset, int nCount, CString& line, int nActualOffset)
+{
+ if (m_pTextBuffer == nullptr || nCount <= 0)
+ return 0;
+
+ const tchar_t* pszChars = GetLineChars(nLineIndex);
+ line.Empty();
+ // Request whitespace characters for codepage ACP
+ // because that is the codepage used by ExtTextOut
+ const ViewableWhitespaceChars * lpspc = GetViewableWhitespaceChars(GetACP(), m_nRenderingMode != RENDERING_MODE::GDI);
+
+ int nLength = nCount;
+ int nColumn = 0;
+ int nColumnCount = 0;
+ int nCurColumn = -1;
+ int nColumnTotalWidth = 0;
+ int nColumnBegin = 0;
+ int nColumnTotalWidthBegin = 0;
+ const int nLineLength = GetFullLineLength (nLineIndex);
+ const int nTabSize = GetTabSize ();
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ const int eollen = nLineLength - GetLineLength (nLineIndex);
+ bool bInQuote = false;
+ bool bInQuoteBegin = false;
+
+ for (int i = 0; i < nLineLength; i++)
+ {
+ tchar_t c = pszChars[i];
+ if (i == nOffset)
+ {
+ nColumnBegin = nColumn;
+ nColumnTotalWidthBegin = nColumnTotalWidth;
+ bInQuoteBegin = bInQuote;
+ }
+ if (nLineIndex == m_ptCursorPos.y && i == m_ptCursorPos.x)
+ nCurColumn = nColumn;
+ if (!bInQuote && c == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nCount = nColumnTotalWidth;
+ }
+ else if (c == '\t')
+ nCount += 1 - 1;
+ else if (c == quote)
+ {
+ bInQuote = !bInQuote;
+ }
+ else if (c >= '\x00' && c <= '\x1F' && c != '\r' && c != '\n')
+ nCount += 3 - 1;
+ }
+ nColumnCount = nColumn + 1;
+
+ // Preallocate line buffer, to avoid reallocations as we add characters
+ line.GetBuffer (nCount + 1); // at least this many characters
+ line.ReleaseBuffer (0);
+ int nCurPos = nActualOffset;
+
+ pszChars += nOffset;
+
+ int curColumnTextCellWidth = 0;
+ bool beforeCursorPos = (nLineIndex == m_ptCursorPos.y && nOffset < m_ptCursorPos.x);
+ CString curColumnText;
+ std::vector<std::pair<int, int>> curColumnByteLenCellWidth;
+ nColumn = nColumnBegin;
+ nColumnTotalWidth = nColumnTotalWidthBegin;
+ bInQuote = bInQuoteBegin;
+ auto pIterChar = ICUBreakIterator::getCharacterBreakIterator (pszChars, nLineLength - nOffset);
+ auto nextColumnDistance = [&](int nCurPos)
+ {
+ return (nColumn == nColumnCount - 1) ? INT_MAX : nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn) - nCurPos;
+ };
+ auto appendChars = [&](int i, int next, int pos, CString& text, int& textwidth)
+ {
+ tchar_t c = pszChars[i];
+ if ((c == '\r' || c == '\n') && i >= nLineLength - nOffset - eollen)
+ {
+ if (m_bViewEols)
+ {
+ if (c == '\n' && !m_bDistinguishEols && i+nOffset>0 && pszChars[i-1] == '\r')
+ {
+ // Ignore \n after \r
+ }
+ else
+ {
+ int prevtextwidth = textwidth;
+ if (c == '\r' && i < nLength - 1 && pszChars[i+1] == '\n' && m_bDistinguishEols)
+ AppendStringAdv (text, textwidth, lpspc->c_eol);
+ else if (c == '\r' && m_bDistinguishEols)
+ AppendStringAdv (text, textwidth, lpspc->c_cr);
+ else if (c == '\n' && m_bDistinguishEols)
+ {
+ if (i == 0 || pszChars[i - 1] != '\r')
+ AppendStringAdv (text, textwidth, lpspc->c_lf);
+ }
+ else
+ AppendStringAdv (text, textwidth, lpspc->c_eol);
+ if (textwidth - prevtextwidth > 0)
+ curColumnByteLenCellWidth.push_back ({ textwidth - prevtextwidth, textwidth - prevtextwidth});
+ }
+ }
+ }
+ else if (c == '\t')
+ {
+ int nSpaces = 1;
+ if (sep != '\t' || bInQuote)
+ {
+ nSpaces = 1;
+ if (nSpaces > nextColumnDistance (pos))
+ nSpaces = nextColumnDistance (pos);
+ }
+ if (nSpaces >= 1 && m_bViewTabs)
+ {
+ curColumnByteLenCellWidth.push_back ({ 1, 1 });
+ AppendStringAdv (text, textwidth, lpspc->c_tab);
+ nSpaces--;
+ }
+ while (nSpaces > 0)
+ {
+ curColumnByteLenCellWidth.push_back ({ 1, 1 });
+ textwidth++;
+ text += ' ';
+ nSpaces--;
+ }
+ }
+ else if (c == ' ' && m_bViewTabs)
+ {
+ curColumnByteLenCellWidth.push_back ({ 1, 1 });
+ AppendStringAdv (text, textwidth, lpspc->c_space);
+ }
+ else if (c >= '\x00' && c <= '\x1F')
+ {
+ curColumnByteLenCellWidth.push_back ({ 3, 3 });
+ AppendEscapeAdv (text, textwidth, c);
+ if (c == '\r' && pszChars[i + 1] == '\n')
+ AppendEscapeAdv (text, textwidth, pszChars[i + 1]);
+ }
+ else
+ {
+ int nLen = GetCharCellCountFromChar (pszChars + i);
+ curColumnByteLenCellWidth.push_back ({ nLen, next - i });
+ textwidth += nLen;
+ for (; i < next; ++i)
+ text += pszChars[i];
+ }
+ if (!bInQuote && c == sep)
+ {
+ int nSpaces = nextColumnDistance (pos + 1);
+ while (nSpaces > 0)
+ {
+ text += ' ';
+ ++textwidth;
+ --nSpaces;
+ }
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn);
+ ++nColumn;
+ }
+ };
+ int i, next;
+ for (i = 0, next = 0; i < nLength; i = next)
+ {
+ next = pIterChar->next ();
+ tchar_t c = pszChars[i];
+ if (c == quote)
+ bInQuote = !bInQuote;
+ int nLen = GetCharCellCountFromChar (pszChars + i);
+ if (nColumn == nCurColumn && beforeCursorPos)
+ {
+ appendChars (i, next, nCurPos + curColumnTextCellWidth, curColumnText, curColumnTextCellWidth);
+ if (next + nOffset == m_ptCursorPos.x || next >= nLength)
+ {
+ int curColumnTextLenAppended = 0;
+ int curColumnTextCellWidthAppended = 0;
+ if (next + nOffset == m_ptCursorPos.x)
+ beforeCursorPos = false;
+ else
+ {
+ int curColumnTextLenSaved = curColumnText.GetLength();
+ int curColumnTextCellWidthSaved = curColumnTextCellWidth;
+ i = next;
+ for (; i < nLineLength - nOffset && nColumn == nCurColumn && next + nOffset < m_ptCursorPos.x; i = next)
+ {
+ next = pIterChar->next ();
+ c = pszChars[i];
+ if (c == quote)
+ bInQuote = !bInQuote;
+ nLen = GetCharCellCountFromChar (pszChars + i);
+ appendChars (i, next, nCurPos + curColumnTextCellWidth, curColumnText, curColumnTextCellWidth);
+ }
+ curColumnTextLenAppended = curColumnText.GetLength() - curColumnTextLenSaved;
+ curColumnTextCellWidthAppended = curColumnTextCellWidth - curColumnTextCellWidthSaved;
+ }
+ if (curColumnTextCellWidth > nextColumnDistance (nCurPos))
+ {
+ for (size_t k = 0; k < curColumnByteLenCellWidth.size () && curColumnTextCellWidth > nextColumnDistance (nCurPos); ++k)
+ {
+ curColumnTextCellWidth -= curColumnByteLenCellWidth[k].first;
+ curColumnText = curColumnText.Mid (curColumnByteLenCellWidth[k].second);
+ }
+ int nSpaces = nextColumnDistance (nCurPos) - curColumnTextCellWidth;
+ if (nSpaces > 0)
+ {
+ CString spaces (' ', nSpaces);
+ curColumnText.Insert (0, spaces);
+ curColumnTextCellWidth = m_pTextBuffer->GetColumnWidth (nColumn);
+ }
+ }
+ if (curColumnTextLenAppended > 0)
+ {
+ if (curColumnTextLenAppended < curColumnText.GetLength())
+ {
+ line += curColumnText.Left(curColumnText.GetLength() - curColumnTextLenAppended);
+ nCurPos += curColumnTextCellWidth - curColumnTextCellWidthAppended;
+ }
+ }
+ else
+ {
+ line += curColumnText;
+ nCurPos += curColumnTextCellWidth;
+ }
+ }
+ }
+ else
+ {
+ if (nLen <= nextColumnDistance (nCurPos))
+ {
+ appendChars (i, next, nCurPos, line, nCurPos);
+ curColumnByteLenCellWidth.clear ();
+ }
+ else
+ {
+ int nSpaces = nextColumnDistance (nCurPos);
+ while (nSpaces > 0)
+ {
+ line += ' ';
+ ++nCurPos;
+ --nSpaces;
+ }
+ if (!bInQuote && c == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn);
+ ++nColumn;
+ }
+ }
+ }
+ }
+ return nCurPos - nActualOffset;
+}
/**
* @note In ANSI build, this routine is buggy for multibytes or double-width characters
*/
void CCrystalTextView::
-DrawLineHelperImpl (CPoint & ptOrigin, const CRect & rcClip,
- int nColorIndex,
- int nBgColorIndex, COLORREF crText, COLORREF crBkgnd, LPCTSTR pszChars, int nOffset, int nCount, int &nActualOffset)
+DrawLineHelperImpl (CPoint & ptOrigin, const CRect & rcClip, int nColorIndex,
+ int nBgColorIndex, CEColor crText, CEColor crBkgnd, int nLineIndex, int nOffset, int nCount, int &nActualOffset)
{
ASSERT (nCount >= 0);
if (nCount > 0)
{
CString line;
- nActualOffset += ExpandChars (pszChars, nOffset, nCount, line, nActualOffset);
+ if (GetTextLayoutMode () == TEXTLAYOUT_TABLE_NOWORDWRAP)
+ nActualOffset += ExpandCharsTableEditingNoWrap (nLineIndex, nOffset, nCount, line, nActualOffset);
+ else
+ nActualOffset += ExpandChars (nLineIndex, nOffset, nCount, line, nActualOffset);
const int lineLen = line.GetLength();
const int nCharWidth = GetCharWidth();
const int nCharWidthNarrowed = nCharWidth / 2;
const int nCharWidthWidened = nCharWidth * 2 - nCharWidthNarrowed;
const int nLineHeight = GetLineHeight();
- auto pIterChar = ICUBreakIterator::getCharacterBreakIterator((LPCTSTR)line, lineLen);
+ auto pIterChar = ICUBreakIterator::getCharacterBreakIterator((const tchar_t*)line, lineLen);
// i the character index, from 0 to lineLen-1
int i = 0;
// Pass if the text begins after the right end of the clipping region
- if (ptOrigin.x < rcClip.right)
+ if (ptOrigin.x < rcClip.right && ptOrigin.y < rcClip.bottom)
{
// Because ExtTextOut is buggy when ptOrigin.x < - 4095 * charWidth
// or when nCount >= 4095
// stop for i = first visible character, at least partly
const int clipLeft = rcClip.left - nCharWidth * 2;
for ( ; i < lineLen; i = pIterChar->next())
- {
- int pnWidthsCurrent = GetCharCellCountFromChar(static_cast<const TCHAR *>(line) + i) * nCharWidth;
- ptOrigin.x += pnWidthsCurrent;
- if (ptOrigin.x >= clipLeft)
{
- ptOrigin.x -= pnWidthsCurrent;
- break;
+ int pnWidthsCurrent = GetCharCellCountFromChar(static_cast<const tchar_t *>(line) + i) * nCharWidth;
+ ptOrigin.x += pnWidthsCurrent;
+ if (ptOrigin.x >= clipLeft)
+ {
+ ptOrigin.x -= pnWidthsCurrent;
+ break;
+ }
}
- }
-
- //
+
+ //
#ifdef _DEBUG
//CSize sz = pdc->GetTextExtent(line, nCount);
//ASSERT(sz.cx == m_nCharWidth * nCount);
for (int next = i; i < lineLen && nSumWidth < nWidth ; i = next)
{
if (line[i] == '\t') // Escape sequence leadin?
- {
- bdisphex = true;
- // Substitute a space narrowed to half the width of a character cell.
- line.SetAt(i, ' ');
- size_t idx = i - ibegin;
- if (idx >= nWidths.size())
+ {
+ bdisphex = true;
+ // Substitute a space narrowed to half the width of a character cell.
+ line.SetAt(i, ' ');
+ size_t idx = i - ibegin;
+ if (idx >= nWidths.size())
nWidths.resize(nWidths.size() * 2);
- nSumWidth += nWidths[idx] = nCharWidthNarrowed;
- // 1st hex digit has normal width.
- idx = pIterChar->next() - ibegin;
- if (idx >= nWidths.size())
+ nSumWidth += nWidths[idx] = nCharWidthNarrowed;
+ // 1st hex digit has normal width.
+ idx = pIterChar->next() - ibegin;
+ if (idx >= nWidths.size())
nWidths.resize(nWidths.size() * 2);
- nSumWidth += nWidths[idx] = nCharWidth;
- // 2nd hex digit is padded by half the width of a character cell.
- idx = pIterChar->next() - ibegin;
- if (idx >= nWidths.size())
+ nSumWidth += nWidths[idx] = nCharWidth;
+ // 2nd hex digit is padded by half the width of a character cell.
+ idx = pIterChar->next() - ibegin;
+ if (idx >= nWidths.size())
nWidths.resize(nWidths.size() * 2);
- nSumWidth += nWidths[idx] = nCharWidthWidened;
- }
+ nSumWidth += nWidths[idx] = nCharWidthWidened;
+ }
else
- {
- size_t idx = i - ibegin;
- if (idx >= nWidths.size())
+ {
+ size_t idx = i - ibegin;
+ if (idx >= nWidths.size())
nWidths.resize(nWidths.size() * 2);
- nSumWidth += nWidths[idx] = GetCharCellCountFromChar(static_cast<const TCHAR *>(line) + i) * nCharWidth;
- }
- next = pIterChar->next();
+ nSumWidth += nWidths[idx] = GetCharCellCountFromChar(static_cast<const tchar_t *>(line) + i) * nCharWidth;
+ }
+ next = pIterChar->next();
}
int nCount1 = i - ibegin;
if (ptOrigin.x + nSumWidth > rcClip.left)
{
+ CEColor crText2 = crText;
+ CEColor crBkgnd2 = crBkgnd;
if (crText == CLR_NONE || nColorIndex & COLORINDEX_APPLYFORCE)
- m_pCrystalRenderer->SetTextColor(GetColor(nColorIndex));
- else
- m_pCrystalRenderer->SetTextColor(crText);
+ crText2 = GetColor(nColorIndex);
if (crBkgnd == CLR_NONE || nBgColorIndex & COLORINDEX_APPLYFORCE)
- m_pCrystalRenderer->SetBkColor(GetColor(nBgColorIndex));
- else
- m_pCrystalRenderer->SetBkColor(crBkgnd);
+ crBkgnd2 = GetColor(nBgColorIndex);
+ if (nColorIndex & COLORINDEX_INTERMEDIATECOLOR)
+ crText2 = CEColor::GetIntermediateColor(crText2, crBkgnd2, 0.333f);
+ m_pCrystalRenderer->SetTextColor(crText2);
+ m_pCrystalRenderer->SetBkColor(crBkgnd2);
m_pCrystalRenderer->SwitchFont(GetItalic(nColorIndex), GetBold(nColorIndex));
// we are sure to have less than 4095 characters because all the chars are visible
RECT rcIntersect;
RECT rcTextBlock = {ptOrigin.x, ptOrigin.y, ptOrigin.x + nSumWidth + 2, ptOrigin.y + nLineHeight};
IntersectRect(&rcIntersect, &rcClip, &rcTextBlock);
- m_pCrystalRenderer->DrawText(ptOrigin.x, ptOrigin.y, rcIntersect, LPCTSTR(line) + ibegin, nCount1, &nWidths[0]);
+ m_pCrystalRenderer->DrawText(ptOrigin.x, ptOrigin.y, rcIntersect, (const tchar_t*)(line) + ibegin, nCount1, &nWidths[0]);
if (bdisphex)
{
- // Draw rounded rectangles around control characters
- m_pCrystalRenderer->PushAxisAlignedClip(rcClip);
- int x = ptOrigin.x;
- for (int j = 0 ; j < nCount1 ; ++j)
- {
- // Assume narrowed space is converted escape sequence leadin.
- if (line[ibegin + j] == ' ' && nWidths[j] < nCharWidth)
- {
- m_pCrystalRenderer->DrawRoundRectangle(x + 2, ptOrigin.y + 1,
- x + 3 * nCharWidth - 2, ptOrigin.y + nLineHeight - 1,
- nCharWidth / 2, nLineHeight / 2);
- }
- x += nWidths[j];
- }
- m_pCrystalRenderer->PopAxisAlignedClip();
- }
+ // Draw rounded rectangles around control characters
+ m_pCrystalRenderer->PushAxisAlignedClip(rcClip);
+ int x = ptOrigin.x;
+ for (int j = 0 ; j < nCount1 ; ++j)
+ {
+ // Assume narrowed space is converted escape sequence leadin.
+ if (line[ibegin + j] == ' ' && nWidths[j] < nCharWidth)
+ {
+ m_pCrystalRenderer->DrawRoundRectangle(x + 2, ptOrigin.y + 1,
+ x + 3 * nCharWidth - 2, ptOrigin.y + nLineHeight - 1,
+ nCharWidth / 2, nLineHeight / 2);
+ }
+ x += nWidths[j];
+ }
+ m_pCrystalRenderer->PopAxisAlignedClip();
+ }
}
// Update the final position after the visible characters
// Update the final position after the right clipped characters
for ( ; i < lineLen; i = pIterChar->next())
{
- ptOrigin.x += GetCharCellCountFromChar(static_cast<const TCHAR *>(line) + i) * nCharWidth;
+ ptOrigin.x += GetCharCellCountFromChar(static_cast<const tchar_t *>(line) + i) * nCharWidth;
}
}
}
+bool CCrystalTextView::
+GetSelectionLeftRight(int nLineIndex, int& nSelLeft, int& nSelRight)
+{
+ int nLineLength = GetViewableLineLength (nLineIndex);
+ nSelLeft = 0;
+ nSelRight = 0;
+ if ( !m_bRectangularSelection )
+ {
+ if (m_ptDrawSelStart.y > nLineIndex)
+ nSelLeft = nLineLength;
+ else if (m_ptDrawSelStart.y == nLineIndex)
+ nSelLeft = m_ptDrawSelStart.x;
+ if (m_ptDrawSelEnd.y > nLineIndex)
+ nSelRight = nLineLength;
+ else if (m_ptDrawSelEnd.y == nLineIndex)
+ nSelRight = m_ptDrawSelEnd.x;
+ return (m_ptDrawSelStart.y <= nLineIndex && nLineIndex <= m_ptDrawSelEnd.y);
+ }
+ else
+ return GetColumnSelection (nLineIndex, nSelLeft, nSelRight);
+}
+
void CCrystalTextView::
DrawLineHelper (CPoint & ptOrigin, const CRect & rcClip, int nColorIndex, int nBgColorIndex,
- COLORREF crText, COLORREF crBkgnd, LPCTSTR pszChars, int nOffset, int nCount, int &nActualOffset, CPoint ptTextPos)
+ CEColor crText, CEColor crBkgnd,
+ int nLineIndex, int nOffset, int nCount, int &nActualOffset, CEPoint ptTextPos,
+ int nSelLeft, int nSelRight)
{
if (nCount > 0)
{
if (m_bFocused || m_bShowInactiveSelection)
{
- int nSelBegin = 0, nSelEnd = 0;
- if ( !m_bColumnSelection )
- {
- if (m_ptDrawSelStart.y > ptTextPos.y)
- {
- nSelBegin = nCount;
- }
- else if (m_ptDrawSelStart.y == ptTextPos.y)
- {
- nSelBegin = m_ptDrawSelStart.x - ptTextPos.x;
- if (nSelBegin < 0)
- nSelBegin = 0;
- if (nSelBegin > nCount)
- nSelBegin = nCount;
- }
- if (m_ptDrawSelEnd.y > ptTextPos.y)
- {
- nSelEnd = nCount;
- }
- else if (m_ptDrawSelEnd.y == ptTextPos.y)
- {
- nSelEnd = m_ptDrawSelEnd.x - ptTextPos.x;
- if (nSelEnd < 0)
- nSelEnd = 0;
- if (nSelEnd > nCount)
- nSelEnd = nCount;
- }
- }
- else
- {
- int nSelLeft, nSelRight;
- GetColumnSelection (ptTextPos.y, nSelLeft, nSelRight);
- nSelBegin = nSelLeft - ptTextPos.x;
- nSelEnd = nSelRight - ptTextPos.x;
- if (nSelBegin < 0) nSelBegin = 0;
- if (nSelBegin > nCount) nSelBegin = nCount;
- if (nSelEnd < 0) nSelEnd = 0;
- if (nSelEnd > nCount) nSelEnd = nCount;
- }
+ int nSelBegin = std::clamp<int>(nSelLeft - ptTextPos.x, 0, nCount);
+ int nSelEnd = std::clamp<int>(nSelRight - ptTextPos.x, 0, nCount);
ASSERT (nSelBegin >= 0 && nSelBegin <= nCount);
ASSERT (nSelEnd >= 0 && nSelEnd <= nCount);
// Draw part of the text before selection
if (nSelBegin > 0)
{
- DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, pszChars, nOffset, nSelBegin, nActualOffset);
+ DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, nLineIndex, nOffset, nSelBegin, nActualOffset);
}
if (nSelBegin < nSelEnd)
{
DrawLineHelperImpl (ptOrigin, rcClip,
- nColorIndex & ~COLORINDEX_APPLYFORCE,
- nBgColorIndex & ~COLORINDEX_APPLYFORCE,
- GetColor (COLORINDEX_SELTEXT),
-
- GetColor (COLORINDEX_SELBKGND),
-
- pszChars,
- nOffset + nSelBegin, nSelEnd - nSelBegin, nActualOffset);
+ nColorIndex & ~COLORINDEX_MASK,
+ nBgColorIndex & ~COLORINDEX_MASK,
+ GetColor (COLORINDEX_SELTEXT),
+ GetColor (COLORINDEX_SELBKGND),
+ nLineIndex,
+ nOffset + nSelBegin, nSelEnd - nSelBegin, nActualOffset);
}
if (nSelEnd < nCount)
{
- DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, pszChars, nOffset + nSelEnd, nCount - nSelEnd, nActualOffset);
+ DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, nLineIndex, nOffset + nSelEnd, nCount - nSelEnd, nActualOffset);
}
}
else
{
- DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, pszChars, nOffset, nCount, nActualOffset);
+ DrawLineHelperImpl (ptOrigin, rcClip, nColorIndex, nBgColorIndex, crText, crBkgnd, nLineIndex, nOffset, nCount, nActualOffset);
}
}
}
void CCrystalTextView::
-GetLineColors (int nLineIndex, COLORREF & crBkgnd,
- COLORREF & crText, bool & bDrawWhitespace)
+GetLineColors (int nLineIndex, CEColor & crBkgnd,
+ CEColor & crText, bool & bDrawWhitespace)
{
- DWORD dwLineFlags = GetLineFlags (nLineIndex);
+ lineflags_t dwLineFlags = GetLineFlags (nLineIndex);
bDrawWhitespace = true;
- crText = RGB (255, 255, 255);
+ crText = { 255, 255, 255 };
if (dwLineFlags & LF_EXECUTION)
{
- crBkgnd = RGB (0, 128, 0);
+ crBkgnd = { 0, 128, 0 };
return;
}
if (dwLineFlags & LF_BREAKPOINT)
{
- crBkgnd = RGB (255, 0, 0);
+ crBkgnd = { 255, 0, 0 };
return;
}
if (dwLineFlags & LF_INVALID_BREAKPOINT)
{
- crBkgnd = RGB (128, 128, 0);
+ crBkgnd = { 128, 128, 0 };
return;
}
crBkgnd = CLR_NONE;
if (m_ParseCookies->size() == 0)
{
// must be initialized to invalid value (DWORD) -1
- m_ParseCookies->assign(nLineCount, static_cast<DWORD>(-1));
+ m_ParseCookies->assign(nLineCount, static_cast<uint32_t>(-1));
}
if (nLineIndex < 0)
L--;
L++;
- int nBlocks;
+ int nBlocks = 0;
while (L <= nLineIndex)
{
- DWORD dwCookie = 0;
+ unsigned dwCookie = 0;
if (L > 0)
dwCookie = (*m_ParseCookies)[L - 1];
ASSERT (dwCookie != - 1);
}
//BEGIN SW
-void CCrystalTextView::WrapLine( int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks )
+void CCrystalTextView::WrapLine( int nLineIndex, int nMaxLineWidth, std::vector<int> *anBreaks, int &nBreaks )
{
// There must be a parser attached to this view
if( m_pParser == nullptr )
void CCrystalTextView::WrapLineCached(
- int nLineIndex, int nMaxLineWidth, int *anBreaks, int &nBreaks )
+ int nLineIndex, int nMaxLineWidth, std::vector<int> *anBreaks, int &nBreaks )
{
if( !GetLineVisible (nLineIndex) )
- {
- nBreaks = -1;
- return;
- }
+ {
+ nBreaks = -1;
+ return;
+ }
// If the word wrap is not active, there is no breaks in the line
if( !m_bWordWrap )
- {
- nBreaks = 0;
- return;
- }
+ {
+ nBreaks = 0;
+ return;
+ }
// word wrap is active
- if( nLineIndex < m_panSubLines->GetSize() && !anBreaks && (*m_panSubLines)[nLineIndex] > -1 )
+ if( nLineIndex < m_panSubLines->size () && !anBreaks && (*m_panSubLines)[nLineIndex] > -1 )
// return cached data
nBreaks = (*m_panSubLines)[nLineIndex] - 1;
else
- {
- // recompute line wrap
- nBreaks = 0;
- WrapLine( nLineIndex, nMaxLineWidth, anBreaks, nBreaks );
+ {
+ // recompute line wrap
+ nBreaks = 0;
+ WrapLine( nLineIndex, nMaxLineWidth, anBreaks, nBreaks );
- // cache data
- ASSERT( nBreaks > -1 );
- m_panSubLines->SetAtGrow( nLineIndex, nBreaks + 1 );
+ // cache data
+ ASSERT( nBreaks > -1 );
+ if (nLineIndex >= m_panSubLines->size())
+ m_panSubLines->resize(nLineIndex + 1);
+ (*m_panSubLines)[nLineIndex] = nBreaks + 1;
- // RecalcVertScrollBar();
- }
+ // RecalcVertScrollBar();
+ }
}
// invalidate cached sub line count
- if( nLineIndex2 == -1 && nLineIndex1 < m_panSubLines->GetSize() )
- for( int i = nLineIndex1; i < m_panSubLines->GetSize(); i++ )
+ if( nLineIndex2 == -1 && nLineIndex1 < m_panSubLines->size () )
+ for( int i = nLineIndex1; i < m_panSubLines->size (); i++ )
(*m_panSubLines)[i] = -1;
else
{
nLineIndex2 = nStorage;
}
- if( nLineIndex1 >= m_panSubLines->GetSize() )
- return;
+ if( nLineIndex1 >= m_panSubLines->size () )
+ return;
- if( nLineIndex2 >= m_panSubLines->GetSize() )
- nLineIndex2 = (int) m_panSubLines->GetUpperBound();
+ if( nLineIndex2 >= m_panSubLines->size () )
+ nLineIndex2 = (int) m_panSubLines->size () - 1;
- for( int i = nLineIndex1; i <= nLineIndex2; i++ )
- if( i >= 0 && i < m_panSubLines->GetSize() )
- (*m_panSubLines)[i] = -1;
- }
+ for( int i = nLineIndex1; i <= nLineIndex2; i++ )
+ if( i >= 0 && i < m_panSubLines->size () )
+ (*m_panSubLines)[i] = -1;
+ }
}
/**
{
Invalidate();
m_nTopSubLine = GetSubLineIndex(m_nTopLine);
- RecalcVertScrollBar ();
- RecalcHorzScrollBar ();
+ InvalidateVertScrollBar ();
+ InvalidateHorzScrollBar ();
UpdateCaret ();
}
}
void CCrystalTextView::DrawScreenLine( CPoint &ptOrigin, const CRect &rcClip,
const std::vector<TEXTBLOCK>& blocks, int &nActualItem,
- COLORREF crText, COLORREF crBkgnd, bool bDrawWhitespace,
- LPCTSTR pszChars, int nOffset, int nCount, int &nActualOffset, CPoint ptTextPos )
+ CEColor crText, CEColor crBkgnd, bool bDrawWhitespace,
+ int nLineIndex, int nOffset, int nCount, int &nActualOffset, CEPoint ptTextPos )
{
CPoint originalOrigin = ptOrigin;
CPoint ptOriginZeroWidthBlock;
int nBlockSize = static_cast<int>(blocks.size());
ASSERT( nActualItem < nBlockSize );
+ int nSelLeft = 0, nSelRight = 0;
+ GetSelectionLeftRight(ptTextPos.y, nSelLeft, nSelRight);
+
if( nBlockSize > 0 && nActualItem < nBlockSize - 1 &&
blocks[nActualItem + 1].m_nCharPos >= nOffset &&
blocks[nActualItem + 1].m_nCharPos <= nOffset + nCount )
if (blocks[I + 1].m_nCharPos - nOffsetToUse > 0)
{
int nOldActualOffset = nActualOffset;
- DrawLineHelper(ptOrigin, rcClip, blk.m_nColorIndex, blk.m_nBgColorIndex, crText, crBkgnd, pszChars,
+ DrawLineHelper(ptOrigin, rcClip, blk.m_nColorIndex, blk.m_nBgColorIndex, crText, crBkgnd, nLineIndex,
(nOffset > blk.m_nCharPos)? nOffset : blk.m_nCharPos,
blocks[I + 1].m_nCharPos - nOffsetToUse,
- nActualOffset, CPoint( nOffsetToUse, ptTextPos.y ));
+ nActualOffset, CEPoint( nOffsetToUse, ptTextPos.y ), nSelLeft, nSelRight);
if (bPrevZeroWidthBlock)
{
CRect rcClipZeroWidthBlock(ptOriginZeroWidthBlock.x, rcClip.top, ptOriginZeroWidthBlock.x + ZEROWIDTHBLOCK_WIDTH, rcClip.bottom);
- DrawLineHelper(ptOriginZeroWidthBlock, rcClipZeroWidthBlock, blk.m_nColorIndex, nBgColorIndexZeorWidthBlock, crText, crBkgnd, pszChars,
+ DrawLineHelper(ptOriginZeroWidthBlock, rcClipZeroWidthBlock, blk.m_nColorIndex, nBgColorIndexZeorWidthBlock, crText, crBkgnd, nLineIndex,
(nOffset > blk.m_nCharPos)? nOffset : blk.m_nCharPos,
blocks[I + 1].m_nCharPos - nOffsetToUse,
- nOldActualOffset, CPoint( nOffsetToUse, ptTextPos.y ));
+ nOldActualOffset, CEPoint( nOffsetToUse, ptTextPos.y ), nSelLeft, nSelRight);
bPrevZeroWidthBlock = false;
}
}
else
{
- if (!bPrevZeroWidthBlock)
+ if (!bPrevZeroWidthBlock && (blk.m_nCharPos < nOffset + nCount || nOffset + nCount == nLineLength))
{
int nBgColorIndex = blk.m_nBgColorIndex;
- COLORREF clrBkColor;
- if (crBkgnd == CLR_NONE || nBgColorIndex & COLORINDEX_APPLYFORCE)
+ CEColor clrBkColor;
+ if (IsInsideSelBlock (CEPoint{nOffsetToUse, ptTextPos.y}))
+ clrBkColor = GetColor(COLORINDEX_SELBKGND);
+ else if (crBkgnd == CLR_NONE || nBgColorIndex & COLORINDEX_APPLYFORCE)
clrBkColor = GetColor(nBgColorIndex);
else
clrBkColor = crBkgnd;
}
}
if (ptOrigin.x > rcClip.right)
- break;
+ {
+ if (GetTextLayoutMode () == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ while (I < blocks.size () - 1 && blocks[I + 1].m_nCharPos <= nOffset + nCount)
+ I++;
+ }
+ break;
+ }
}
nActualItem = static_cast<int>(I);
- ASSERT(blocks[nActualItem].m_nCharPos >= 0 &&
- blocks[nActualItem].m_nCharPos <= nLineLength);
+ const TEXTBLOCK& blk = blocks[nActualItem];
+ ASSERT(blk.m_nCharPos >= 0 &&
+ blk.m_nCharPos <= nLineLength);
- if (nOffset + nCount - blocks[nActualItem].m_nCharPos > 0)
+ if (nOffset + nCount - blk.m_nCharPos > 0)
{
int nOldActualOffset = nActualOffset;
- DrawLineHelper(ptOrigin, rcClip, blocks[nActualItem].m_nColorIndex, blocks[nActualItem].m_nBgColorIndex,
- crText, crBkgnd, pszChars, blocks[nActualItem].m_nCharPos,
- nOffset + nCount - blocks[nActualItem].m_nCharPos,
- nActualOffset, CPoint(blocks[nActualItem].m_nCharPos, ptTextPos.y));
+ DrawLineHelper(ptOrigin, rcClip, blk.m_nColorIndex, blk.m_nBgColorIndex,
+ crText, crBkgnd, nLineIndex, blk.m_nCharPos,
+ nOffset + nCount - blk.m_nCharPos,
+ nActualOffset, CEPoint(blk.m_nCharPos, ptTextPos.y), nSelLeft, nSelRight);
if (bPrevZeroWidthBlock)
{
CRect rcClipZeroWidthBlock(ptOriginZeroWidthBlock.x, rcClip.top, ptOriginZeroWidthBlock.x + ZEROWIDTHBLOCK_WIDTH, rcClip.bottom);
- DrawLineHelper(ptOriginZeroWidthBlock, rcClipZeroWidthBlock, blocks[nActualItem].m_nColorIndex, nBgColorIndexZeorWidthBlock,
- crText, crBkgnd, pszChars, blocks[nActualItem].m_nCharPos,
- nOffset + nCount - blocks[nActualItem].m_nCharPos,
- nOldActualOffset, CPoint(blocks[nActualItem].m_nCharPos, ptTextPos.y));
+ DrawLineHelper(ptOriginZeroWidthBlock, rcClipZeroWidthBlock, blk.m_nColorIndex, nBgColorIndexZeorWidthBlock,
+ crText, crBkgnd, nLineIndex, blk.m_nCharPos,
+ nOffset + nCount - blk.m_nCharPos,
+ nOldActualOffset, CEPoint(blk.m_nCharPos, ptTextPos.y), nSelLeft, nSelRight);
bPrevZeroWidthBlock = false;
}
}
else
{
- if (!bPrevZeroWidthBlock)
+ if (!bPrevZeroWidthBlock && (blk.m_nCharPos < nOffset + nCount || nOffset + nCount == nLineLength))
{
- int nBgColorIndex = blocks[nActualItem].m_nBgColorIndex;
- COLORREF clrBkColor;
- if (crBkgnd == CLR_NONE || nBgColorIndex & COLORINDEX_APPLYFORCE)
+ int nBgColorIndex = blk.m_nBgColorIndex;
+ CEColor clrBkColor;
+ if (IsInsideSelBlock (CEPoint{blk.m_nCharPos, ptTextPos.y}))
+ clrBkColor = GetColor(COLORINDEX_SELBKGND);
+ else if (crBkgnd == CLR_NONE || nBgColorIndex & COLORINDEX_APPLYFORCE)
clrBkColor = GetColor(nBgColorIndex);
else
clrBkColor = crBkgnd;
{
DrawLineHelper(
ptOrigin, rcClip, blocks[nActualItem].m_nColorIndex, blocks[nActualItem].m_nBgColorIndex,
- crText, crBkgnd, pszChars, nOffset, nCount, nActualOffset, ptTextPos);
+ crText, crBkgnd, nLineIndex, nOffset, nCount, nActualOffset, ptTextPos, nSelLeft, nSelRight);
}
// Draw space on the right of the text
frect.left = ptOrigin.x + (bPrevZeroWidthBlock ? ZEROWIDTHBLOCK_WIDTH : 0);
if ((m_bFocused || m_bShowInactiveSelection)
- && !m_bColumnSelection
- && IsInsideSelBlock(CPoint(nLineLength, ptTextPos.y))
+ && !m_bRectangularSelection
+ && IsInsideSelBlock(CEPoint(nLineLength, ptTextPos.y))
&& (nOffset + nCount) == nLineLength )
{
if (frect.left >= rcClip.left)
}
//END SW
-class IntArray : public CArray<int, int>
-{
-public:
- explicit IntArray(int len) { SetSize(len); }
-};
-
std::vector<TEXTBLOCK> CCrystalTextView::
MergeTextBlocks (const std::vector<TEXTBLOCK>& blocks1, const std::vector<TEXTBLOCK>& blocks2) const
{
(blocks1[i].m_nCharPos == blocks2[j].m_nCharPos))
{
mergedBlocks[k].m_nCharPos = blocks2[j].m_nCharPos;
- if (blocks2[j].m_nColorIndex == COLORINDEX_NONE)
- mergedBlocks[k].m_nColorIndex = blocks1[i].m_nColorIndex;
+ if ((blocks2[j].m_nColorIndex & ~COLORINDEX_MASK) == COLORINDEX_NONE)
+ mergedBlocks[k].m_nColorIndex = blocks1[i].m_nColorIndex | (blocks2[j].m_nColorIndex & COLORINDEX_MASK);
else
mergedBlocks[k].m_nColorIndex = blocks2[j].m_nColorIndex;
if (blocks2[j].m_nBgColorIndex == COLORINDEX_NONE)
blocks1[i].m_nCharPos < blocks2[j].m_nCharPos))
{
mergedBlocks[k].m_nCharPos = blocks1[i].m_nCharPos;
- if (blocks2.size() == 0 || blocks2[j - 1].m_nColorIndex == COLORINDEX_NONE)
- mergedBlocks[k].m_nColorIndex = blocks1[i].m_nColorIndex;
+ if (blocks2.size() == 0 || (blocks2[j - 1].m_nColorIndex & ~COLORINDEX_MASK) == COLORINDEX_NONE)
+ mergedBlocks[k].m_nColorIndex = blocks1[i].m_nColorIndex |
+ (blocks2.size() == 0 ? 0 : (blocks2[j - 1].m_nColorIndex & COLORINDEX_MASK));
else
mergedBlocks[k].m_nColorIndex = blocks2[j - 1].m_nColorIndex;
if (blocks2.size() == 0 || blocks2[j - 1].m_nBgColorIndex == COLORINDEX_NONE)
else if (i >= blocks1.size() || (j < blocks2.size() && blocks1[i].m_nCharPos > blocks2[j].m_nCharPos))
{
mergedBlocks[k].m_nCharPos = blocks2[j].m_nCharPos;
- if (i > 0 && blocks2[j].m_nColorIndex == COLORINDEX_NONE)
- mergedBlocks[k].m_nColorIndex = blocks1[i - 1].m_nColorIndex;
+ if (i > 0 && (blocks2[j].m_nColorIndex & ~COLORINDEX_MASK) == COLORINDEX_NONE)
+ mergedBlocks[k].m_nColorIndex = blocks1[i - 1].m_nColorIndex | (blocks2[j].m_nColorIndex & COLORINDEX_MASK);
else
mergedBlocks[k].m_nColorIndex = blocks2[j].m_nColorIndex;
if (i > 0 && blocks2[j].m_nBgColorIndex == COLORINDEX_NONE)
}
std::vector<TEXTBLOCK>
+CCrystalTextView::GetWhitespaceTextBlocks(int nLineIndex) const
+{
+ const tchar_t *pszChars = GetLineChars(nLineIndex);
+ int nLineLength = GetLineLength(nLineIndex);
+ std::vector<TEXTBLOCK> blocks((nLineLength + 1) * 3);
+ blocks[0].m_nCharPos = 0;
+ blocks[0].m_nColorIndex = COLORINDEX_NONE;
+ blocks[0].m_nBgColorIndex = COLORINDEX_NONE;
+ int nBlocks = 1;
+ if (pszChars != nullptr)
+ {
+ for (int i = 0; i < nLineLength; ++i)
+ {
+ if (pszChars[i] == ' ' || pszChars[i] == '\t')
+ {
+ blocks[nBlocks].m_nCharPos = i;
+ blocks[nBlocks].m_nColorIndex = COLORINDEX_NONE | COLORINDEX_INTERMEDIATECOLOR;
+ blocks[nBlocks].m_nBgColorIndex = COLORINDEX_NONE;
+ ++nBlocks;
+ while (i < nLineLength && (pszChars[i] == ' ' || pszChars[i] == '\t'))
+ ++i;
+ if (i < nLineLength)
+ {
+ blocks[nBlocks].m_nCharPos = i;
+ blocks[nBlocks].m_nColorIndex = COLORINDEX_NONE;
+ blocks[nBlocks].m_nBgColorIndex = COLORINDEX_NONE;
+ ++nBlocks;
+ }
+ }
+ }
+ }
+ if (nBlocks == 0 || blocks[nBlocks].m_nColorIndex == COLORINDEX_NONE)
+ {
+ blocks[nBlocks].m_nCharPos = nLineLength;
+ blocks[nBlocks].m_nColorIndex = COLORINDEX_NONE | COLORINDEX_INTERMEDIATECOLOR;
+ blocks[nBlocks].m_nBgColorIndex = COLORINDEX_NONE;
+ ++nBlocks;
+ }
+ blocks.resize(nBlocks);
+ return blocks;
+}
+
+std::vector<TEXTBLOCK>
CCrystalTextView::GetMarkerTextBlocks(int nLineIndex) const
{
std::vector<TEXTBLOCK> allblocks;
for (const auto& marker : m_pMarkers->GetMarkers())
{
if (!marker.second.bVisible)
- continue;
+ continue;
int nBlocks = 0;
std::vector<TEXTBLOCK> blocks((nLength + 1) * 3); // be aware of nLength == 0
blocks[0].m_nCharPos = 0;
blocks[0].m_nColorIndex = COLORINDEX_NONE;
blocks[0].m_nBgColorIndex = COLORINDEX_NONE;
++nBlocks;
- const TCHAR *pszChars = GetLineChars(nLineIndex);
+ const tchar_t *pszChars = GetLineChars(nLineIndex);
int nLineLength = GetLineLength(nLineIndex);
if (pszChars != nullptr)
{
RxNode *node = nullptr;
- for (const TCHAR *p = pszChars; p < pszChars + nLineLength; )
+ for (const tchar_t *p = pszChars; p < pszChars + nLineLength; )
{
RxMatchRes matches;
int nMatchLen = 0;
size_t nPos = ::FindStringHelper(pszChars, nLineLength, p, marker.second.sFindWhat, marker.second.dwFlags | FIND_NO_WRAP, nMatchLen, node, &matches);
if (nPos == -1)
- break;
- if (nLineLength < static_cast<int>((p - pszChars) + nPos) + nMatchLen)
- nMatchLen = static_cast<int>(nLineLength - (p - pszChars));
- ASSERT(((p - pszChars) + nPos) < INT_MAX);
- blocks[nBlocks].m_nCharPos = static_cast<int>((p - pszChars) + nPos);
+ break;
+ if (nLineLength < static_cast<int>(nPos) + nMatchLen)
+ nMatchLen = static_cast<int>(nLineLength - nPos);
+ ASSERT(nPos < INT_MAX);
+ blocks[nBlocks].m_nCharPos = static_cast<int>(nPos);
blocks[nBlocks].m_nBgColorIndex = marker.second.nBgColorIndex | COLORINDEX_APPLYFORCE;
blocks[nBlocks].m_nColorIndex = COLORINDEX_NONE;
++nBlocks;
- ASSERT(((p - pszChars) + nPos + nMatchLen) < INT_MAX);
- blocks[nBlocks].m_nCharPos = static_cast<int>((p - pszChars) + nPos + nMatchLen);
+ ASSERT((nPos + nMatchLen) < INT_MAX);
+ blocks[nBlocks].m_nCharPos = static_cast<int>(nPos + nMatchLen);
blocks[nBlocks].m_nBgColorIndex = COLORINDEX_NONE;
blocks[nBlocks].m_nColorIndex = COLORINDEX_NONE;
++nBlocks;
- p += nPos + (nMatchLen == 0 ? 1 : nMatchLen);
+ p = pszChars + nPos + (nMatchLen == 0 ? 1 : nMatchLen);
}
RxFree (node);
blocks.resize(nBlocks);
int nLength = GetViewableLineLength (nLineIndex);
// Parse the line
- DWORD dwCookie = GetParseCookie(nLineIndex - 1);
+ unsigned dwCookie = GetParseCookie(nLineIndex - 1);
std::vector<TEXTBLOCK> blocks((nLength + 1) * 3); // be aware of nLength == 0
int nBlocks = 0;
// insert at least one textblock of normal color at the beginning
(*m_ParseCookies)[nLineIndex] = ParseLine(dwCookie, GetLineChars(nLineIndex), GetLineLength(nLineIndex), blocks.data(), nBlocks);
ASSERT((*m_ParseCookies)[nLineIndex] != -1);
blocks.resize(nBlocks);
-
- return MergeTextBlocks(blocks,
- (m_pMarkers && m_pMarkers->GetEnabled() && m_pMarkers->GetMarkers().size() > 0) ?
- MergeTextBlocks(GetAdditionalTextBlocks(nLineIndex), GetMarkerTextBlocks(nLineIndex)) :
- GetAdditionalTextBlocks(nLineIndex));
+
+ std::vector<TEXTBLOCK> additionalBlocks = GetAdditionalTextBlocks(nLineIndex);
+ std::vector<TEXTBLOCK> mergedBlocks;
+ if (m_pMarkers && m_pMarkers->GetEnabled() && m_pMarkers->GetMarkers().size() > 0)
+ mergedBlocks = MergeTextBlocks(additionalBlocks, GetMarkerTextBlocks(nLineIndex));
+ else
+ mergedBlocks = std::move(additionalBlocks);
+ std::vector<TEXTBLOCK> mergedBlocks2 = MergeTextBlocks(blocks, mergedBlocks);
+ if (m_bViewTabs || m_bViewEols)
+ return MergeTextBlocks(mergedBlocks2, GetWhitespaceTextBlocks(nLineIndex));
+ return mergedBlocks2;
}
void CCrystalTextView::
// Acquire the background color for the current line
bool bDrawWhitespace = false;
- COLORREF crBkgnd, crText;
+ CEColor crBkgnd, crText;
GetLineColors (nLineIndex, crBkgnd, crText, bDrawWhitespace);
int nLength = GetViewableLineLength (nLineIndex);
- LPCTSTR pszChars = GetLineChars (nLineIndex);
std::vector<TEXTBLOCK> blocks = GetTextBlocks(nLineIndex);
int nActualItem = 0;
int nActualOffset = 0;
// Wrap the line
- IntArray anBreaks(nLength);
+ std::vector<int> anBreaks(nLength);
int nBreaks = 0;
- WrapLineCached( nLineIndex, GetScreenChars(), anBreaks.GetData(), nBreaks );
+ WrapLineCached( nLineIndex, GetScreenChars(), &anBreaks, nBreaks );
// Draw the line text
CPoint origin (rc.left - m_nOffsetChar * nCharWidth, rc.top);
if (crText != CLR_NONE)
m_pCrystalRenderer->SetTextColor (crText);
- if( nBreaks > 0 )
+ const TextLayoutMode layoutMode = GetTextLayoutMode ();
+ if (layoutMode == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ anBreaks.push_back (-nLength);
+ CPoint originOrg = origin;
+ DrawScreenLine(
+ origin, rc,
+ blocks, nActualItem,
+ crText, crBkgnd, bDrawWhitespace,
+ nLineIndex, 0, abs(anBreaks[0]),
+ nActualOffset, CEPoint( 0, nLineIndex ) );
+ int nColumn = 0;
+ for( int i = 0, j = 0; i < static_cast<int> (anBreaks.size ()) - 1; i++, j++ )
+ {
+ if (anBreaks[i] < 0)
+ {
+ if (j < nBreaks)
+ {
+ CRect frect( origin.x, originOrg.y + (j + 1) * GetLineHeight (),
+ origin.x + m_pTextBuffer->GetColumnWidth (nColumn) * nCharWidth, rc.bottom );
+ if (frect.left < rc.left)
+ frect.left = rc.left;
+ if (frect.right > rc.left)
+ m_pCrystalRenderer->FillSolidRectangle (frect, crBkgnd == CLR_NONE ? GetColor(COLORINDEX_WHITESPACE) : crBkgnd);
+ }
+ origin.y = originOrg.y;
+ origin.x += m_pTextBuffer->GetColumnWidth (nColumn++) * nCharWidth;
+ j = -1;
+ }
+ DrawScreenLine(
+ origin, rc,
+ blocks, nActualItem,
+ crText, crBkgnd, bDrawWhitespace,
+ nLineIndex, abs(anBreaks[i]), abs(anBreaks[i + 1]) - abs(anBreaks[i]),
+ nActualOffset, CEPoint( abs(anBreaks[i]), nLineIndex ) );
+ }
+ }
+ else if (layoutMode == TEXTLAYOUT_WORDWRAP && nBreaks > 0)
{
// Draw all the screen lines of the wrapped line
ASSERT( anBreaks[0] < nLength );
origin, rc,
blocks, nActualItem,
crText, crBkgnd, bDrawWhitespace,
- pszChars, 0, anBreaks[0], nActualOffset, CPoint( 0, nLineIndex ) );
+ nLineIndex, 0, anBreaks[0], nActualOffset, CEPoint( 0, nLineIndex ) );
// draw from first break to last break
int i=0;
origin, rc,
blocks, nActualItem,
crText, crBkgnd, bDrawWhitespace,
- pszChars, anBreaks[i], anBreaks[i + 1] - anBreaks[i],
- nActualOffset, CPoint( anBreaks[i], nLineIndex ) );
+ nLineIndex, anBreaks[i], anBreaks[i + 1] - anBreaks[i],
+ nActualOffset, CEPoint( anBreaks[i], nLineIndex ) );
}
// draw from last break till end of line
origin, rc,
blocks, nActualItem,
crText, crBkgnd, bDrawWhitespace,
- pszChars, anBreaks[i], nLength - anBreaks[i],
- nActualOffset, CPoint( anBreaks[i], nLineIndex ) );
+ nLineIndex, anBreaks[i], nLength - anBreaks[i],
+ nActualOffset, CEPoint( anBreaks[i], nLineIndex ) );
}
else
- DrawScreenLine(
- origin, rc,
- blocks, nActualItem,
- crText, crBkgnd, bDrawWhitespace,
- pszChars, 0, nLength, nActualOffset, CPoint(0, nLineIndex));
+ DrawScreenLine(
+ origin, rc,
+ blocks, nActualItem,
+ crText, crBkgnd, bDrawWhitespace,
+ nLineIndex, 0, nLength, nActualOffset, CEPoint(0, nLineIndex));
// Draw empty sublines
int nEmptySubLines = GetEmptySubLines(nLineIndex);
if (nEmptySubLines > 0)
{
CRect frect = rc;
- frect.top = frect.bottom - nEmptySubLines * GetLineHeight();
+ frect.top += (nBreaks + 1) * GetLineHeight ();
m_pCrystalRenderer->FillSolidRectangle(frect, crBkgnd == CLR_NONE ? GetColor(COLORINDEX_WHITESPACE) : crBkgnd);
}
}
int len = strText.GetLength ();
for (int i = 0; i < len; ++i)
{
- TCHAR ch = strText[i];
+ tchar_t ch = strText[i];
switch (ch)
{
case '&':
}
// Make a CString from printf-style args (single call version of CString::Format)
-static CString Fmt(LPCTSTR fmt, ...)
+static CString Fmt(const tchar_t* fmt, ...)
{
CString str;
va_list args;
};
CString strStyles;
- for (int f = 0; f < sizeof(arColorIndices)/sizeof(int); f++)
+ for (int i = 0; i < 2; i++)
{
- int nColorIndex = arColorIndices[f];
- for (int b = 0; b < sizeof(arBgColorIndices)/sizeof(int); b++)
+ for (int f = 0; f < sizeof(arColorIndices) / sizeof(int); f++)
{
- int nBgColorIndex = arBgColorIndices[b];
- COLORREF clr;
-
- strStyles += Fmt (_T(".sf%db%d {"), nColorIndex, nBgColorIndex);
- clr = GetColor (nColorIndex);
- strStyles += Fmt (_T("color: #%02x%02x%02x; "), GetRValue (clr), GetGValue (clr), GetBValue (clr));
- clr = GetColor (nBgColorIndex);
- strStyles += Fmt (_T("background-color: #%02x%02x%02x; "), GetRValue (clr), GetGValue (clr), GetBValue (clr));
- if (GetBold (nColorIndex))
- strStyles += _T("font-weight: bold; ");
- if (GetItalic (nColorIndex))
- strStyles += _T("font-style: italic; ");
- strStyles += _T("}\n");
+ int nColorIndex = arColorIndices[f];
+ for (int b = 0; b < sizeof(arBgColorIndices) / sizeof(int); b++)
+ {
+ int nBgColorIndex = arBgColorIndices[b];
+ CEColor clr;
+
+ strStyles += Fmt(_T(".sf%db%d%s {"), nColorIndex, nBgColorIndex, i == 0 ? _T("") : _T("i"));
+ clr = GetColor(nColorIndex);
+ if (i == 1)
+ clr = CEColor::GetIntermediateColor(clr, GetColor(nBgColorIndex), 0.333f);
+ strStyles += Fmt(_T("color: #%02x%02x%02x; "), GetRValue(clr), GetGValue(clr), GetBValue(clr));
+ clr = GetColor(nBgColorIndex);
+ strStyles += Fmt(_T("background-color: #%02x%02x%02x; "), GetRValue(clr), GetGValue(clr), GetBValue(clr));
+ if (GetBold(nColorIndex))
+ strStyles += _T("font-weight: bold; ");
+ if (GetItalic(nColorIndex))
+ strStyles += _T("font-style: italic; ");
+ strStyles += _T("}\n");
+ }
}
}
- COLORREF clrSelMargin = GetColor(COLORINDEX_SELMARGIN);
- COLORREF clrNormalText = GetColor(COLORINDEX_NORMALTEXT);
- strStyles += Fmt(_T(".ln {text-align: right; word-break: normal; color: #%02x%02x%02x; background-color: #%02x%02x%02x;}\n"),
+ CEColor clrSelMargin = GetColor(COLORINDEX_SELMARGIN);
+ CEColor clrNormalText = GetColor(COLORINDEX_NORMALTEXT);
+ strStyles += Fmt(_T(".cn {text-align: center; word-break: normal; color: #%02x%02x%02x; background-color: #%02x%02x%02x;}\n")
+ _T(".ln {text-align: right; word-break: normal; color: #%02x%02x%02x; background-color: #%02x%02x%02x;}\n"),
+ GetRValue(clrNormalText), GetGValue(clrNormalText), GetBValue(clrNormalText),
+ GetRValue(clrSelMargin), GetGValue(clrSelMargin), GetBValue(clrSelMargin),
GetRValue(clrNormalText), GetGValue(clrNormalText), GetBValue(clrNormalText),
GetRValue(clrSelMargin), GetGValue(clrSelMargin), GetBValue(clrSelMargin));
return strStyles;
* @return The HTML attribute
*/
CString CCrystalTextView::
-GetHTMLAttribute (int nColorIndex, int nBgColorIndex, COLORREF crText, COLORREF crBkgnd)
+GetHTMLAttribute (int nColorIndex, int nBgColorIndex, CEColor crText, CEColor crBkgnd)
{
CString strAttr;
- COLORREF clr;
+ CEColor clr, clrBk;
if ((crText == CLR_NONE || (nColorIndex & COLORINDEX_APPLYFORCE)) &&
(crBkgnd == CLR_NONE || (nBgColorIndex & COLORINDEX_APPLYFORCE)))
- return Fmt(_T("class=\"sf%db%d\""), nColorIndex & ~COLORINDEX_APPLYFORCE, nBgColorIndex & ~COLORINDEX_APPLYFORCE);
+ return Fmt(_T("class=\"sf%db%d%s\""), nColorIndex & ~COLORINDEX_MASK, nBgColorIndex & ~COLORINDEX_MASK,
+ (nColorIndex & COLORINDEX_INTERMEDIATECOLOR) ? _T("i") : _T(""));
if (crText == CLR_NONE || (nColorIndex & COLORINDEX_APPLYFORCE))
clr = GetColor (nColorIndex);
else
clr = crText;
- strAttr += Fmt (_T("style=\"color: #%02x%02x%02x; "), GetRValue (clr), GetGValue (clr), GetBValue (clr));
-
if (crBkgnd == CLR_NONE || (nBgColorIndex & COLORINDEX_APPLYFORCE))
- clr = GetColor (nBgColorIndex);
+ clrBk = GetColor (nBgColorIndex);
else
- clr = crBkgnd;
- strAttr += Fmt (_T("background-color: #%02x%02x%02x; "), GetRValue (clr), GetGValue (clr), GetBValue (clr));
+ clrBk = crBkgnd;
+ if (nColorIndex & COLORINDEX_INTERMEDIATECOLOR)
+ clr = CEColor::GetIntermediateColor(clr, clrBk, 0.333f);
+ strAttr += Fmt (_T("style=\"color: #%02x%02x%02x; "), GetRValue (clr), GetGValue (clr), GetBValue (clr));
+ strAttr += Fmt (_T("background-color: #%02x%02x%02x; "), GetRValue (clrBk), GetGValue (clrBk), GetBValue (clrBk));
if (GetBold (nColorIndex))
strAttr += _T("font-weight: bold; ");
return strAttr;
}
+CString CCrystalTextView::
+GetColumnName(int nColumn)
+{
+ CString columnName;
+ for (int i = 0; ; ++i)
+ {
+ tchar_t c = 'A' + (nColumn % 26) - (i == 0 ? 0 : 1);
+ columnName.Insert (0, c);
+ nColumn /= 26;
+ if (nColumn == 0)
+ break;
+ }
+ return columnName;
+};
+
/**
* @brief Retrieve the html version of the line
* @param [in] nLineIndex Index of line in view
* @param [in] pszTag The HTML tag to enclose the line
+ * @param [in] nColumnCountMax Maximum number of columns
* @return The html version of the line
*/
CString CCrystalTextView::
-GetHTMLLine (int nLineIndex, LPCTSTR pszTag)
+GetHTMLLine (int nLineIndex, const tchar_t* pszTag, int nColumnCountMax)
{
ASSERT (nLineIndex >= -1 && nLineIndex < GetLineCount ());
int nLength = GetViewableLineLength (nLineIndex);
- LPCTSTR pszChars = GetLineChars (nLineIndex);
// Acquire the background color for the current line
bool bDrawWhitespace = false;
- COLORREF crBkgnd, crText;
+ CEColor crBkgnd, crText;
GetLineColors (nLineIndex, crBkgnd, crText, bDrawWhitespace);
std::vector<TEXTBLOCK> blocks = GetTextBlocks(nLineIndex);
-
+ int nColumn = 0;
+ const int nColumnCount = m_pTextBuffer->GetColumnCount (nLineIndex);
CString strHTML;
CString strExpanded;
- size_t i;
int nNonbreakChars = 0;
bool bLastCharSpace = false;
const int nScreenChars = 40; // GetScreenChars();
- strHTML += _T("<");
- strHTML += pszTag;
- strHTML += _T(" ");
- strHTML += GetHTMLAttribute (COLORINDEX_NORMALTEXT, COLORINDEX_BKGND, crText, crBkgnd);
- strHTML += _T("><code>");
-
auto MakeSpan = [&](const TEXTBLOCK& block, const CString& strExpanded) {
- CString strHTML;
- strHTML += _T("<span ");
- strHTML += GetHTMLAttribute (block.m_nColorIndex, block.m_nBgColorIndex, crText, crBkgnd);
- strHTML += _T(">");
- strHTML += EscapeHTML (strExpanded, bLastCharSpace, nNonbreakChars, nScreenChars);
- strHTML += _T("</span>");
- return strHTML;
- };
+ CString strHTML;
+ strHTML += _T("<span ");
+ strHTML += GetHTMLAttribute (block.m_nColorIndex, block.m_nBgColorIndex, crText, crBkgnd);
+ strHTML += _T(">");
+ strHTML += EscapeHTML (strExpanded, bLastCharSpace, nNonbreakChars, nScreenChars);
+ strHTML += _T("</span>");
+ return strHTML;
+ };
+
+ const TextLayoutMode layoutMode = GetTextLayoutMode ();
+ if (layoutMode == TEXTLAYOUT_TABLE_NOWORDWRAP ||
+ layoutMode == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ std::vector<int> anBreaks;
+ if (layoutMode == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ int nBreaks = 0;
+ anBreaks.resize (GetLineLength(nLineIndex) + 1);
+ WrapLineCached ( nLineIndex, nScreenChars, &anBreaks, nBreaks );
+ }
+ anBreaks.push_back (-nLength);
- for (i = 0; i < blocks.size() - 1; i++)
+ const tchar_t* pszChars = GetLineChars (nLineIndex);
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ bool bInQuote = false;
+
+ strHTML += _T("<");
+ strHTML += pszTag;
+ strHTML += _T(" ");
+ if (nColumn + 1 == nColumnCount && (nColumnCountMax - nColumn) > 1)
+ {
+ CString colspan;
+ colspan.Format (_T("colspan=\"%d\" "), nColumnCountMax - nColumn);
+ strHTML += colspan;
+ }
+ strHTML += GetHTMLAttribute (COLORINDEX_NORMALTEXT, COLORINDEX_BKGND, crText, crBkgnd);
+ strHTML += _T("><code>");
+ int k = 0;
+ for (size_t j = 0; j < blocks.size(); j++)
+ {
+ int blockBegin = blocks[j].m_nCharPos;
+ int blockEnd = (j + 1 < blocks.size()) ? blocks[j + 1].m_nCharPos : nLength;
+ for (int i = blockBegin; i < blockEnd; i++)
+ {
+ tchar_t c = pszChars[i];
+ if (abs(anBreaks[k]) == i)
+ {
+ if (anBreaks[k] >= 0)
+ {
+ ExpandChars (nLineIndex, blockBegin, i - blockBegin, strExpanded, 0);
+ strHTML += MakeSpan (blocks[j], strExpanded);
+ strHTML += _T("<br />");
+ blockBegin = i;
+ }
+ k++;
+ }
+ if (!bInQuote && c == sep)
+ {
+ ExpandChars (nLineIndex, blockBegin, i + 1 - blockBegin, strExpanded, 0);
+ strHTML += MakeSpan (blocks[j], strExpanded);
+ blockBegin = i + 1;
+ bLastCharSpace = false;
+ nNonbreakChars = 0;
+ nColumn++;
+ strHTML += _T("</code></");
+ strHTML += pszTag;
+ strHTML += _T("><");
+ strHTML += pszTag;
+ strHTML += _T(" ");
+ if (nColumn + 1 == nColumnCount && (nColumnCountMax - nColumn) > 1)
+ {
+ CString colspan;
+ colspan.Format (_T("colspan=\"%d\" "), nColumnCountMax - nColumn);
+ strHTML += colspan;
+ }
+ strHTML += GetHTMLAttribute (COLORINDEX_NORMALTEXT, COLORINDEX_BKGND, crText, crBkgnd);
+ strHTML += _T("><code>");
+ }
+ else if (c == quote)
+ {
+ bInQuote = !bInQuote;
+ }
+ }
+ ExpandChars (nLineIndex, blockBegin, blockEnd - blockBegin, strExpanded, 0);
+ strHTML += MakeSpan (blocks[j], strExpanded);
+ }
+ strHTML += _T("</code></");
+ strHTML += pszTag;
+ strHTML += _T(">");
+ }
+ else
{
- ExpandChars (pszChars, blocks[i].m_nCharPos, blocks[i + 1].m_nCharPos - blocks[i].m_nCharPos, strExpanded, 0);
- if (!strExpanded.IsEmpty())
- strHTML += MakeSpan(blocks[i], strExpanded);
+ strHTML += _T("<");
+ strHTML += pszTag;
+ strHTML += _T(" ");
+ strHTML += GetHTMLAttribute (COLORINDEX_NORMALTEXT, COLORINDEX_BKGND, crText, crBkgnd);
+ strHTML += _T("><code>");
+
+ size_t i;
+ for (i = 0; i < blocks.size() - 1; i++)
+ {
+ ExpandChars (nLineIndex, blocks[i].m_nCharPos, blocks[i + 1].m_nCharPos - blocks[i].m_nCharPos, strExpanded, 0);
+ if (!strExpanded.IsEmpty())
+ strHTML += MakeSpan(blocks[i], strExpanded);
+ }
+ if (blocks.size() > 0)
+ {
+ ExpandChars (nLineIndex, blocks[i].m_nCharPos, nLength - blocks[i].m_nCharPos, strExpanded, 0);
+ if (!strExpanded.IsEmpty())
+ strHTML += MakeSpan(blocks[i], strExpanded);
+ if (strExpanded.Compare (CString (' ', strExpanded.GetLength())) == 0)
+ strHTML += _T(" ");
+ }
+ strHTML += _T("</code></");
+ strHTML += pszTag;
+ strHTML += _T(">");
}
- if (blocks.size() > 0)
- {
- ExpandChars (pszChars, blocks[i].m_nCharPos, nLength - blocks[i].m_nCharPos, strExpanded, 0);
- if (!strExpanded.IsEmpty())
- strHTML += MakeSpan(blocks[i], strExpanded);
- if (strExpanded.Compare (CString (' ', strExpanded.GetLength())) == 0)
- strHTML += _T(" ");
- }
- strHTML += _T("</code></");
- strHTML += pszTag;
- strHTML += _T(">");
return strHTML;
}
-COLORREF CCrystalTextView::
-GetColor (int nColorIndex)
+CEColor CCrystalTextView::
+GetColor (int nColorIndex) const
{
if (m_pColors != nullptr)
{
- nColorIndex &= ~COLORINDEX_APPLYFORCE;
+ nColorIndex &= ~COLORINDEX_MASK;
return m_pColors->GetColor(nColorIndex);
}
else
- return RGB(0, 0, 0);
+ return { 0, 0, 0 };
}
-DWORD CCrystalTextView::
+lineflags_t CCrystalTextView::
GetLineFlags (int nLineIndex) const
{
if (m_pTextBuffer == nullptr)
return m_pTextBuffer->GetLineFlags (nLineIndex);
}
+void CCrystalTextView::
+GetTopMarginText (const CRect& rect, CString& text, std::vector<int>& nWidths)
+{
+ auto replaceControlChars = [](const CString& text) -> CString
+ {
+ CString result;
+ for (int i = 0; i < text.GetLength(); ++i)
+ {
+ if (_istcntrl(text[i]))
+ {
+ if (i == 0 || !_istcntrl(text[i - 1]))
+ result += L' ';
+ }
+ else
+ result += text[i];
+ }
+ return result;
+ };
+
+ const int nCharWidth = GetCharWidth ();
+ const int nMarginWidth = GetMarginWidth ();
+ for (int nColumn = 0, x = nMarginWidth - m_nOffsetChar * nCharWidth; x < rect.Width (); ++nColumn)
+ {
+ int nColumnWidth = m_pTextBuffer->GetColumnWidth (nColumn);
+ CString columnName;
+ if (m_nLineNumberUsedAsHeaders >= 0 && m_nLineNumberUsedAsHeaders < m_pTextBuffer->GetLineCount() &&
+ (m_nTopSubLine > 0 || (m_pTextBuffer->GetLineFlags(m_nLineNumberUsedAsHeaders) & LF_INVISIBLE)))
+ columnName = replaceControlChars (m_pTextBuffer->GetCellText (m_nLineNumberUsedAsHeaders, nColumn).c_str ()); // Use std::basic_string<tchar_t> instead of CString
+ if (columnName.IsEmpty())
+ columnName = GetColumnName (nColumn);
+ int columnNameLen = 0;
+ std::vector<int> nCharWidths;
+ for (int i = 0; i < columnName.GetLength(); ++i)
+ {
+ int cnt = GetCharCellCountFromChar (((const tchar_t*)columnName) + i);
+ nCharWidths.push_back (cnt * nCharWidth);
+ columnNameLen += cnt;
+ }
+ while (nColumnWidth < columnNameLen)
+ {
+ columnNameLen -= nCharWidths.back() / nCharWidth;
+ columnName.Truncate(columnName.GetLength() - 1);
+ nCharWidths.resize(columnName.GetLength());
+ }
+ const int leftspaces = (nColumnWidth - columnNameLen) / 2;
+ const int rightspaces = nColumnWidth - leftspaces - columnNameLen;
+ text += CString (' ', leftspaces) + columnName + CString (' ', rightspaces);
+ std::vector<int> preWidths(leftspaces, nCharWidth);
+ std::vector<int> postWidths(rightspaces, nCharWidth);
+ nCharWidths.insert (nCharWidths.begin (), preWidths.begin (), preWidths.end ());
+ nCharWidths.insert (nCharWidths.end (), postWidths.begin (), postWidths.end ());
+ x += nColumnWidth * nCharWidth;
+ nWidths.insert (nWidths.end (), nCharWidths.begin (), nCharWidths.end ());
+ }
+}
+
+void CCrystalTextView::
+DrawTopMargin (const CRect& rect)
+{
+ if (!m_bTopMargin)
+ return;
+ m_pCrystalRenderer->SetBkColor (GetColor (COLORINDEX_SELMARGIN));
+ m_pCrystalRenderer->FillRectangle (rect);
+ m_pCrystalRenderer->SetTextColor (GetColor (COLORINDEX_NORMALTEXT));
+ if (m_pTextBuffer->GetTableEditing ())
+ {
+ CString columnNames;
+ std::vector<int> nWidths;
+ GetTopMarginText (rect, columnNames, nWidths);
+ m_pCrystalRenderer->SwitchFont (false, false);
+ m_pCrystalRenderer->DrawText (rect.left + GetMarginWidth () - m_nOffsetChar * GetCharWidth (), 0, rect, columnNames, columnNames.GetLength (), nWidths.data ());
+ }
+ else
+ m_pCrystalRenderer->DrawRuler (GetMarginWidth (), 0, rect.Width (), rect.Height (), GetCharWidth (), m_nOffsetChar);
+}
+
/**
* @brief Draw selection margin.
* @param [in] pdc Pointer to draw context.
}
// Draw line revision mark (or background) whenever we have valid lineindex
- COLORREF clrRevisionMark = GetColor(COLORINDEX_WHITESPACE);
+ CEColor clrRevisionMark = GetColor(COLORINDEX_WHITESPACE);
if (nLineIndex >= 0 && m_pTextBuffer != nullptr)
{
// get line revision marks color
- DWORD dwRevisionNumber = m_pTextBuffer->GetLineRevisionNumber(nLineIndex);
+ uint32_t dwRevisionNumber = m_pTextBuffer->GetLineRevisionNumber(nLineIndex);
if (dwRevisionNumber > 0)
{
if (m_pTextBuffer->m_dwRevisionNumberOnSave < dwRevisionNumber)
int nImageIndex = -1;
if (nLineIndex >= 0)
{
- DWORD dwLineFlags = GetLineFlags (nLineIndex);
- static const DWORD adwFlags[] =
+ lineflags_t dwLineFlags = GetLineFlags (nLineIndex);
+ static const lineflags_t adwFlags[] =
{
LF_EXECUTION,
LF_BREAKPOINT,
}
if (nImageIndex >= 0)
{
+ const int iconsize = GetMarginIconSize();
m_pCrystalRenderer->DrawMarginIcon(
- rect.left + 2, rect.top + (GetLineHeight() - CCrystalRenderer::MARGIN_ICON_HEIGHT) / 2, nImageIndex);
+ rect.left + 2, rect.top + (GetLineHeight() - iconsize) / 2, nImageIndex, iconsize);
}
// draw wrapped-line-icon
if (nLineNumber > 0)
{
+ const int iconsize = GetMarginIconSize();
int nBreaks = 0;
WrapLineCached( nLineIndex, GetScreenChars(), nullptr, nBreaks );
for (int i = 0; i < nBreaks; i++)
{
m_pCrystalRenderer->DrawMarginIcon(
- rect.right - CCrystalRenderer::MARGIN_ICON_WIDTH, rect.top + (GetLineHeight()
- - CCrystalRenderer::MARGIN_ICON_WIDTH) / 2 + (i+1) * GetLineHeight(), ICON_INDEX_WRAPLINE);
+ rect.right - iconsize, rect.top + (GetLineHeight()
+ - iconsize) / 2 + (i+1) * GetLineHeight(), ICON_INDEX_WRAPLINE, iconsize);
}
}
}
bool CCrystalTextView::
-IsInsideSelBlock (CPoint ptTextPos)
+IsInsideSelBlock (CEPoint ptTextPos)
{
PrepareSelBounds();
ASSERT_VALIDTEXTPOS (ptTextPos);
return false;
if (ptTextPos.y > m_ptDrawSelEnd.y)
return false;
- if (m_bColumnSelection)
+ if (m_bRectangularSelection)
return ptTextPos.x >= m_ptDrawSelStart.x && ptTextPos.x < m_ptDrawSelEnd.x;
if (ptTextPos.y < m_ptDrawSelEnd.y && ptTextPos.y > m_ptDrawSelStart.y)
return true;
}
bool CCrystalTextView::
-IsInsideSelection (const CPoint & ptTextPos)
+IsInsideSelection (const CEPoint & ptTextPos)
{
PrepareSelBounds ();
return IsInsideSelBlock (ptTextPos);
int nCursorY = TextToClient (m_ptCursorPos).y;
CRect rcLine;
+ CRect rcTopMargin(rcClient.left, rcClient.top, rcClient.right, rcClient.top + GetTopMarginHeight());
rcLine = rcClient;
- rcLine.top += nSubLineOffset * nLineHeight;
+ rcLine.top = rcTopMargin.bottom + nSubLineOffset * nLineHeight;
CRect rcMargin (rcLine.left, rcLine.top, rcLine.left + GetMarginWidth (), rcLine.top + nLineHeight);
rcLine.left = rcMargin.right;
m_pCrystalRenderer->BindDC(cacheDC, rcClient);
m_pCrystalRenderer->BeginDraw();
+ int nLastLineBottom = 0;
int nCurrentLine = m_nTopLine;
while (rcLine.top < rcClient.bottom)
{
int nSubLines = 1;
if( nCurrentLine < nLineCount /*&& GetLineLength( nCurrentLine ) > nMaxLineChars*/ )
- nSubLines = GetSubLines(nCurrentLine);
+ nSubLines = GetSubLines(nCurrentLine);
- rcLine.bottom = rcLine.top + nSubLines * nLineHeight;
+ rcLine.bottom = (std::min)(rcClient.bottom, rcLine.top + nSubLines * nLineHeight);
rcMargin.bottom = rcLine.bottom;
CRect rcMarginAndLine(rcClient.left, rcLine.top, rcClient.right, rcLine.bottom);
DrawMargin (rcMargin, nCurrentLine, nCurrentLine + 1);
DrawSingleLine (rcLine, nCurrentLine);
if (nCurrentLine+1 < nLineCount && !GetLineVisible (nCurrentLine + 1))
- m_pCrystalRenderer->DrawBoundaryLine (rcMargin.left, rcLine.right, rcMargin.bottom-1);
+ m_pCrystalRenderer->DrawBoundaryLine (rcMargin.left, rcLine.right, rcMargin.top + nSubLines * nLineHeight - 1);
+ if (m_pTextBuffer->GetTableEditing ())
+ m_pCrystalRenderer->DrawGridLine (rcMargin.left, rcMargin.top + nSubLines * nLineHeight - 1, rcLine.right, rcMargin.top + nSubLines * nLineHeight - 1, 24);
if (nCurrentLine == m_ptCursorPos.y)
m_pCrystalRenderer->DrawLineCursor (rcMargin.left, rcLine.right,
nCursorY + nLineHeight - 1, 1);
+ nLastLineBottom = rcMargin.bottom;
}
else
{
}
nCurrentLine++;
- rcLine.top = rcLine.bottom;
+ rcLine.top += nSubLines * nLineHeight;
rcMargin.top = rcLine.top;
}
+ if (pdc->RectVisible (rcTopMargin))
+ DrawTopMargin (rcTopMargin);
+
+ if (m_pTextBuffer->GetTableEditing ())
+ {
+ int nCharWidth = GetCharWidth ();
+ int nMarginWidth = GetMarginWidth ();
+ for (int nColumn = 0, x = nMarginWidth - m_nOffsetChar * nCharWidth;
+ x < rcClient.Width();
+ x += m_pTextBuffer->GetColumnWidth (nColumn++) * nCharWidth)
+ {
+ if (x >= nMarginWidth && nColumn > 0)
+ m_pCrystalRenderer->DrawGridLine (x, rcClient.top, x, nLastLineBottom, 24);
+ }
+ }
+
m_pCrystalRenderer->EndDraw();
VERIFY (pdc->BitBlt (rcClient.left, rcClient.top, rcClient.Width (),
{
ASSERT_VALIDTEXTPOS (m_ptCursorPos);
if (m_bFocused && !m_bCursorHidden &&
- CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x) >= m_nOffsetChar)
+ CalculateActualOffset (m_ptCursorPos.y, m_ptCursorPos.x) >= m_nOffsetChar &&
+ m_ptCursorPos.y >= m_nTopLine)
{
int nCaretHeight = GetLineVisible(m_ptCursorPos.y) ? GetLineHeight () : 0;
- if (m_bOverrideCaret) //UPDATE
- CreateSolidCaret(GetCharWidth(), nCaretHeight);
+ if (m_bOvrMode) //UPDATE
+ {
+ int nCaretWidth = GetCharWidth ();
+ if (m_ptCursorPos.x < GetLineLength (m_ptCursorPos.y))
+ {
+ const tchar_t* pszLine = GetLineChars (m_ptCursorPos.y);
+ if (pszLine[m_ptCursorPos.x] != '\t')
+ nCaretWidth *= GetCharCellCountFromChar (pszLine + m_ptCursorPos.x);
+ }
+ CreateSolidCaret (nCaretWidth, nCaretHeight);
+ }
else
CreateSolidCaret (2, nCaretHeight);
{
}
-int CCrystalTextView::
+CRLFSTYLE CCrystalTextView::
GetCRLFMode ()
{
if (m_pTextBuffer != nullptr)
{
return m_pTextBuffer->GetCRLFMode ();
}
- return -1;
+ return CRLFSTYLE::AUTOMATIC;
}
void CCrystalTextView::
m_pTextBuffer->SetTabSize( nTabSize );
m_pnActualLineLength->clear();
- RecalcHorzScrollBar ();
+ InvalidateHorzScrollBar ();
Invalidate ();
UpdateCaret ();
}
return GetEmptySubLines(nLineIndex) + nBreaks + 1;
}
-int CCrystalTextView::GetEmptySubLines( int nLineIndex )
-{
- return 0;
-}
-
bool CCrystalTextView::IsEmptySubLineIndex( int nSubLineIndex )
{
int nLineIndex;
return false;
}
-int CCrystalTextView::CharPosToPoint( int nLineIndex, int nCharPos, CPoint &charPoint )
+int CCrystalTextView::CharPosToPoint( int nLineIndex, int nCharPos, CEPoint &charPoint, int* pnColumn )
{
// if we do not wrap lines, y is allways 0 and x is equl to nCharPos
if (!m_bWordWrap)
vector<int> anBreaks(GetLineLength (nLineIndex) + 1);
int nBreaks = 0;
- WrapLineCached (nLineIndex, GetScreenChars(), &anBreaks[0], nBreaks);
+ WrapLineCached (nLineIndex, GetScreenChars(), &anBreaks, nBreaks);
- int i = (nBreaks <= 0) ? -1 : nBreaks - 1;
- for (; i >= 0 && nCharPos < anBreaks[i]; i--)
- ; // Empty loop!
+ if (GetTextLayoutMode () == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ int nColumn = 0;
+ int j = 0;
+ size_t i = 0;
+ for (; i < anBreaks.size () && abs (anBreaks[i]) <= nCharPos ; ++i)
+ {
+ if (anBreaks[i] < 0)
+ {
+ nColumn++;
+ j = 0;
+ }
+ else
+ ++j;
+ }
+ charPoint.x = (i > 0) ? nCharPos - abs (anBreaks[i - 1]) : nCharPos;
+ charPoint.y = j;
+ if (pnColumn)
+ *pnColumn = nColumn;
- charPoint.x = (i >= 0)? nCharPos - anBreaks[i] : nCharPos;
- charPoint.y = i + 1;
+ return (i > 0)? abs (anBreaks[i - 1]) : 0;
+ }
+ else
+ {
+ int i = (nBreaks <= 0) ? -1 : nBreaks - 1;
+ for (; i >= 0 && nCharPos < anBreaks[i]; i--)
+ ; // Empty loop!
- int nReturnVal = (i >= 0)? anBreaks[i] : 0;
+ charPoint.x = (i >= 0)? nCharPos - anBreaks[i] : nCharPos;
+ charPoint.y = i + 1;
- return nReturnVal;
+ int nReturnVal = (i >= 0)? anBreaks[i] : 0;
+
+ return nReturnVal;
+ }
}
/** Does character introduce a multicharacter character? */
-static inline bool IsLeadByte(TCHAR ch)
+static inline bool IsLeadByte(tchar_t ch)
{
#ifdef UNICODE
return false;
#endif
}
-int CCrystalTextView::CursorPointToCharPos( int nLineIndex, const CPoint &curPoint )
+int CCrystalTextView::CursorPointToCharPos( int nLineIndex, const CEPoint &curPoint )
{
// calculate char pos out of point
const int nLength = GetLineLength( nLineIndex );
const int nScreenChars = GetScreenChars();
- LPCTSTR szLine = GetLineChars( nLineIndex );
+ const tchar_t* szLine = GetLineChars( nLineIndex );
// wrap line
vector<int> anBreaks(nLength + 1);
int nBreaks = 0;
- WrapLineCached( nLineIndex, nScreenChars, &anBreaks[0], nBreaks );
+ WrapLineCached( nLineIndex, nScreenChars, &anBreaks, nBreaks );
// find char pos that matches cursor position
int nXPos = 0;
int nIndex=0, nPrevIndex = 0;
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(szLine, nLength);
- for( nIndex = 0; nIndex < nLength; nIndex = pIterChar->next())
+ switch (GetTextLayoutMode ())
{
- if( nBreaks > 0 && nIndex == anBreaks[nYPos] )
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
{
- nXPos = 0;
- nYPos++;
- }
+ int nColumnCount = m_pTextBuffer->GetColumnCount (nLineIndex);
+ int nColumnTotalWidth = 0;
+ int nColumn = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ for( nIndex = 0; nIndex < nLength; nIndex = pIterChar->next())
+ {
+ int nOffset;
+ if (!bInQuote && szLine[nIndex] == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nOffset = nColumnTotalWidth - nXPos;
+ }
+ else
+ {
+ if (szLine[nIndex] == quote)
+ bInQuote = !bInQuote;
+ if (szLine[nIndex] == '\t')
+ nOffset = 1;
+ else
+ nOffset = GetCharCellCountFromChar (szLine + nIndex);
+ if (nColumn < nColumnCount && nCurPos + nOffset > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nOffset = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn) - nXPos;
+ }
+ nXPos += nOffset;
+ nCurPos += nOffset;
- int nOffset;
- if (szLine[nIndex] == _T('\t'))
- nOffset = nTabSize - nCurPos % nTabSize;
- else
- nOffset = GetCharCellCountFromChar(szLine + nIndex);
- nXPos += nOffset;
- nCurPos += nOffset;
+ if( nXPos > curPoint.x && nYPos == curPoint.y )
+ break;
+ else if( nYPos > curPoint.y )
+ {
+ nIndex = nPrevIndex;
+ break;
+ }
- if( nXPos > curPoint.x && nYPos == curPoint.y )
+ nPrevIndex = nIndex;
+ }
+ }
break;
- else if( nYPos > curPoint.y )
+ case TEXTLAYOUT_TABLE_WORDWRAP:
{
- nIndex = nPrevIndex;
- break;
+ int i = 0;
+ int nColumn = 0;
+ int nColumnSumWidth = 0;
+ int nColumnCurPoint = INT_MAX;
+ if (curPoint.x < m_pTextBuffer->GetColumnWidth (0))
+ nColumnCurPoint = 0;
+ for( nIndex = 0; nIndex < nLength; nIndex = pIterChar->next ())
+ {
+ if (i < static_cast<int>(anBreaks.size ()) && nIndex == abs (anBreaks[i]))
+ {
+ if (anBreaks[i++] < 0)
+ {
+ nYPos = 0;
+ nColumnSumWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nXPos = nColumnSumWidth;
+ if (nColumnSumWidth <= curPoint.x && curPoint.x < nColumnSumWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nColumnCurPoint = nColumn;
+ }
+ else
+ {
+ nXPos = nColumnSumWidth;
+ nYPos++;
+ }
+ }
+
+ int nOffset;
+ if (szLine[nIndex] == '\t')
+ nOffset = 1;
+ else
+ nOffset = GetCharCellCountFromChar (szLine + nIndex);
+ nXPos += nOffset;
+ nCurPos += nOffset;
+
+ if( nXPos > curPoint.x && nYPos == curPoint.y )
+ break;
+ else if( nColumnCurPoint < nColumn && nPrevIndex != 0)
+ {
+ nIndex = nPrevIndex;
+ break;
+ }
+ else if ( nYPos == curPoint.y)
+ nPrevIndex = nIndex;
+ }
+ if (nIndex == nLength && nYPos != curPoint.y)
+ nIndex = nPrevIndex;
}
+ break;
+ default:
+ {
+ for( nIndex = 0; nIndex < nLength; nIndex = pIterChar->next())
+ {
+ if( nBreaks > 0 && nYPos < static_cast<int>(anBreaks.size ()) && nIndex == anBreaks[nYPos] )
+ {
+ nXPos = 0;
+ nYPos++;
+ }
- nPrevIndex = nIndex;
- }
+ int nOffset;
+ if (szLine[nIndex] == _T('\t'))
+ nOffset = nTabSize - nCurPos % nTabSize;
+ else
+ nOffset = GetCharCellCountFromChar(szLine + nIndex);
+ nXPos += nOffset;
+ nCurPos += nOffset;
+
+ if( nXPos > curPoint.x && nYPos == curPoint.y )
+ break;
+ else if( nYPos > curPoint.y )
+ {
+ nIndex = nPrevIndex;
+ break;
+ }
+ nPrevIndex = nIndex;
+ }
+ }
+ }
return nIndex;
}
-void CCrystalTextView::SubLineCursorPosToTextPos( const CPoint &subLineCurPos, CPoint &textPos )
+void CCrystalTextView::SubLineCursorPosToTextPos( const CEPoint &subLineCurPos, CEPoint &textPos )
{
// Get line breaks
int nSubLineOffset, nLine;
GetLineBySubLine( subLineCurPos.y, nLine, nSubLineOffset );
// compute cursor-position
- textPos.x = CursorPointToCharPos( nLine, CPoint( subLineCurPos.x, nSubLineOffset ) );
+ textPos.x = CursorPointToCharPos( nLine, CEPoint( subLineCurPos.x, nSubLineOffset ) );
textPos.y = nLine;
}
vector<int> anBreaks(nLength + 1);
int nBreaks = 0;
- WrapLineCached(nLineIndex, GetScreenChars(), &anBreaks[0], nBreaks);
+ WrapLineCached(nLineIndex, GetScreenChars(), &anBreaks, nBreaks);
+
+ if (GetTextLayoutMode() == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ int nBreakLast = -1;
+ for (int i = 0, j = 1; i < static_cast<int>(anBreaks.size ()); ++i, ++j)
+ {
+ if (anBreaks[i] < 0)
+ j = 0;
+ if (j == nSubLineOffset)
+ nBreakLast = i;
+ }
+ if (nBreakLast < static_cast<int>(anBreaks.size ()) - 1)
+ return abs (anBreaks[nBreakLast + 1]) - 1;
+ return nLength;
+ }
// if there is no break inside the line or the given subline is the last
// one in this line...
vector<int> anBreaks(nLength + 1);
int nBreaks = 0;
- WrapLineCached(nLineIndex, GetScreenChars(), &anBreaks[0], nBreaks);
+ WrapLineCached(nLineIndex, GetScreenChars(), &anBreaks, nBreaks);
+
+ if (GetTextLayoutMode() == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ for (int i = 0, j = 1; i < static_cast<int>(anBreaks.size ()); ++i, ++j)
+ {
+ if (anBreaks[i] < 0)
+ j = 0;
+ if (j == nSubLineOffset)
+ return abs (anBreaks[i]);
+ }
+ return 0;
+ }
// if there is no break inside the line...
if (nBreaks == 0)
return nMaxLineLength;
}
+bool CCrystalTextView::
+CoverLength(int nTopLine, int nLines, int min_length)
+{
+ const int nLineCount = (std::min)(nTopLine + nLines, GetLineCount ());
+ for (int I = nTopLine; I != nLineCount; I++)
+ {
+ if (GetLineActualLength (I) >= min_length)
+ return true;
+ }
+ return false;
+}
+
CCrystalTextView *CCrystalTextView::
GetSiblingView (int nRow, int nCol)
{
GoToLine (int nLine, bool bRelative)
{
int nLines = m_pTextBuffer->GetLineCount () - 1;
- CPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptCursorPos = GetCursorPos ();
if (bRelative)
{
nLine += ptCursorPos.y;
OnInitialUpdate ()
{
CView::OnInitialUpdate ();
- CString sDoc = GetDocument ()->GetPathName (), sExt = GetExt (sDoc);
- if (!sExt.IsEmpty())
- SetTextType (sExt);
+ std::basic_string<tchar_t> sDoc = GetDocument ()->GetPathName (), sExt = GetExt (sDoc);
+ if (!sExt.empty ())
+ SetTextType (sExt.c_str ());
AttachToBuffer (nullptr);
CSplitterWnd *pSplitter = GetParentSplitter (this, false);
}
}
SetFont (m_LogFont);
- if (m_bRememberLastPos && !sDoc.IsEmpty ())
- {
- DWORD dwLastPos[3];
- CString sKey = REG_EDITPAD;
- sKey += _T ("\\Remembered");
- CReg reg;
- if (reg.Open (HKEY_CURRENT_USER, sKey, KEY_READ) &&
- reg.LoadBinary (sDoc, (LPBYTE) dwLastPos, sizeof (dwLastPos)))
- {
- CPoint ptCursorPos;
- ptCursorPos.x = dwLastPos[1];
- ptCursorPos.y = dwLastPos[2];
- if (IsValidTextPosY (ptCursorPos))
- {
- if (!IsValidTextPosX (ptCursorPos))
- ptCursorPos.x = 0;
- ASSERT_VALIDTEXTPOS (ptCursorPos);
- SetCursorPos (ptCursorPos);
- SetSelection (ptCursorPos, ptCursorPos);
- SetAnchor (ptCursorPos);
- EnsureVisible (ptCursorPos);
- }
- }
- }
}
/////////////////////////////////////////////////////////////////////////////
void CCrystalTextView::
GetPrintMargins (long & nLeft, long & nTop, long & nRight, long & nBottom)
{
- nLeft = DEFAULT_PRINT_MARGIN;
- nTop = DEFAULT_PRINT_MARGIN;
- nRight = DEFAULT_PRINT_MARGIN;
- nBottom = DEFAULT_PRINT_MARGIN;
- CReg reg;
- if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ))
- {
- DWORD dwTemp;
- if (reg.LoadNumber (_T ("PageLeft"), &dwTemp))
- nLeft = dwTemp;
- if (reg.LoadNumber (_T ("PageRight"), &dwTemp))
- nRight = dwTemp;
- if (reg.LoadNumber (_T ("PageTop"), &dwTemp))
- nTop = dwTemp;
- if (reg.LoadNumber (_T ("PageBottom"), &dwTemp))
- nBottom = dwTemp;
- }
+ CWinApp *pApp = AfxGetApp ();
+ ASSERT (pApp != nullptr);
+ nLeft = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageLeft"), DEFAULT_PRINT_MARGIN);
+ nRight = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageRight"), DEFAULT_PRINT_MARGIN);
+ nTop = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageTop"), DEFAULT_PRINT_MARGIN);
+ nBottom = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageBottom"), DEFAULT_PRINT_MARGIN);
}
void CCrystalTextView::
m_rcPrintArea = m_ptPageArea;
CSize szTopLeft, szBottomRight;
- CWinApp *pApp = AfxGetApp ();
- ASSERT (pApp != nullptr);
GetPrintMargins (szTopLeft.cx, szTopLeft.cy, szBottomRight.cx, szBottomRight.cy);
pdc->HIMETRICtoLP (&szTopLeft);
pdc->HIMETRICtoLP (&szBottomRight);
OnEndPrinting (CDC * pdc, CPrintInfo * pInfo)
{
if (m_pCrystalRendererSaved)
- {
- m_pCrystalRenderer.reset(m_pCrystalRendererSaved);
- m_pCrystalRendererSaved = nullptr;
- }
+ {
+ m_pCrystalRenderer.reset(m_pCrystalRendererSaved);
+ m_pCrystalRendererSaved = nullptr;
+ }
if (m_pPrintFont != nullptr)
{
delete m_pPrintFont;
{
pdc->SelectObject (m_pPrintFont);
- const COLORREF defaultLineColor = RGB(0,0,0);
- const COLORREF defaultBgColor = RGB(255,255,255);
+ const CEColor defaultLineColor{ 0,0,0 };
+ const CEColor defaultBgColor{ 255,255,255 };
RecalcPageLayouts (pdc, pInfo);
int nSubLineOffset = GetSubLineIndex (nTopLine) - nTopSubLine;
if( nSubLineOffset < 0 )
- {
- rcLine.OffsetRect( 0, nSubLineOffset * nLineHeight );
- }
+ {
+ rcLine.OffsetRect( 0, nSubLineOffset * nLineHeight );
+ }
int nLineCount = GetLineCount();
int nCurrentLine;
// calculate number of sub lines
if (nLineCount <= 0)
- return 0;
+ return 0;
return CCrystalTextView::GetSubLineIndex( nLineCount - 1 ) + GetSubLines( nLineCount - 1 );
}
else
{
m_nLastLineIndexCalculatedSubLineIndex = 0;
- m_panSubLineIndexCache->SetAtGrow( 0, 0 );
+ m_panSubLineIndexCache->resize (1);
+ (*m_panSubLineIndexCache)[0] = 0;
}
// TODO: Rethink this, it is very time consuming
for( int i = m_nLastLineIndexCalculatedSubLineIndex; i < nLineIndex; i++ )
{
- m_panSubLineIndexCache->SetAtGrow( i, nSubLineCount);
+ if (m_panSubLineIndexCache->size () >= i)
+ m_panSubLineIndexCache->resize (i + 1);
+ (*m_panSubLineIndexCache)[i] = nSubLineCount;
nSubLineCount+= GetSubLines( i );
}
- m_panSubLineIndexCache->SetAtGrow( nLineIndex, nSubLineCount);
+ if (m_panSubLineIndexCache->size () >= nLineIndex)
+ m_panSubLineIndexCache->resize (nLineIndex + 1);
+ (*m_panSubLineIndexCache)[nLineIndex] = nSubLineCount;
m_nLastLineIndexCalculatedSubLineIndex = nLineIndex;
return nSubLineCount;
return GetLineLength(nLineIndex);
}
-LPCTSTR CCrystalTextView::
+const tchar_t* CCrystalTextView::
GetLineChars (int nLineIndex) const
{
if (m_pTextBuffer == nullptr)
pVertScrollBarCtrl->EnableScrollBar (GetScreenLines () >= GetLineCount ()?
ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
// Update vertical scrollbar only
- RecalcVertScrollBar ();
+ InvalidateVertScrollBar ();
}
/**
ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
CScrollBar *pHorzScrollBarCtrl = GetScrollBarCtrl (SB_HORZ);
if (pHorzScrollBarCtrl != nullptr)
- pHorzScrollBarCtrl->EnableScrollBar (GetScreenChars () >= GetMaxLineLength (m_nTopLine, GetScreenLines())?
- ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
+ pHorzScrollBarCtrl->EnableScrollBar(CoverLength(m_nTopLine, GetScreenLines(), GetScreenChars()) ?
+ ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
// Update scrollbars
- RecalcVertScrollBar ();
- RecalcHorzScrollBar ();
+ InvalidateVertScrollBar ();
+ InvalidateHorzScrollBar ();
}
void CCrystalTextView::
{
CRect rect;
GetClientRect (&rect);
- m_nScreenLines = rect.Height () / GetLineHeight ();
+ m_nScreenLines = (rect.Height () - GetTopMarginHeight ()) / GetLineHeight ();
}
return m_nScreenLines;
}
{
if (m_pColors != nullptr)
{
- nColorIndex &= ~COLORINDEX_APPLYFORCE;
+ nColorIndex &= ~COLORINDEX_MASK;
return m_pColors->GetBold(nColorIndex);
}
else
//BEGIN SW
// get char position of top left visible character with old cached word wrap
- CPoint topPos;
- SubLineCursorPosToTextPos( CPoint( 0, m_nTopSubLine ), topPos );
+ CEPoint topPos;
+ SubLineCursorPosToTextPos( CEPoint( 0, m_nTopSubLine ), topPos );
//END SW
//BEGIN SW
InvalidateScreenRect(false);
// compute new top sub line
- CPoint topSubLine;
+ CEPoint topSubLine;
CharPosToPoint( topPos.y, topPos.x, topSubLine );
m_nTopSubLine = GetSubLineIndex(topPos.y) + topSubLine.y;
UpdateCaret();
//END SW
- RecalcVertScrollBar (false, false);
- RecalcHorzScrollBar (false, false);
+ InvalidateVertScrollBar ();
+ InvalidateHorzScrollBar ();
}
void CCrystalTextView::
void CCrystalTextView::
RecalcVertScrollBar (bool bPositionOnly /*= false*/, bool bRedraw /*= true */)
{
- SCROLLINFO si = {0};
- si.cbSize = sizeof (si);
+ SCROLLINFO si{ sizeof (si) };
if (bPositionOnly)
{
si.fMask = SIF_POS;
CView::OnVScroll (nSBCode, nPos, pScrollBar);
// Note we cannot use nPos because of its 16-bit nature
- SCROLLINFO si = {0};
- si.cbSize = sizeof (si);
+ SCROLLINFO si{ sizeof(si) };
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
VERIFY (GetScrollInfo (SB_VERT, &si));
break;
}
ScrollToSubLine(nCurPos, bDisableSmooth);
+ UpdateCaret ();
}
void CCrystalTextView::
RecalcHorzScrollBar (bool bPositionOnly /*= false*/, bool bRedraw /*= true */)
{
- SCROLLINFO si = {0};
- si.cbSize = sizeof (si);
+ SCROLLINFO si{ sizeof(si) };
const int nScreenChars = GetScreenChars();
+ const TextLayoutMode layoutMode = GetTextLayoutMode ();
- if (m_bWordWrap)
+ if (layoutMode == TEXTLAYOUT_WORDWRAP)
{
- if (m_nOffsetChar > nScreenChars)
- {
- m_nOffsetChar = 0;
- UpdateCaret ();
- }
+ if (m_nOffsetChar > nScreenChars)
+ {
+ m_nOffsetChar = 0;
+ UpdateCaret ();
+ }
// Disable horizontal scroll bar
si.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE;
+ si.nPage = 1;
SetScrollInfo (SB_HORZ, &si);
return;
}
- const int nMaxLineLen = GetMaxLineLength (m_nTopLine, GetScreenLines());
+ int nMaxLineLen = GetMaxLineLength (m_nTopLine, GetScreenLines());
+ if (layoutMode == TEXTLAYOUT_TABLE_NOWORDWRAP || layoutMode == TEXTLAYOUT_TABLE_WORDWRAP)
+ {
+ auto widths = m_pTextBuffer->GetColumnWidths ();
+ nMaxLineLen = (std::max)(nMaxLineLen, std::accumulate (widths.begin (), widths.end (), 0));
+ }
if (bPositionOnly)
{
//CView::OnHScroll (nSBCode, nPos, pScrollBar);
// Again, we cannot use nPos because it's 16-bit
- SCROLLINFO si = {0};
- si.cbSize = sizeof (si);
+ SCROLLINFO si { sizeof(si) };
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
VERIFY (GetScrollInfo (SB_HORZ, &si));
CPoint pt;
::GetCursorPos (&pt);
ScreenToClient (&pt);
- if (pt.x < GetMarginWidth ())
+ if (pt.y < GetTopMarginHeight ())
+ {
+ if (m_pTextBuffer->GetTableEditing ())
+ {
+ const int nColumnResizing = ClientToColumnResizing (pt.x);
+ ::SetCursor (::LoadCursor (nullptr, nColumnResizing >= 0 ? IDC_SIZEWE : IDC_ARROW));
+ }
+ else
+ {
+ ::SetCursor (::LoadCursor (nullptr, IDC_ARROW));
+ }
+ }
+ else if (pt.x < GetMarginWidth ())
{
::SetCursor (::LoadCursor (AfxGetInstanceHandle (), MAKEINTRESOURCE (IDR_MARGIN_CURSOR)));
}
else
{
- CPoint ptText = ClientToText (pt);
+ CEPoint ptText = ClientToText (pt);
PrepareSelBounds ();
if (IsInsideSelBlock (ptText))
{
return CView::OnSetCursor (pWnd, nHitTest, message);
}
+int CCrystalTextView::
+ClientToIdealTextPos (int x)
+{
+ int nPos;
+ if (x > GetMarginWidth ())
+ nPos = m_nOffsetChar + (x - GetMarginWidth ()) / GetCharWidth ();
+ else
+ nPos = 0;
+ return nPos;
+}
+
/**
* @brief Converts client area point to text position.
* @param [in] point Client area point.
* @return Text position (line index, char index in line).
* @note For gray selection area char index is 0.
*/
-CPoint CCrystalTextView::
+CEPoint CCrystalTextView::
ClientToText (const CPoint & point)
{
//BEGIN SW
const int nSubLineCount = GetSubLineCount();
const int nLineCount = GetLineCount();
- CPoint pt;
- pt.y = m_nTopSubLine + point.y / GetLineHeight();
+ CEPoint pt;
+ pt.y = m_nTopSubLine + (point.y - GetTopMarginHeight ()) / GetLineHeight();
if (pt.y >= nSubLineCount)
pt.y = nSubLineCount - 1;
if (pt.y < 0)
int nLine;
int nSubLineOffset;
- int nOffsetChar = m_nOffsetChar;
GetLineBySubLine( pt.y, nLine, nSubLineOffset );
pt.y = nLine;
- LPCTSTR pszLine = nullptr;
+ const tchar_t* pszLine = nullptr;
int nLength = 0;
vector<int> anBreaks(1);
int nBreaks = 0;
nLength = GetLineLength( pt.y );
anBreaks.resize(nLength + 1);
pszLine = GetLineChars(pt.y);
- WrapLineCached( pt.y, GetScreenChars(), &anBreaks[0], nBreaks );
+ WrapLineCached( pt.y, GetScreenChars(), &anBreaks, nBreaks );
- if (nSubLineOffset > 0)
- {
- if (nSubLineOffset < nBreaks)
- nOffsetChar = anBreaks[nSubLineOffset - 1];
- else if (nBreaks > 0)
- nOffsetChar = anBreaks[nBreaks - 1];
- }
- if (nBreaks > nSubLineOffset)
+ if (nBreaks > nSubLineOffset && GetTextLayoutMode () == TEXTLAYOUT_WORDWRAP)
nLength = anBreaks[nSubLineOffset] - 1;
}
- int nPos = 0;
// Char index for margin area is 0
- if (point.x > GetMarginWidth())
- nPos = nOffsetChar + (point.x - GetMarginWidth()) / GetCharWidth();
- if (nPos < 0)
- nPos = 0;
-
+ int nPos = ClientToIdealTextPos (point.x);
int nIndex = 0;
int nCurPos = 0;
int n = 0;
const int nTabSize = GetTabSize();
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszLine, nLength);
- while (nIndex < nLength)
+ switch (GetTextLayoutMode ())
{
- if (nBreaks && nIndex == anBreaks[i])
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
{
- n = nIndex;
- i++;
+ int nColumnCount = m_pTextBuffer->GetColumnCount (nLine);
+ int nColumnTotalWidth = 0;
+ int nColumn = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ while (nIndex < nLength)
+ {
+ int nOffset;
+ if (!bInQuote && pszLine[nIndex] == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nOffset = nColumnTotalWidth - nCurPos;
+ }
+ else
+ {
+ if (pszLine[nIndex] == quote)
+ bInQuote = !bInQuote;
+ if (pszLine[nIndex] == '\t')
+ nOffset = 1;
+ else
+ nOffset = GetCharCellCountFromChar (pszLine + nIndex);
+ if (nColumn < nColumnCount && nCurPos + nOffset > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nOffset = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn) - nCurPos;
+ }
+ n += nOffset;
+ nCurPos += nOffset;
+
+ if (n > nPos && i == nSubLineOffset)
+ break;
+
+ nIndex = pIterChar->next ();
+ }
}
+ break;
+ case TEXTLAYOUT_TABLE_WORDWRAP:
+ {
+ int j = 0;
+ int nColumn = 0;
+ int nColumnSumWidth = 0;
+ int nColumnCurPoint = INT_MAX;
+ int nPrevIndex = 0;
+ if (nPos < m_pTextBuffer->GetColumnWidth (0))
+ nColumnCurPoint = 0;
+ while (nIndex < nLength)
+ {
+ if (i < static_cast<int>(anBreaks.size()) && nIndex == abs(anBreaks[i]))
+ {
+ if (anBreaks[i++] < 0)
+ {
+ j = 0;
+ nColumnSumWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ n = nColumnSumWidth;
+ if (nColumnSumWidth <= nPos && nPos < nColumnSumWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nColumnCurPoint = nColumn;
+ }
+ else
+ {
+ n = nColumnSumWidth;
+ j++;
+ }
+ }
+
+ int nOffset;
+ if (pszLine[nIndex] == '\t')
+ nOffset = 1;
+ else
+ nOffset = GetCharCellCountFromChar(pszLine + nIndex);
+ n += nOffset;
+ nCurPos += nOffset;
- int nOffset;
- if (pszLine[nIndex] == '\t')
- nOffset = nTabSize - nCurPos % nTabSize;
- else
- nOffset = GetCharCellCountFromChar(pszLine + nIndex);
- n += nOffset;
- nCurPos += nOffset;
+ if (n > nPos && j == nSubLineOffset)
+ break;
+ else if( nColumnCurPoint < nColumn && nPrevIndex != 0)
+ {
+ nIndex = nPrevIndex;
+ break;
+ }
+ else if ( j == nSubLineOffset)
+ nPrevIndex = nIndex;
- if (n > nPos && i == nSubLineOffset)
+ nIndex = pIterChar->next();
+ }
+ if (nIndex == nLength && j != nSubLineOffset)
+ nIndex = nPrevIndex;
+ }
break;
+ default:
+ {
+ while (nIndex < nLength)
+ {
+ if (nBreaks && i < static_cast<int>(anBreaks.size ()) && nIndex == anBreaks[i])
+ {
+ n = 0;
+ i++;
+ }
+
+ int nOffset;
+ if (pszLine[nIndex] == '\t')
+ nOffset = nTabSize - nCurPos % nTabSize;
+ else
+ nOffset = GetCharCellCountFromChar(pszLine + nIndex);
+ n += nOffset;
+ nCurPos += nOffset;
- nIndex = pIterChar->next();
+ if (n > nPos && i == nSubLineOffset)
+ break;
+
+ nIndex = pIterChar->next();
+ }
+ }
+ break;
}
ASSERT(nIndex >= 0 && nIndex <= nLength);
return pt;
}
+int CCrystalTextView::
+ClientToColumn (int x)
+{
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ int nCharWidth = GetCharWidth ();
+ int nMarginWidth = GetMarginWidth ();
+ for (int nColumn = 0, columnleft = nMarginWidth - m_nOffsetChar * nCharWidth;
+ columnleft < rcClient.Width ();
+ columnleft += m_pTextBuffer->GetColumnWidth (nColumn++) * nCharWidth)
+ {
+ if (columnleft <= x && x < columnleft + m_pTextBuffer->GetColumnWidth (nColumn) * nCharWidth)
+ return nColumn;
+ }
+ return -1;
+}
+
+int CCrystalTextView::
+ClientToColumnResizing (int x)
+{
+ const int nColumn = ClientToColumn (x);
+ const int nColumnL = ClientToColumn (x - 4);
+ const int nColumnR = ClientToColumn (x + 4);
+ if (nColumn != nColumnL || nColumn != nColumnR)
+ {
+ return (nColumn != nColumnL) ? nColumnL : nColumn;
+ }
+ return -1;
+}
#ifdef _DEBUG
void CCrystalTextView::
-AssertValidTextPos (const CPoint & point)
+AssertValidTextPos (const CEPoint & point)
{
if (GetLineCount () > 0)
{
#endif
bool CCrystalTextView::
-IsValidTextPos (const CPoint &point)
+IsValidTextPos (const CEPoint &point)
{
return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 &&
point.y >= 0 && point.y < GetLineCount () && point.x >= 0 && point.x <= GetLineLength (point.y);
}
bool CCrystalTextView::
-IsValidTextPosX (const CPoint &point)
+IsValidTextPosX (const CEPoint &point)
{
return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 &&
point.y >= 0 && point.y < GetLineCount () && point.x >= 0 && point.x <= GetLineLength (point.y);
}
bool CCrystalTextView::
-IsValidTextPosY (const CPoint &point)
+IsValidTextPosY (const CEPoint &point)
{
return GetLineCount () > 0 && m_nTopLine >= 0 && m_nOffsetChar >= 0 &&
point.y >= 0 && point.y < GetLineCount ();
}
CPoint CCrystalTextView::
-TextToClient (const CPoint & point)
+TextToClient (const CEPoint & point)
{
ASSERT_VALIDTEXTPOS (point);
- LPCTSTR pszLine = GetLineChars (point.y);
+ const tchar_t* pszLine = GetLineChars (point.y);
+ int nColumnIndex = 0;
CPoint pt;
//BEGIN SW
- CPoint charPoint;
- int nSubLineStart = CharPosToPoint( point.y, point.x, charPoint );
+ CEPoint charPoint;
+ int nSubLineStart = CharPosToPoint( point.y, point.x, charPoint, &nColumnIndex );
charPoint.y+= GetSubLineIndex( point.y );
// compute y-position
- pt.y = (charPoint.y - m_nTopSubLine) * GetLineHeight();
+ pt.y = (charPoint.y - m_nTopSubLine) * GetLineHeight() + GetTopMarginHeight ();
// if pt.x is null, we know the result
- if( charPoint.x == 0 )
+ if( charPoint.x == 0 && nColumnIndex == 0)
{
pt.x = GetMarginWidth();
return pt;
pt.x = 0;
int nTabSize = GetTabSize ();
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszLine, point.x);
- for (int nIndex = 0; nIndex < point.x; nIndex = pIterChar->next())
+ switch (GetTextLayoutMode ())
{
- //BEGIN SW
- if( nIndex == nSubLineStart )
- nPreOffset = pt.x;
- //END SW
- if (pszLine[nIndex] == _T ('\t'))
- pt.x += (nTabSize - pt.x % nTabSize);
- else
- pt.x += GetCharCellCountFromChar(pszLine + nIndex);
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
+ {
+ int nColumnCount = m_pTextBuffer->GetColumnCount (point.y);
+ int nColumnTotalWidth = 0;
+ int nColumn = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ for (int nIndex = 0; nIndex < point.x; nIndex = pIterChar->next())
+ {
+ if (!bInQuote && pszLine[nIndex] == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ pt.x = nColumnTotalWidth;
+ }
+ else
+ {
+ if (pszLine[nIndex] == quote)
+ bInQuote = !bInQuote;
+ if (pszLine[nIndex] == _T ('\t'))
+ pt.x ++;
+ else
+ pt.x += GetCharCellCountFromChar(pszLine + nIndex);
+ if (nColumn < nColumnCount && pt.x > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ pt.x = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn);
+ }
+ }
+ pt.x = (pt.x - m_nOffsetChar) * GetCharWidth () + GetMarginWidth ();
+ return pt;
+ }
+ break;
+ case TEXTLAYOUT_TABLE_WORDWRAP:
+ {
+ pt.x = 0;
+ for (int i = 0; i < nColumnIndex; ++i)
+ pt.x += m_pTextBuffer->GetColumnWidth (i);
+ for (int nIndex = 0; nIndex < point.x; nIndex = pIterChar->next())
+ {
+ if( nIndex >= nSubLineStart )
+ {
+ if (pszLine[nIndex] == '\t')
+ pt.x ++;
+ else
+ pt.x += GetCharCellCountFromChar (pszLine + nIndex);
+ }
+ }
+ pt.x = (pt.x - m_nOffsetChar) * GetCharWidth () + GetMarginWidth ();
+ return pt;
+ }
+ break;
+ default:
+ {
+ for (int nIndex = 0; nIndex < point.x; nIndex = pIterChar->next())
+ {
+ //BEGIN SW
+ if( nIndex == nSubLineStart )
+ nPreOffset = pt.x;
+ //END SW
+ if (pszLine[nIndex] == _T ('\t'))
+ pt.x += (nTabSize - pt.x % nTabSize);
+ else
+ pt.x += GetCharCellCountFromChar(pszLine + nIndex);
+ }
+ //BEGIN SW
+ pt.x-= nPreOffset;
+ //END SW
+
+ pt.x = (pt.x - m_nOffsetChar) * GetCharWidth () + GetMarginWidth ();
+ return pt;
+ }
}
- //BEGIN SW
- pt.x-= nPreOffset;
- //END SW
+}
- pt.x = (pt.x - m_nOffsetChar) * GetCharWidth () + GetMarginWidth ();
- return pt;
+int CCrystalTextView::
+ColumnToClient (int nColumn)
+{
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ int nCharWidth = GetCharWidth ();
+ int columnleft = GetMarginWidth () - m_nOffsetChar * nCharWidth;
+ for (int nColumn2 = 0; nColumn2 != nColumn && columnleft < rcClient.Width ();
+ columnleft += m_pTextBuffer->GetColumnWidth (nColumn2++) * nCharWidth)
+ ;
+ return columnleft;
}
void CCrystalTextView::
InvalidateLines (int nLine1, int nLine2, bool bInvalidateMargin /*= false*/ )
{
bInvalidateMargin = true;
+ const int nTopMarginHeight = GetTopMarginHeight ();
const int nLineHeight = GetLineHeight();
if (nLine2 == -1)
{
if (!bInvalidateMargin)
rcInvalid.left += GetMarginWidth ();
//BEGIN SW
- rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * nLineHeight;
+ rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * nLineHeight + nTopMarginHeight;
/*ORIGINAL
rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
*/
if (!bInvalidateMargin)
rcInvalid.left += GetMarginWidth ();
//BEGIN SW
- rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * nLineHeight;
- rcInvalid.bottom = (GetSubLineIndex( nLine2 ) - m_nTopSubLine + GetSubLines( nLine2 )) * nLineHeight;
+ rcInvalid.top = (GetSubLineIndex( nLine1 ) - m_nTopSubLine) * nLineHeight + nTopMarginHeight;
+ rcInvalid.bottom = (GetSubLineIndex( nLine2 ) - m_nTopSubLine + GetSubLines( nLine2 )) * nLineHeight + nTopMarginHeight;
/*ORIGINAL
rcInvalid.top = (nLine1 - m_nTopLine) * GetLineHeight();
rcInvalid.bottom = (nLine2 - m_nTopLine + 1) * GetLineHeight();
}
void CCrystalTextView::
-SetSelection (const CPoint & ptStart, const CPoint & ptEnd, bool bUpdateView /* = true */)
+SetSelection (const CEPoint & ptStart, const CEPoint & ptEnd, bool bUpdateView /* = true */)
{
ASSERT_VALIDTEXTPOS (ptStart);
ASSERT_VALIDTEXTPOS (ptEnd);
- if (m_ptSelStart == ptStart && !m_bColumnSelection)
+ if (m_ptSelStart == ptStart && !m_bRectangularSelection)
{
if (m_ptSelEnd != ptEnd)
InvalidateLines (ptEnd.y, m_ptSelEnd.y);
UpdateCaret ();
}
-DWORD CCrystalTextView::
-ParseLine (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
+unsigned CCrystalTextView::
+ParseLine (unsigned dwCookie, const tchar_t *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
{
return m_CurSourceDef->ParseLineX (dwCookie, pszChars, nLength, pBuf, nActualItems);
}
{
const int nLength = GetLineLength (nLineIndex);
ASSERT (nCharIndex >= 0 && nCharIndex <= nLength);
- LPCTSTR pszChars = GetLineChars (nLineIndex);
+ const tchar_t* pszChars = GetLineChars (nLineIndex);
int nOffset = 0;
const int nTabSize = GetTabSize ();
- //BEGIN SW
- vector<int> anBreaks(nLength + 1);
- int nBreaks = 0;
-
- /*if( nLength > GetScreenChars() )*/
- WrapLineCached( nLineIndex, GetScreenChars(), &anBreaks[0], nBreaks );
-
- int nPreOffset = 0;
- int nPreBreak = 0;
-
- if( nBreaks > 0 )
- {
- int J=0;
- for( J = nBreaks - 1; J >= 0 && nCharIndex < anBreaks[J]; J-- );
- nPreBreak = (J >= 0) ? anBreaks[J] : 0;
- }
- //END SW
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszChars, nCharIndex);
int I=0;
- for (I = 0; I < nCharIndex; I = pIterChar->next())
+ switch (GetTextLayoutMode ())
{
- //BEGIN SW
- if( nPreBreak == I && nBreaks )
- nPreOffset = nOffset;
- //END SW
- if (pszChars[I] == _T ('\t'))
- nOffset += (nTabSize - nOffset % nTabSize);
- else
- nOffset += GetCharCellCountFromChar(pszChars + I);
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
+ {
+ int nColumnCount = m_pTextBuffer->GetColumnCount (nLineIndex);
+ int nColumnTotalWidth = 0;
+ int nColumn = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ for (I = 0; I < nCharIndex; I = pIterChar->next())
+ {
+ if (!bInQuote && pszChars[I] == sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nOffset = nColumnTotalWidth;
+ }
+ else
+ {
+ if (pszChars[I] == quote)
+ bInQuote = !bInQuote;
+ else if (pszChars[I] == '\t')
+ nOffset ++;
+ else
+ nOffset += GetCharCellCountFromChar (pszChars + I);
+ if (nColumn < nColumnCount && nOffset > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nOffset = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn);
+ }
+ }
+ return nOffset;
+ }
+ break;
+ case TEXTLAYOUT_TABLE_WORDWRAP:
+ {
+ int nColumnIndex = 0;
+ CEPoint charPoint;
+ int nSubLineStart = CharPosToPoint( nLineIndex, nCharIndex, charPoint, &nColumnIndex );
+ for (int i = 0; i < nColumnIndex; ++i)
+ nOffset += m_pTextBuffer->GetColumnWidth (i);
+ for (int nIndex = 0; nIndex < nCharIndex; nIndex = pIterChar->next())
+ {
+ if( nIndex >= nSubLineStart )
+ {
+ if (pszChars[nIndex] == '\t')
+ nOffset ++;
+ else
+ nOffset += GetCharCellCountFromChar (pszChars + nIndex);
+ }
+ }
+ return nOffset;
+ }
+ break;
+ default:
+ {
+ //BEGIN SW
+ vector<int> anBreaks(nLength + 1);
+ int nBreaks = 0;
+
+ /*if( nLength > GetScreenChars() )*/
+ WrapLineCached( nLineIndex, GetScreenChars(), &anBreaks, nBreaks );
+
+ int nPreOffset = 0;
+ int nPreBreak = 0;
+
+ if( nBreaks > 0 )
+ {
+ int J=0;
+ for( J = nBreaks - 1; J >= 0 && nCharIndex < anBreaks[J]; J-- );
+ nPreBreak = (J >= 0) ? anBreaks[J] : 0;
+ }
+ //END SW
+ for (I = 0; I < nCharIndex; I = pIterChar->next())
+ {
+ //BEGIN SW
+ if( nPreBreak == I && nBreaks )
+ nPreOffset = nOffset;
+ //END SW
+ if (pszChars[I] == _T ('\t'))
+ nOffset += (nTabSize - nOffset % nTabSize);
+ else
+ nOffset += GetCharCellCountFromChar(pszChars + I);
+ }
+ if (bAccumulate)
+ return nOffset;
+ //BEGIN SW
+ if( nPreBreak == I && nBreaks > 0)
+ return 0;
+ else
+ return nOffset - nPreOffset;
+ /*ORIGINAL
+ return nOffset;
+ *///END SW
+ }
}
- if (bAccumulate)
- return nOffset;
- //BEGIN SW
- if( nPreBreak == I && nBreaks > 0)
- return 0;
- else
- return nOffset - nPreOffset;
- /*ORIGINAL
- return nOffset;
- *///END SW
}
int CCrystalTextView::
return 0;
int nLength = GetLineLength (nLineIndex);
- LPCTSTR pszChars = GetLineChars (nLineIndex);
+ const tchar_t* pszChars = GetLineChars (nLineIndex);
int nCurrentOffset = 0;
int nTabSize = GetTabSize ();
auto pIterChar = ICUBreakIterator::getCharacterBreakIterator(pszChars, nLength);
- for (int I = 0; I < nLength; I = pIterChar->next())
+ switch (GetTextLayoutMode ())
{
- if (pszChars[I] == _T ('\t'))
- nCurrentOffset += (nTabSize - nCurrentOffset % nTabSize);
- else
+ case TEXTLAYOUT_TABLE_NOWORDWRAP:
+ case TEXTLAYOUT_TABLE_WORDWRAP:
{
- nCurrentOffset += GetCharCellCountFromChar(pszChars + I);
+ int nColumnCount = m_pTextBuffer->GetColumnCount (nLineIndex);
+ int nColumnTotalWidth = 0;
+ bool bInQuote = false;
+ const int sep = m_pTextBuffer->GetFieldDelimiter ();
+ const int quote = m_pTextBuffer->GetFieldEnclosure ();
+ for (int I = 0, nColumn = 0; I < nLength; I = pIterChar->next())
+ {
+ if (!bInQuote && pszChars[I] ==sep)
+ {
+ nColumnTotalWidth += m_pTextBuffer->GetColumnWidth (nColumn++);
+ nCurrentOffset = nColumnTotalWidth;
+ }
+ else
+ {
+ if (pszChars[I] == quote)
+ bInQuote = !bInQuote;
+ if (pszChars[I] == '\t')
+ nCurrentOffset ++;
+ else
+ nCurrentOffset += GetCharCellCountFromChar (pszChars + I);
+ if (nColumn < nColumnCount && nCurrentOffset > nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn))
+ nCurrentOffset = nColumnTotalWidth + m_pTextBuffer->GetColumnWidth (nColumn);
+ }
+ if (nCurrentOffset >= nOffset)
+ {
+ if (nOffset <= nCurrentOffset - nTabSize / 2)
+ return I;
+ return pIterChar->next ();
+ }
+ }
}
- if (nCurrentOffset >= nOffset)
+ break;
+ default:
{
- if (nOffset <= nCurrentOffset - nTabSize / 2)
- return I;
- return pIterChar->next();
+ for (int I = 0; I < nLength; I = pIterChar->next())
+ {
+ if (pszChars[I] == _T ('\t'))
+ nCurrentOffset += (nTabSize - nCurrentOffset % nTabSize);
+ else
+ {
+ nCurrentOffset += GetCharCellCountFromChar(pszChars + I);
+ }
+ if (nCurrentOffset >= nOffset)
+ {
+ if (nOffset <= nCurrentOffset - nTabSize / 2)
+ return I;
+ return pIterChar->next();
+ }
+ }
}
}
return nLength;
}
void CCrystalTextView::
-EnsureVisible (CPoint pt)
+EnsureVisible (CEPoint pt)
{
EnsureVisible(pt, pt);
}
}
void CCrystalTextView::
-GetText (const CPoint & ptStart, const CPoint & ptEnd, CString & text, bool bExcludeInvisibleLines /*= true*/)
+GetText (const CEPoint & ptStart, const CEPoint & ptEnd, CString & text, bool bExcludeInvisibleLines /*= true*/)
{
if (m_pTextBuffer != nullptr)
- m_pTextBuffer->GetText (ptStart.y, ptStart.x, ptEnd.y, ptEnd.x, text);
+ {
+ std::basic_string<tchar_t> sText;
+ m_pTextBuffer->GetText (ptStart.y, ptStart.x, ptEnd.y, ptEnd.x, sText);
+ text.SetString(sText.c_str (), static_cast<int> (sText.length ())); // TODO: Use std::basic_string<tchar_t> instead of CString
+ }
else
text = _T ("");
}
PrepareSelBounds ();
- CString sEol = m_pTextBuffer->GetStringEol (CRLF_STYLE_DOS);
+ CString sEol = m_pTextBuffer->GetStringEol (CRLFSTYLE::DOS);
int nBufSize = 1;
for (int L = m_ptDrawSelStart.y; L <= m_ptDrawSelEnd.y; L++)
- nBufSize += GetLineLength (L) + sEol.GetLength ();
- LPTSTR pszBuf = text.GetBuffer (nBufSize);
+ nBufSize += GetLineLength (L) + sEol.GetLength ();
+ tchar_t* pszBuf = text.GetBuffer (nBufSize);
for (int I = m_ptDrawSelStart.y; I <= m_ptDrawSelEnd.y; I++)
{
continue;
int nSelLeft, nSelRight;
GetColumnSelection (I, nSelLeft, nSelRight);
- memcpy (pszBuf, GetLineChars (I) + nSelLeft, sizeof (TCHAR) * (nSelRight - nSelLeft));
+ memcpy (pszBuf, GetLineChars (I) + nSelLeft, sizeof (tchar_t) * (nSelRight - nSelLeft));
pszBuf += (nSelRight - nSelLeft);
- memcpy (pszBuf, sEol, sizeof (TCHAR) * sEol.GetLength ());
+ memcpy (pszBuf, sEol, sizeof (tchar_t) * sEol.GetLength ());
pszBuf += sEol.GetLength ();
}
pszBuf[0] = 0;
void CCrystalTextView::
UpdateView (CCrystalTextView * pSource, CUpdateContext * pContext,
- DWORD dwFlags, int nLineIndex /*= -1*/ )
+ updateview_flags_t dwFlags, int nLineIndex /*= -1*/ )
{
// SetTextType (GetExt (GetDocument ()->GetPathName ()));
if (dwFlags & UPDATE_RESET)
{
ResetView ();
- RecalcVertScrollBar ();
- RecalcHorzScrollBar ();
+ InvalidateVertScrollBar ();
+ InvalidateHorzScrollBar ();
return;
}
ASSERT (cookiesSize == nLineCount);
// must be reinitialized to invalid value (DWORD) - 1
for (int i = nLineIndex; i < cookiesSize; ++i)
- (*m_ParseCookies)[i] = static_cast<DWORD>(-1);
+ (*m_ParseCookies)[i] = static_cast<uint32_t>(-1);
}
// This line'th actual length must be recalculated
if (m_pnActualLineLength->size())
ASSERT (m_pnActualLineLength->size() == static_cast<size_t>(nLineCount));
// must be initialized to invalid code -1
(*m_pnActualLineLength)[nLineIndex] = -1;
- //BEGIN SW
- InvalidateLineCache( nLineIndex, nLineIndex );
- //END SW
+ //BEGIN SW
+ InvalidateLineCache( nLineIndex, nLineIndex );
+ //END SW
}
// Repaint the lines
InvalidateLines (nLineIndex, -1, true);
arrSize = nLineCount;
// must be initialized to invalid value (DWORD) - 1
for (size_t i = oldsize; i < arrSize; ++i)
- (*m_ParseCookies)[i] = static_cast<DWORD>(-1);
+ (*m_ParseCookies)[i] = static_cast<uint32_t>(-1);
}
for (size_t i = nLineIndex; i < arrSize; ++i)
- (*m_ParseCookies)[i] = static_cast<DWORD>(-1);
+ (*m_ParseCookies)[i] = static_cast<uint32_t>(-1);
}
// Recalculate actual length for all lines below this
if (m_pnActualLineLength->size())
{
- size_t arrsize = m_pnActualLineLength->size();
- if (arrsize != static_cast<size_t>(nLineCount))
+ size_t arrsize = m_pnActualLineLength->size();
+ if (arrsize != static_cast<size_t>(nLineCount))
{
// Reallocate actual length array
size_t oldsize = arrsize;
for (size_t i = nLineIndex; i < arrsize; ++i)
(*m_pnActualLineLength)[i] = -1;
}
- //BEGIN SW
- InvalidateLineCache( nLineIndex, -1 );
- //END SW
+ //BEGIN SW
+ InvalidateLineCache( nLineIndex, -1 );
+ //END SW
// Repaint the lines
InvalidateLines (nLineIndex, -1, true);
}
ASSERT_VALIDTEXTPOS (m_ptDraggedTextBegin);
ASSERT_VALIDTEXTPOS (m_ptDraggedTextEnd);
}
- CPoint ptTopLine (0, m_nTopLine);
+ CEPoint ptTopLine (0, m_nTopLine);
pContext->RecalcPoint (ptTopLine);
ASSERT_VALIDTEXTPOS (ptTopLine);
m_nTopLine = ptTopLine.y;
if ((dwFlags & UPDATE_VERTRANGE) != 0)
{
if (!m_bVertScrollBarLocked)
- RecalcVertScrollBar ();
+ InvalidateVertScrollBar ();
}
// Recalculate horizontal scrollbar, if needed
if ((dwFlags & UPDATE_HORZRANGE) != 0)
{
if (!m_bHorzScrollBarLocked)
- RecalcHorzScrollBar ();
+ InvalidateHorzScrollBar ();
}
}
OnCreate (LPCREATESTRUCT lpCreateStruct)
{
m_lfBaseFont = {};
- _tcscpy_s (m_lfBaseFont.lfFaceName, _T ("FixedSys"));
+ tc::tcslcpy (m_lfBaseFont.lfFaceName, _T ("FixedSys"));
m_lfBaseFont.lfHeight = 0;
m_lfBaseFont.lfWeight = FW_NORMAL;
m_lfBaseFont.lfItalic = false;
}
void CCrystalTextView::
-SetAnchor (const CPoint & ptNewAnchor)
+SetAnchor (const CEPoint & ptNewAnchor)
{
ASSERT_VALIDTEXTPOS (ptNewAnchor);
m_ptAnchor = ptNewAnchor;
}
void CCrystalTextView::
-OnEditOperation (int nAction, LPCTSTR pszText, size_t cchText)
+OnEditOperation (int nAction, const tchar_t* pszText, size_t cchText)
{
}
return CView::PreTranslateMessage (pMsg);
}
-CPoint CCrystalTextView::
-GetCursorPos () const
-{
- return m_ptCursorPos;
-}
-
void CCrystalTextView::
-SetCursorPos (const CPoint & ptCursorPos)
+SetCursorPos (const CEPoint & ptCursorPos)
{
ASSERT_VALIDTEXTPOS (ptCursorPos);
m_ptCursorPos = ptCursorPos;
}
void CCrystalTextView::
+SetTopMargin (bool bTopMargin)
+{
+ if (m_bTopMargin != bTopMargin)
+ {
+ m_bTopMargin = bTopMargin;
+ if (::IsWindow (m_hWnd))
+ {
+ Invalidate ();
+ m_nScreenLines = -1;
+ InvalidateVertScrollBar ();
+ UpdateCaret ();
+ }
+ }
+}
+
+void CCrystalTextView::
SetSelectionMargin (bool bSelMargin)
{
if (m_bSelMargin != bSelMargin)
}
void CCrystalTextView::
-GetFont (LOGFONT & lf)
-{
- lf = m_lfBaseFont;
-}
-
-void CCrystalTextView::
SetFont (const LOGFONT & lf)
{
m_lfBaseFont = lf;
{
InvalidateScreenRect();
m_nTopSubLine = GetSubLineIndex(m_nTopLine);
- RecalcVertScrollBar ();
- RecalcHorzScrollBar ();
+ InvalidateVertScrollBar ();
+ InvalidateHorzScrollBar ();
UpdateCaret ();
}
#ifdef _UNICODE
{
if (m_pTextBuffer != nullptr)
{
- std::basic_string<TCHAR> eol;
+ std::basic_string<tchar_t> eol;
CRLFSTYLE crlfMode = m_pTextBuffer->GetCRLFMode ();
switch (crlfMode)
{
- case CRLF_STYLE_DOS:
+ case CRLFSTYLE::DOS:
eol = LoadResString (IDS_EOL_DOS);
pCmdUI->SetText (eol.c_str());
pCmdUI->Enable (true);
break;
- case CRLF_STYLE_UNIX:
+ case CRLFSTYLE::UNIX:
eol = LoadResString (IDS_EOL_UNIX);
pCmdUI->SetText (eol.c_str());
pCmdUI->Enable (true);
break;
- case CRLF_STYLE_MAC:
+ case CRLFSTYLE::MAC:
eol = LoadResString (IDS_EOL_MAC);
pCmdUI->SetText (eol.c_str());
pCmdUI->Enable (true);
break;
- case CRLF_STYLE_MIXED:
+ case CRLFSTYLE::MIXED:
eol = LoadResString (IDS_EOL_MIXED);
pCmdUI->SetText (eol.c_str());
pCmdUI->Enable (true);
ASSERT (nBookmarkID >= 0 && nBookmarkID <= 9);
if (m_pTextBuffer != nullptr)
{
- DWORD dwFlags = GetLineFlags (m_ptCursorPos.y);
- DWORD dwMask = LF_BOOKMARK (nBookmarkID);
+ lineflags_t dwFlags = GetLineFlags (m_ptCursorPos.y);
+ lineflags_t dwMask = LF_BOOKMARK (nBookmarkID);
m_pTextBuffer->SetLineFlag (m_ptCursorPos.y, dwMask, (dwFlags & dwMask) == 0);
}
}
int nLine = m_pTextBuffer->GetLineWithFlag (LF_BOOKMARK (nBookmarkID));
if (nLine >= 0)
{
- CPoint pt (0, nLine);
+ CEPoint pt (0, nLine);
ASSERT_VALIDTEXTPOS (pt);
SetCursorPos (pt);
SetSelection (pt, pt);
UpdateCaret ();
}
-DROPEFFECT CCrystalTextView::
-GetDropEffect ()
-{
- return DROPEFFECT_COPY;
-}
-
void CCrystalTextView::
OnDropSource (DROPEFFECT de)
{
CString text;
GetText (m_ptDrawSelStart, m_ptDrawSelEnd, text);
int cchText = text.GetLength();
- SIZE_T cbData = (cchText + 1) * sizeof(TCHAR);
+ SIZE_T cbData = (cchText + 1) * sizeof(tchar_t);
HGLOBAL hData =::GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, cbData);
if (hData == nullptr)
return nullptr;
- LPTSTR pszData = (LPTSTR)::GlobalLock (hData);
+ tchar_t* pszData = (tchar_t*)::GlobalLock (hData);
if (pszData == nullptr)
{
::GlobalFree(hData);
return hData;
}
-static const TCHAR *memstr(const TCHAR *str1, size_t str1len, const TCHAR *str2, size_t str2len)
-{
- for (const TCHAR *p = str1; p < str1 + str1len - str2len; ++p)
- {
- if (*p == *str2)
- {
- if (memcmp(p, str2, str2len * sizeof(TCHAR)) == 0)
- return p;
- }
- }
- return nullptr;
-}
-
-static const TCHAR *memistr(const TCHAR *str1, size_t str1len, const TCHAR *str2, size_t str2len)
-{
- for (const TCHAR *p = str1; p < str1 + str1len - str2len; ++p)
- {
- if (toupper(*p) == toupper(*str2))
- {
- size_t i;
- for (i = 0; i < str2len; ++i)
- {
- if (toupper(p[i]) != toupper(str2[i]))
- break;
- }
- if (i == str2len)
- return p;
- }
- }
- return nullptr;
-}
-
-static ptrdiff_t
-FindStringHelper (LPCTSTR pszLineBegin, size_t nLineLength, LPCTSTR pszFindWhere, LPCTSTR pszFindWhat, DWORD dwFlags, int &nLen, RxNode *&rxnode, RxMatchRes *rxmatch)
-{
- if (dwFlags & FIND_REGEXP)
- {
- ptrdiff_t pos = -1;
-
- if (rxnode)
- RxFree (rxnode);
- rxnode = nullptr;
- if (pszFindWhat[0] == '^' && pszLineBegin != pszFindWhere)
- return pos;
- rxnode = RxCompile (pszFindWhat, (dwFlags & FIND_MATCH_CASE) != 0 ? RX_CASE : 0);
- if (rxnode && RxExec (rxnode, pszFindWhere, nLineLength - (pszFindWhere - pszLineBegin), pszFindWhere, rxmatch))
- {
- pos = rxmatch->Open[0];
- ASSERT((rxmatch->Close[0] - rxmatch->Open[0]) < INT_MAX);
- nLen = static_cast<int>(rxmatch->Close[0] - rxmatch->Open[0]);
- }
- return pos;
- }
- else
- {
- ASSERT (pszFindWhere != nullptr);
- ASSERT (pszFindWhat != nullptr);
- int nCur = 0;
- int nLength = (int) _tcslen (pszFindWhat);
- LPCTSTR pszFindWhereOrig = pszFindWhere;
- nLen = nLength;
- for (;;)
- {
- LPCTSTR pszPos;
- if (dwFlags & FIND_MATCH_CASE)
- pszPos = memstr(pszFindWhere, nLineLength - (pszFindWhere - pszLineBegin), pszFindWhat, nLength);
- else
- pszPos = memistr(pszFindWhere, nLineLength - (pszFindWhere - pszLineBegin), pszFindWhat, nLength);
- if (pszPos == nullptr)
- return -1;
- if ((dwFlags & FIND_WHOLE_WORD) == 0)
- return nCur + (int) (pszPos - pszFindWhere);
- if (pszPos > pszFindWhereOrig && xisalnum (pszPos[-1]))
- {
- nCur += (int) (pszPos - pszFindWhere + 1);
- pszFindWhere = pszPos + 1;
- continue;
- }
- if (xisalnum (pszPos[nLength]))
- {
- nCur += (int) (pszPos - pszFindWhere + 1);
- pszFindWhere = pszPos + 1;
- continue;
- }
- return nCur + (int) (pszPos - pszFindWhere);
- }
- }
-//~ ASSERT (false); // Unreachable
-}
-
/**
* @brief Select text in editor.
* @param [in] ptStartPos Star position for highlight.
* selection, if false cursor is positioned to right-end.
*/
bool CCrystalTextView::
-HighlightText (const CPoint & ptStartPos, int nLength,
- bool bCursorToLeft /*= false*/)
+HighlightText (const CEPoint & ptStartPos, int nLength,
+ bool bCursorToLeft /*= false*/, bool bUpdateView /*= true*/)
{
ASSERT_VALIDTEXTPOS (ptStartPos);
- CPoint ptEndPos = ptStartPos;
+ CEPoint ptEndPos = ptStartPos;
int nCount = GetLineLength (ptEndPos.y) - ptEndPos.x;
if (nLength <= nCount)
{
m_ptCursorPos = bCursorToLeft ? ptStartPos : ptEndPos;
m_ptAnchor = bCursorToLeft ? ptEndPos : ptStartPos;
SetSelection (ptStartPos, ptEndPos);
+
+ if (!bUpdateView)
+ return true;
+
UpdateCaret ();
// Scrolls found text to middle of screen if out-of-screen
}
bool CCrystalTextView::
-FindText (LPCTSTR pszText, const CPoint & ptStartPos, DWORD dwFlags,
- bool bWrapSearch, CPoint * pptFoundPos)
+FindText (const tchar_t* pszText, const CEPoint & ptStartPos, DWORD dwFlags,
+ bool bWrapSearch, CEPoint * pptFoundPos)
{
if (m_pMarkers != nullptr)
{
m_pMarkers->UpdateViews();
}
int nLineCount = GetLineCount ();
- return FindTextInBlock (pszText, ptStartPos, CPoint (0, 0),
- CPoint (GetLineLength (nLineCount - 1), nLineCount - 1),
+ return FindTextInBlock (pszText, ptStartPos, CEPoint (0, 0),
+ CEPoint (GetLineLength (nLineCount - 1), nLineCount - 1),
dwFlags, bWrapSearch, pptFoundPos);
}
-int HowManyStr (LPCTSTR s, LPCTSTR m)
+int HowManyStr (const tchar_t* s, const tchar_t* m)
{
- LPCTSTR p = s;
+ const tchar_t* p = s;
int n = 0;
- const int l = (int) _tcslen (m);
- while ((p = _tcsstr (p, m)) != nullptr)
+ const int l = (int) tc::tcslen (m);
+ while ((p = tc::tcsstr (p, m)) != nullptr)
{
n++;
p += l;
return n;
}
-int HowManyStr (LPCTSTR s, TCHAR c)
+int HowManyStr (const tchar_t* s, tchar_t c)
{
- LPCTSTR p = s;
+ const tchar_t* p = s;
int n = 0;
- while ((p = _tcschr (p, c)) != nullptr)
+ while ((p = tc::tcschr (p, c)) != nullptr)
{
n++;
p++;
}
bool CCrystalTextView::
-FindTextInBlock (LPCTSTR pszText, const CPoint & ptStartPosition,
- const CPoint & ptBlockBegin, const CPoint & ptBlockEnd,
- DWORD dwFlags, bool bWrapSearch, CPoint * pptFoundPos)
+FindTextInBlock (const tchar_t* pszText, const CEPoint & ptStartPosition,
+ const CEPoint & ptBlockBegin, const CEPoint & ptBlockEnd,
+ findtext_flags_t dwFlags, bool bWrapSearch, CEPoint * pptFoundPos)
{
- CPoint ptCurrentPos = ptStartPosition;
+ CEPoint ptCurrentPos = ptStartPosition;
- ASSERT (pszText != nullptr && _tcslen (pszText) > 0);
+ ASSERT (pszText != nullptr && tc::tcslen (pszText) > 0);
ASSERT_VALIDTEXTPOS (ptCurrentPos);
ASSERT_VALIDTEXTPOS (ptBlockBegin);
ASSERT_VALIDTEXTPOS (ptBlockEnd);
for (int i = 0; i <= nEolns && ptCurrentPos.y >= i; i++)
{
CString item;
- LPCTSTR pszChars = GetLineChars (ptCurrentPos.y - i);
+ const tchar_t* pszChars = GetLineChars (ptCurrentPos.y - i);
if (i)
{
nLineLength = GetLineLength (ptCurrentPos.y - i);
{
ptCurrentPos.x = nLineLength;
}
- else
- if( ptCurrentPos.x > nLineLength )
- ptCurrentPos.x = nLineLength;
+ else if( ptCurrentPos.x > nLineLength )
+ ptCurrentPos.x = nLineLength;
if (ptCurrentPos.x == -1)
ptCurrentPos.x = 0;
size_t nPos = 0;
for (;;)
{
- size_t nPosRel = ::FindStringHelper(line, nLineLen, static_cast<LPCTSTR>(line) + nPos, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch);
- if (nPosRel == -1)
+ nPos = ::FindStringHelper(line, nLineLen, static_cast<const tchar_t*>(line) + nPos, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch);
+ if (nPos == -1)
break;
- nFoundPos = nPos + nPosRel;
+ nFoundPos = nPos;
nMatchLen = m_nLastFindWhatLen;
nPos += nMatchLen == 0 ? 1 : nMatchLen;
}
// Start again from the end of text
bWrapSearch = false;
- ptCurrentPos = CPoint (GetLineLength (GetLineCount () - 1), GetLineCount () - 1);
+ ptCurrentPos = CEPoint (GetLineLength (GetLineCount () - 1), GetLineCount () - 1);
}
}
else
int nLines = m_pTextBuffer->GetLineCount ();
for (int i = 0; i <= nEolns && ptCurrentPos.y + i < nLines; i++)
{
- LPCTSTR pszChars = GetLineChars (ptCurrentPos.y + i);
+ const tchar_t* pszChars = GetLineChars (ptCurrentPos.y + i);
nLineLength = GetLineLength (ptCurrentPos.y + i);
if (i)
{
if (nLineLength > 0)
{
int nLineLengthOld = line.GetLength();
- memcpy(line.GetBufferSetLength(nLineLengthOld + nLineLength) + nLineLengthOld, pszChars, nLineLength * sizeof(TCHAR));
+ memcpy(line.GetBufferSetLength(nLineLengthOld + nLineLength) + nLineLengthOld, pszChars, nLineLength * sizeof(tchar_t));
}
}
nLineLength = line.GetLength ();
}
// Perform search in the line
- size_t nPos = ::FindStringHelper (line, line.GetLength (), static_cast<LPCTSTR>(line) + ptCurrentPos.x, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch);
+ size_t nPos = ::FindStringHelper (line, line.GetLength (), static_cast<const tchar_t*>(line) + ptCurrentPos.x, what, dwFlags, m_nLastFindWhatLen, m_rxnode, &m_rxmatch);
if (nPos != -1)
{
if (m_pszMatched != nullptr)
free(m_pszMatched);
- m_pszMatched = _tcsdup (line);
+ m_pszMatched = tc::tcsdup (line);
if (nEolns)
{
CString item = line.Left (static_cast<LONG>(nPos));
- LPCTSTR current = _tcsrchr (item, _T('\n'));
+ const tchar_t* current = tc::tcsrchr (item, _T('\n'));
if (current)
current++;
else
if (nEolns)
{
ptCurrentPos.y += nEolns;
- ptCurrentPos.x = static_cast<LONG>(nPos - (current - (LPCTSTR) item));
+ ptCurrentPos.x = static_cast<LONG>(nPos - (current - (const tchar_t*) item));
}
else
{
- ptCurrentPos.x += static_cast<LONG>(nPos - (current - (LPCTSTR) item));
+ ptCurrentPos.x = static_cast<LONG>(nPos - (current - (const tchar_t*) item));
}
if (ptCurrentPos.x < 0)
ptCurrentPos.x = 0;
}
else
{
- ptCurrentPos.x += static_cast<LONG>(nPos);
+ ptCurrentPos.x = static_cast<LONG>(nPos);
}
// Check of the text found is outside the block.
if (ptCurrentPos.y == ptBlockEnd.y && ptCurrentPos.x >= ptBlockEnd.x)
}
}
- //~ ASSERT (false); // Unreachable
-}
-
-static DWORD ConvertSearchInfosToSearchFlags(const LastSearchInfos *lastSearch)
-{
- DWORD dwSearchFlags = 0;
- if (lastSearch->m_bMatchCase)
- dwSearchFlags |= FIND_MATCH_CASE;
- if (lastSearch->m_bWholeWord)
- dwSearchFlags |= FIND_WHOLE_WORD;
- if (lastSearch->m_bRegExp)
- dwSearchFlags |= FIND_REGEXP;
- if (lastSearch->m_nDirection == 0)
- dwSearchFlags |= FIND_DIRECTION_UP;
- if (lastSearch->m_bNoWrap)
- dwSearchFlags |= FIND_NO_WRAP;
- if (lastSearch->m_bNoClose)
- dwSearchFlags |= FIND_NO_CLOSE;
- return dwSearchFlags;
-}
-
-static void ConvertSearchFlagsToLastSearchInfos(LastSearchInfos *lastSearch, DWORD dwFlags)
-{
- lastSearch->m_bMatchCase = (dwFlags & FIND_MATCH_CASE) != 0;
- lastSearch->m_bWholeWord = (dwFlags & FIND_WHOLE_WORD) != 0;
- lastSearch->m_bRegExp = (dwFlags & FIND_REGEXP) != 0;
- lastSearch->m_nDirection = (dwFlags & FIND_DIRECTION_UP) == 0;
- lastSearch->m_bNoWrap = (dwFlags & FIND_NO_WRAP) != 0;
- lastSearch->m_bNoClose = (dwFlags & FIND_NO_CLOSE) != 0;
+ //~ ASSERT (false); // Unreachable
}
-CPoint CCrystalTextView::
-GetSearchPos(DWORD dwSearchFlags)
+CEPoint CCrystalTextView::
+GetSearchPos(findtext_flags_t dwSearchFlags)
{
- CPoint ptSearchPos;
+ CEPoint ptSearchPos;
if (IsSelection())
{
- CPoint ptStart, ptEnd;
- GetSelection(ptStart, ptEnd);
+ auto [ptStart, ptEnd] = GetSelection ();
if( dwSearchFlags & FIND_DIRECTION_UP)
ptSearchPos = ptStart;
else
bool CCrystalTextView::
FindText (const LastSearchInfos * lastSearch)
{
- CPoint ptTextPos;
- DWORD dwSearchFlags = ConvertSearchInfosToSearchFlags(lastSearch);
+ CEPoint ptTextPos;
+ findtext_flags_t dwSearchFlags = ConvertSearchInfosToSearchFlags(lastSearch);
if (!FindText (lastSearch->m_sText, GetSearchPos(dwSearchFlags), dwSearchFlags, !lastSearch->m_bNoWrap,
&ptTextPos))
{
m_bLastSearch = true;
if (m_pszLastFindWhat != nullptr)
free (m_pszLastFindWhat);
- m_pszLastFindWhat = _tcsdup (lastSearch->m_sText);
+ m_pszLastFindWhat = tc::tcsdup (lastSearch->m_sText);
m_dwLastSearchFlags = dwSearchFlags;
// Save search parameters to registry
- VERIFY (RegSaveNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("FindFlags"), m_dwLastSearchFlags));
+ VERIFY (AfxGetApp ()->WriteProfileInt (EDITPAD_SECTION, _T ("FindFlags"), m_dwLastSearchFlags));
return true;
}
void CCrystalTextView::
OnEditFind ()
{
- CWinApp *pApp = AfxGetApp ();
- ASSERT (pApp != nullptr);
-
if (m_pFindTextDlg == nullptr)
m_pFindTextDlg = new CFindTextDlg (this);
}
else
{
- DWORD dwFlags;
- if (!RegLoadNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("FindFlags"), &dwFlags))
- dwFlags = 0;
+ findtext_flags_t dwFlags = AfxGetApp ()->GetProfileInt (EDITPAD_SECTION, _T("FindFlags"), FIND_NO_CLOSE);
ConvertSearchFlagsToLastSearchInfos(lastSearch, dwFlags);
}
m_pFindTextDlg->UseLastSearch ();
// Take the current selection, if any
if (IsSelection ())
{
- CPoint ptSelStart, ptSelEnd;
- GetSelection (ptSelStart, ptSelEnd);
+ auto [ptSelStart, ptSelEnd] = GetSelection ();
if (ptSelStart.y == ptSelEnd.y)
GetText (ptSelStart, ptSelEnd, m_pFindTextDlg->m_sText);
}
else
{
- CPoint ptCursorPos = GetCursorPos ();
- CPoint ptStart = WordToLeft (ptCursorPos);
- CPoint ptEnd = WordToRight (ptCursorPos);
+ CEPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptStart = WordToLeft (ptCursorPos);
+ CEPoint ptEnd = WordToRight (ptCursorPos);
if (IsValidTextPos (ptStart) && IsValidTextPos (ptEnd) && ptStart != ptEnd)
GetText (ptStart, ptEnd, m_pFindTextDlg->m_sText);
}
{
bool bEnable = m_bLastSearch;
// Show dialog if no last find text
- if (m_pszLastFindWhat == nullptr || _tcslen(m_pszLastFindWhat) == 0)
+ if (m_pszLastFindWhat == nullptr || tc::tcslen(m_pszLastFindWhat) == 0)
bEnable = false;
CString sText;
if (bEnable)
{
if (IsSelection())
{
- CPoint ptSelStart, ptSelEnd;
- GetSelection (ptSelStart, ptSelEnd);
+ auto [ptSelStart, ptSelEnd] = GetSelection ();
GetText (ptSelStart, ptSelEnd, sText);
}
else
{
- CPoint ptCursorPos = GetCursorPos ();
- CPoint ptStart = WordToLeft (ptCursorPos);
- CPoint ptEnd = WordToRight (ptCursorPos);
+ CEPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptStart = WordToLeft (ptCursorPos);
+ CEPoint ptEnd = WordToRight (ptCursorPos);
if (IsValidTextPos (ptStart) && IsValidTextPos (ptEnd) && ptStart != ptEnd)
GetText (ptStart, ptEnd, sText);
}
{
bEnable = true;
free(m_pszLastFindWhat);
- m_pszLastFindWhat = _tcsdup (sText);
+ m_pszLastFindWhat = tc::tcsdup (sText);
m_bLastSearch = true;
}
}
m_dwLastSearchFlags &= ~FIND_DIRECTION_UP;
if (bEnable)
{
- CPoint ptFoundPos;
+ CEPoint ptFoundPos;
//BEGIN SW
// for correct backward search we need some changes:
if (! FindText(sText, GetSearchPos(m_dwLastSearchFlags), m_dwLastSearchFlags,
(m_dwLastSearchFlags & FIND_NO_WRAP) == 0, &ptFoundPos))
{
CString prompt;
- prompt.Format (LoadResString(IDS_EDIT_TEXT_NOT_FOUND).c_str(), (LPCTSTR)sText);
+ prompt.Format (LoadResString(IDS_EDIT_TEXT_NOT_FOUND).c_str(), (const tchar_t*)sText);
AfxMessageBox (prompt, MB_ICONINFORMATION);
return;
}
OnEditMark ()
{
CString sText;
- DWORD dwFlags;
- if (!RegLoadNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("MarkerFlags"), &dwFlags))
- dwFlags = 0;
+ findtext_flags_t dwFlags = AfxGetApp ()->GetProfileInt (EDITPAD_SECTION, _T("MarkerFlags"), 0);
// Take the current selection, if any
if (IsSelection ())
{
- CPoint ptSelStart, ptSelEnd;
- GetSelection (ptSelStart, ptSelEnd);
+ auto[ptSelStart, ptSelEnd] = GetSelection ();
if (ptSelStart.y == ptSelEnd.y)
GetText (ptSelStart, ptSelEnd, sText);
}
else
{
- CPoint ptCursorPos = GetCursorPos ();
- CPoint ptStart = WordToLeft (ptCursorPos);
- CPoint ptEnd = WordToRight (ptCursorPos);
+ CEPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptStart = WordToLeft (ptCursorPos);
+ CEPoint ptEnd = WordToRight (ptCursorPos);
if (IsValidTextPos (ptStart) && IsValidTextPos (ptEnd) && ptStart != ptEnd)
GetText (ptStart, ptEnd, sText);
}
if (markerDlg.DoModal() == IDOK)
{
// Save search parameters to registry
- VERIFY (RegSaveNumber (HKEY_CURRENT_USER, REG_EDITPAD, _T ("MarkerFlags"), markerDlg.GetLastSearchFlags()));
+ VERIFY (AfxGetApp ()->WriteProfileInt (EDITPAD_SECTION, _T ("MarkerFlags"), markerDlg.GetLastSearchFlags()));
m_pMarkers->SaveToRegistry();
}
}
dlg.m_psd.hDevMode = pd.hDevMode;
dlg.m_psd.hDevNames = pd.hDevNames;
dlg.m_psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS|PSD_MARGINS;
- dlg.m_psd.rtMargin.left = DEFAULT_PRINT_MARGIN;
- dlg.m_psd.rtMargin.right = DEFAULT_PRINT_MARGIN;
- dlg.m_psd.rtMargin.top = DEFAULT_PRINT_MARGIN;
- dlg.m_psd.rtMargin.bottom = DEFAULT_PRINT_MARGIN;
- CReg reg;
- if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ))
- {
- DWORD dwTemp;
- if (reg.LoadNumber (_T ("PageWidth"), &dwTemp))
- dlg.m_psd.ptPaperSize.x = dwTemp;
- if (reg.LoadNumber (_T ("PageHeight"), &dwTemp))
- dlg.m_psd.ptPaperSize.y = dwTemp;
- if (reg.LoadNumber (_T ("PageLeft"), &dwTemp))
- dlg.m_psd.rtMargin.left = dwTemp;
- if (reg.LoadNumber (_T ("PageRight"), &dwTemp))
- dlg.m_psd.rtMargin.right = dwTemp;
- if (reg.LoadNumber (_T ("PageTop"), &dwTemp))
- dlg.m_psd.rtMargin.top = dwTemp;
- if (reg.LoadNumber (_T ("PageBottom"), &dwTemp))
- dlg.m_psd.rtMargin.bottom = dwTemp;
- }
+ dlg.m_psd.ptPaperSize.x = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageWidth"), dlg.m_psd.ptPaperSize.x);
+ dlg.m_psd.ptPaperSize.y = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageHeight"), dlg.m_psd.ptPaperSize.y);
+ dlg.m_psd.rtMargin.left = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageLeft"), DEFAULT_PRINT_MARGIN);
+ dlg.m_psd.rtMargin.right = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageRight"), DEFAULT_PRINT_MARGIN);
+ dlg.m_psd.rtMargin.top = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageTop"), DEFAULT_PRINT_MARGIN);
+ dlg.m_psd.rtMargin.bottom = pApp->GetProfileInt(EDITPAD_SECTION, _T("PageBottom"), DEFAULT_PRINT_MARGIN);
if (dlg.DoModal () == IDOK)
{
- CReg reg1;
- if (reg1.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE))
- {
- VERIFY (reg1.SaveNumber (_T ("PageWidth"), dlg.m_psd.ptPaperSize.x));
- VERIFY (reg1.SaveNumber (_T ("PageHeight"), dlg.m_psd.ptPaperSize.y));
- VERIFY (reg1.SaveNumber (_T ("PageLeft"), dlg.m_psd.rtMargin.left));
- VERIFY (reg1.SaveNumber (_T ("PageRight"), dlg.m_psd.rtMargin.right));
- VERIFY (reg1.SaveNumber (_T ("PageTop"), dlg.m_psd.rtMargin.top));
- VERIFY (reg1.SaveNumber (_T ("PageBottom"), dlg.m_psd.rtMargin.bottom));
- }
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageWidth"), dlg.m_psd.ptPaperSize.x));
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageHeight"), dlg.m_psd.ptPaperSize.y));
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageLeft"), dlg.m_psd.rtMargin.left));
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageRight"), dlg.m_psd.rtMargin.right));
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageTop"), dlg.m_psd.rtMargin.top));
+ VERIFY (pApp->WriteProfileInt (EDITPAD_SECTION, _T ("PageBottom"), dlg.m_psd.rtMargin.bottom));
pApp->SelectPrinter (dlg.m_psd.hDevNames, dlg.m_psd.hDevMode, false);
}
}
ASSERT(nLine >= 0 && nLine < GetLineCount());
if (m_pTextBuffer != nullptr)
{
- DWORD dwFlags = GetLineFlags (nLine);
- DWORD dwMask = LF_BOOKMARKS;
+ lineflags_t dwFlags = GetLineFlags (nLine);
+ lineflags_t dwMask = LF_BOOKMARKS;
m_pTextBuffer->SetLineFlag (nLine, dwMask, (dwFlags & dwMask) == 0, false);
const int nBookmarkLine = m_pTextBuffer->GetLineWithFlag (LF_BOOKMARKS);
if (nBookmarkLine >= 0)
int nLine = m_pTextBuffer->FindNextBookmarkLine (m_ptCursorPos.y);
if (nLine >= 0)
{
- CPoint pt (0, nLine);
+ CEPoint pt (0, nLine);
ASSERT_VALIDTEXTPOS (pt);
SetCursorPos (pt);
SetSelection (pt, pt);
int nLine = m_pTextBuffer->FindPrevBookmarkLine (m_ptCursorPos.y);
if (nLine >= 0)
{
- CPoint pt (0, nLine);
+ CEPoint pt (0, nLine);
ASSERT_VALIDTEXTPOS (pt);
SetCursorPos (pt);
SetSelection (pt, pt);
pCmdUI->Enable (m_bBookmarkExist);
}
-bool CCrystalTextView::
-GetViewTabs ()
-{
- return m_bViewTabs;
-}
-
void CCrystalTextView::
SetViewTabs (bool bViewTabs)
{
}
}
-DWORD CCrystalTextView::
-GetFlags ()
-{
- return m_dwFlags;
-}
-
void CCrystalTextView::
SetFlags (DWORD dwFlags)
{
}
}
-bool CCrystalTextView::
-GetSelectionMargin ()
-{
- return m_bSelMargin;
-}
-
-bool CCrystalTextView::
-GetViewLineNumbers () const
+int CCrystalTextView::
+GetTopMarginHeight()
{
- return m_bViewLineNumbers;
+ if (!m_bTopMargin)
+ return 0;
+ return GetLineHeight();
}
/**
if (m_bSelMargin)
{
if (pdc == nullptr || !pdc->IsPrinting ())
- nMarginWidth += MARGIN_ICON_WIDTH + 7; // Width for icon markers and some margin
+ nMarginWidth += GetMarginIconSize () + 7; // Width for icon markers and some margin
}
else
{
return nMarginWidth;
}
-bool CCrystalTextView::
-GetSmoothScroll ()
-const
-{
- return m_bSmoothScroll;
-}
-
-void CCrystalTextView::SetSmoothScroll (bool bSmoothScroll)
-{
- m_bSmoothScroll = bSmoothScroll;
-}
-
-// [JRT]
-bool CCrystalTextView::
-GetDisableDragAndDrop ()
-const
-{
- return m_bDisableDragAndDrop;
-}
-
-// [JRT]
-void CCrystalTextView::SetDisableDragAndDrop (bool bDDAD)
-{
- m_bDisableDragAndDrop = bDDAD;
-}
-
void CCrystalTextView::CopyProperties (CCrystalTextView *pSource)
{
m_nTopLine = pSource->m_nTopLine;
m_bViewTabs = pSource->m_bViewTabs;
m_bViewEols = pSource->m_bViewEols;
m_bDistinguishEols = pSource->m_bDistinguishEols;
+ m_bTopMargin = pSource->m_bTopMargin;
m_bSelMargin = pSource->m_bSelMargin;
m_bViewLineNumbers = pSource->m_bViewLineNumbers;
m_bSmoothScroll = pSource->m_bSmoothScroll;
BOOL CCrystalTextView::
OnMouseWheel (UINT nFlags, short zDelta, CPoint pt)
{
- SCROLLINFO si = {0};
- si.cbSize = sizeof (si);
+ SCROLLINFO si{ sizeof(si) };
si.fMask = SIF_PAGE | SIF_RANGE;
VERIFY (GetScrollInfo (SB_VERT, &si));
ScrollToSubLine(nNewTopSubLine, true);
UpdateSiblingScrollPos(false);
+ UpdateCaret ();
return CView::OnMouseWheel (nFlags, zDelta, pt);
}
si.fMask = SIF_POS | SIF_RANGE;
VERIFY (GetScrollInfo (SB_HORZ, &si));
- int nCurPos = si.nPos + zDelta;
+ int nCurPos = si.nPos + zDelta / 40;
if (nCurPos < si.nMin)
nCurPos = si.nMin;
else if (nCurPos > si.nMax)
void CCrystalTextView::
OnSourceType (UINT nId)
{
- SetTextType ((CCrystalTextView::TextType) (nId - ID_SOURCE_PLAIN));
+ SetTextType ((CrystalLineParser::TextType) (nId - ID_SOURCE_PLAIN));
Invalidate ();
}
void CCrystalTextView::
OnUpdateSourceType (CCmdUI * pCmdUI)
{
- pCmdUI->SetRadio (m_SourceDefs + (pCmdUI->m_nID - ID_SOURCE_PLAIN) == m_CurSourceDef);
+ pCmdUI->SetRadio (CrystalLineParser::m_SourceDefs + (pCmdUI->m_nID - ID_SOURCE_PLAIN) == m_CurSourceDef);
}
int
-bracetype (TCHAR c)
+bracetype (tchar_t c)
{
- static LPCTSTR braces = _T("{}()[]<>");
- LPCTSTR pos = _tcschr (braces, c);
+ static const tchar_t* braces = _T("{}()[]<>");
+ const tchar_t* pos = tc::tcschr (braces, c);
return pos != nullptr ? (int) (pos - braces) + 1 : 0;
}
int
-bracetype (LPCTSTR s)
+bracetype (const tchar_t* s)
{
if (s[1])
return 0;
void CCrystalTextView::
OnMatchBrace ()
{
- CPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptCursorPos = GetCursorPos ();
int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y);
- LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y), pszEnd = pszText + ptCursorPos.x;
+ const tchar_t* pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y), *pszEnd = pszText + ptCursorPos.x;
bool bAfter = false;
int nType = 0;
if (ptCursorPos.x < nLength)
if (!(nOther & 1))
pszEnd++;
}
- LPCTSTR pszOpenComment = m_CurSourceDef->opencomment,
- pszCloseComment = m_CurSourceDef->closecomment,
- pszCommentLine = m_CurSourceDef->commentline, pszTest;
- int nOpenComment = (int) _tcslen (pszOpenComment),
- nCloseComment = (int) _tcslen (pszCloseComment),
- nCommentLine = (int) _tcslen (pszCommentLine);
+ const tchar_t* pszOpenComment = m_CurSourceDef->opencomment,
+ *pszCloseComment = m_CurSourceDef->closecomment,
+ *pszCommentLine = m_CurSourceDef->commentline, *pszTest;
+ int nOpenComment = (int) tc::tcslen (pszOpenComment),
+ nCloseComment = (int) tc::tcslen (pszCloseComment),
+ nCommentLine = (int) tc::tcslen (pszCommentLine);
if (nOther & 1)
{
for (;;)
while (--pszEnd >= pszText)
{
pszTest = pszEnd - nOpenComment + 1;
- if (pszTest >= pszText && !_tcsnicmp (pszTest, pszOpenComment, nOpenComment))
+ if (pszTest >= pszText && !tc::tcsnicmp (pszTest, pszOpenComment, nOpenComment))
{
nComment--;
pszEnd = pszTest;
}
}
pszTest = pszEnd - nCloseComment + 1;
- if (pszTest >= pszText && !_tcsnicmp (pszTest, pszCloseComment, nCloseComment))
+ if (pszTest >= pszText && !tc::tcsnicmp (pszTest, pszCloseComment, nCloseComment))
{
nComment++;
pszEnd = pszTest;
if (!nComment)
{
pszTest = pszEnd - nCommentLine + 1;
- if (pszTest >= pszText && !_tcsnicmp (pszTest, pszCommentLine, nCommentLine))
+ if (pszTest >= pszText && !tc::tcsnicmp (pszTest, pszCommentLine, nCommentLine))
{
break;
}
}
else
{
- LPCTSTR pszBegin = pszText;
+ const tchar_t* pszBegin = pszText;
pszText = pszEnd;
pszEnd = pszBegin + nLength;
int nLines = m_pTextBuffer->GetLineCount ();
while (pszText < pszEnd)
{
pszTest = pszText + nCloseComment;
- if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszCloseComment, nCloseComment))
+ if (pszTest <= pszEnd && !tc::tcsnicmp (pszText, pszCloseComment, nCloseComment))
{
nComment--;
pszText = pszTest;
}
}
pszTest = pszText + nOpenComment;
- if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszOpenComment, nOpenComment))
+ if (pszTest <= pszEnd && !tc::tcsnicmp (pszText, pszOpenComment, nOpenComment))
{
nComment++;
pszText = pszTest;
if (!nComment)
{
pszTest = pszText + nCommentLine;
- if (pszTest <= pszEnd && !_tcsnicmp (pszText, pszCommentLine, nCommentLine))
+ if (pszTest <= pszEnd && !tc::tcsnicmp (pszText, pszCommentLine, nCommentLine))
{
break;
}
void CCrystalTextView::
OnUpdateMatchBrace (CCmdUI * pCmdUI)
{
- CPoint ptCursorPos = GetCursorPos ();
+ CEPoint ptCursorPos = GetCursorPos ();
int nLength = m_pTextBuffer->GetLineLength (ptCursorPos.y);
- LPCTSTR pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y) + ptCursorPos.x;
+ const tchar_t* pszText = m_pTextBuffer->GetLineChars (ptCursorPos.y) + ptCursorPos.x;
pCmdUI->Enable (ptCursorPos.x < nLength && (bracetype (*pszText) || ptCursorPos.x > 0 && bracetype (pszText[-1])) || ptCursorPos.x > 0 && bracetype (pszText[-1]));
}
void CCrystalTextView::
OnUpdateToggleSourceHeader (CCmdUI * pCmdUI)
{
- pCmdUI->Enable (m_CurSourceDef->type == SRC_C);
+ pCmdUI->Enable (m_CurSourceDef->type == CrystalLineParser::SRC_C);
}
void CCrystalTextView::
OnToggleSourceHeader ()
{
- if (m_CurSourceDef->type == SRC_C)
+ auto FileExist = [](const tchar_t* lpszPath) -> bool
+ {
+ CFileStatus status;
+ return CFile::GetStatus(lpszPath, status) != 0;
+ };
+ if (m_CurSourceDef->type == CrystalLineParser::SRC_C)
{
CDocument *pDoc = GetDocument ();
ASSERT (pDoc != nullptr);
CString sFilePath = pDoc->GetPathName (), sOriginalPath = sFilePath;
- if (!_tcsicmp (sFilePath.Right (2), _T (".c")))
+ if (!tc::tcsicmp (sFilePath.Right (2), _T (".c")))
{
sFilePath = sFilePath.Left (sFilePath.GetLength () - 1) + _T ('h');
}
- else if (!_tcsicmp (sFilePath.Right (4), _T (".cpp")))
+ else if (!tc::tcsicmp (sFilePath.Right (4), _T (".cpp")))
{
sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('h');
}
- else if (!_tcsicmp (sFilePath.Right (4), _T (".inl")))
+ else if (!tc::tcsicmp (sFilePath.Right (4), _T (".inl")))
{
sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ('c');
if (!FileExist(sFilePath))
sFilePath = sFilePath + _T ("pp");
}
}
- else if (!_tcsicmp (sFilePath.Right (4), _T (".hpp")))
+ else if (!tc::tcsicmp (sFilePath.Right (4), _T (".hpp")))
{
sFilePath = sFilePath.Left (sFilePath.GetLength () - 3) + _T ("inl");
if (!FileExist(sFilePath))
}
}
}
- else if (!_tcsicmp (sFilePath.Right (2), _T (".h")))
+ else if (!tc::tcsicmp (sFilePath.Right (2), _T (".h")))
{
sFilePath = sFilePath.Left (sFilePath.GetLength () - 1) + _T ("hpp");
if (!FileExist(sFilePath))
{
m_ptCursorLast.x = m_ptCursorLast.y = 0;
ASSERT_VALIDTEXTPOS (m_ptCursorLast);
- CPoint ptCursorPos = m_ptCursorLast;
+ CEPoint ptCursorPos = m_ptCursorLast;
SetCursorPos (ptCursorPos);
SetSelection (ptCursorPos, ptCursorPos);
SetAnchor (ptCursorPos);
}
void CCrystalTextView::
+OnUpdateTopMargin (CCmdUI * pCmdUI)
+{
+ pCmdUI->SetCheck (m_bTopMargin);
+}
+
+void CCrystalTextView::
+OnTopMargin ()
+{
+ ASSERT (m_CurSourceDef != nullptr);
+ if (m_bTopMargin)
+ m_CurSourceDef->flags &= ~SRCOPT_TOPMARGIN;
+ else
+ m_CurSourceDef->flags |= SRCOPT_TOPMARGIN;
+ SetTopMargin (!m_bTopMargin);
+}
+
+void CCrystalTextView::
OnUpdateSelMargin (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck (m_bSelMargin);
{
ASSERT (m_CurSourceDef != nullptr);
if (m_bSelMargin)
- {
- m_CurSourceDef->flags &= ~SRCOPT_SELMARGIN;
- SetSelectionMargin (false);
- }
+ m_CurSourceDef->flags &= ~SRCOPT_SELMARGIN;
else
- {
- m_CurSourceDef->flags |= SRCOPT_SELMARGIN;
- SetSelectionMargin (true);
- }
+ m_CurSourceDef->flags |= SRCOPT_SELMARGIN;
+ SetSelectionMargin (!m_bSelMargin);
}
void CCrystalTextView::
void CCrystalTextView::
OnToggleColumnSelection ()
{
- m_bColumnSelection = !m_bColumnSelection;
+ m_bRectangularSelection = !m_bRectangularSelection;
Invalidate ();
}
void CCrystalTextView::SetRenderingMode(RENDERING_MODE nRenderingMode)
{
#ifdef _WIN64
- if (nRenderingMode == RENDERING_MODE_GDI)
+ if (nRenderingMode == RENDERING_MODE::GDI)
m_pCrystalRenderer.reset(new CCrystalRendererGDI());
else
- m_pCrystalRenderer.reset(new CCrystalRendererDirectWrite(nRenderingMode));
+ m_pCrystalRenderer.reset(new CCrystalRendererDirectWrite(static_cast<int>(nRenderingMode)));
m_pCrystalRenderer->SetFont(m_lfBaseFont);
#endif
m_nRenderingMode = nRenderingMode;
}
//END SW
-bool CCrystalTextView::GetEnableHideLines () const
-{
- return m_bHideLines;
-}
-
-void CCrystalTextView::SetEnableHideLines (bool bHideLines)
-{
- m_bHideLines = bHideLines;
-}
-
/**
* @brief Return whether a line is visible.
*/
}
// add character to incremental search string and search
- *m_pstrIncrementalSearchString += (TCHAR) nChar;
+ *m_pstrIncrementalSearchString += (tchar_t) nChar;
OnEditFindIncremental();
}
// otherwise search next occurence of search string,
// starting at current cursor position
- CPoint matchStart, matchEnd;
+ CEPoint matchStart, matchEnd;
// calculate start point for search
if( bFindNextOccurence )
{
- CPoint selStart, selEnd;
- GetSelection( selStart, selEnd );
+ auto[selStart, selEnd] = GetSelection ();
m_incrementalSearchStartPos = (m_bIncrementalSearchBackward)? selStart : selEnd;
}
formatid = IDS_FIND_INCREMENTAL_BACKWARD;
else
return;
- strFormat.Format( LoadResString(formatid).c_str(), (LPCTSTR)*m_pstrIncrementalSearchString );
+ strFormat.Format( LoadResString(formatid).c_str(), (const tchar_t*)*m_pstrIncrementalSearchString );
pStatusBar->SetPaneText( 0, strFormat );
bUpdatedAtLastCall = false;
wchar_t nEnd = nStart + 255;
m_pCrystalRenderer->GetCharWidth(nStart, nEnd, nWidthArray);
int nCharWidth = GetCharWidth();
+ const ViewableWhitespaceChars * lpspc = GetViewableWhitespaceChars(GetACP(), m_nRenderingMode != RENDERING_MODE::GDI);
for (int i = 0; i < 256; i++)
{
+ wchar_t ch2 = static_cast<wchar_t>(nStart + i);
if (nCharWidth * 15 < nWidthArray[i] * 10)
- m_iChDoubleWidthFlags[(nStart+i)/32] |= 1 << (i % 32);
+ {
+ if (ch2 != lpspc->c_space[0] && ch2 != lpspc->c_tab[0])
+ m_iChDoubleWidthFlags[ch2 / 32] |= 1 << (i % 32);
+ }
else
{
- wchar_t ch2 = static_cast<wchar_t>(nStart + i);
if (wcwidth(ch2) > 1)
- m_iChDoubleWidthFlags[(nStart + i) / 32] |= 1 << (i % 32);
+ m_iChDoubleWidthFlags[ch2 / 32] |= 1 << (i % 32);
}
}
m_bChWidthsCalculated[ch / 256] = true;
}
// This function assumes selection is in one line
-void CCrystalTextView::EnsureVisible (CPoint ptStart, CPoint ptEnd)
+void CCrystalTextView::EnsureVisible (CEPoint ptStart, CEPoint ptEnd)
{
// Scroll vertically
//BEGIN SW
int nSubLineCount = GetSubLineCount();
int nNewTopSubLine = m_nTopSubLine;
- CPoint subLinePos;
+ CEPoint subLinePos;
CharPosToPoint( ptStart.y, ptStart.x, subLinePos );
subLinePos.y += GetSubLineIndex( ptStart.y );
// Scroll horizontally
//BEGIN SW
// we do not need horizontally scrolling, if we wrap the words
- if( m_bWordWrap )
+ if( GetTextLayoutMode () == TEXTLAYOUT_WORDWRAP )
return;
//END SW
int nActualPos = CalculateActualOffset (ptStart.y, ptStart.x);
{
// Scroll so that there is max 5 chars margin at end
if (nScreenChars - nSelLen > 5)
- nNewOffset = nActualPos + 5 - nScreenChars + nSelLen;
+ nNewOffset = nActualPos + 5 - nScreenChars + nSelLen;
else
- nNewOffset = nActualPos - 5;
+ nNewOffset = nActualPos - 5;
}
else if (nBeginOffset < 0)
{
// Scroll so that there is max 5 chars margin at begin
if (nScreenChars - nSelLen >= 5)
- nNewOffset = nActualPos - 5;
+ nNewOffset = nActualPos - 5;
else
- nNewOffset = nActualPos - 5 - nScreenChars + nSelLen;
+ nNewOffset = nActualPos - 5 - nScreenChars + nSelLen;
}
// End of selection not visible
else if (nEndOffset > nScreenChars ||
// Analyze the first line of file to detect its type
// Mainly it works for xml files
bool CCrystalTextView::
-SetTextTypeByContent (LPCTSTR pszContent)
+SetTextTypeByContent (const tchar_t* pszContent)
{
RxNode *rxnode = nullptr;
RxMatchRes rxmatch;
int nLen;
- if (::FindStringHelper(pszContent, _tcslen(pszContent), pszContent, _T("^\\s*\\<\\?xml\\s+.+?\\?\\>\\s*$"),
+ if (::FindStringHelper(pszContent, tc::tcslen(pszContent), pszContent, _T("^\\s*\\<\\?xml\\s+.+?\\?\\>\\s*$"),
FIND_REGEXP, nLen, rxnode, &rxmatch) == 0)
{
if (rxnode)
RxFree (rxnode);
- return SetTextType(CCrystalTextView::SRC_XML);
+ return SetTextType(CrystalLineParser::SRC_XML);
}
if (rxnode)
RxFree (rxnode);
return false;
}
+void CCrystalTextView::
+AutoFitColumn (int nColumn)
+{
+ int nLastColumn = 0;
+ int nLastColumnWidth = 0;
+ const int nTabSize = GetTabSize ();
+ std::vector<int> aColumnWidths;
+ const int nScreenChars = GetScreenChars ();
+ const int nMaxColumnWidth = nScreenChars < 1 ? 1 : nScreenChars - 1;
+ for (auto& pbuf : m_pTextBuffer->GetTextBufferList ())
+ {
+ const tchar_t sep = pbuf->GetFieldDelimiter ();
+ const int quote = pbuf->GetFieldEnclosure ();
+ const int nLineCount = pbuf->GetLineCount ();
+ for (int i = 0; i < nLineCount; ++i)
+ {
+ bool bInQuote = false;
+ int nColumn2 = 0;
+ int nColumnWidth = 0;
+ const tchar_t* pszChars = pbuf->GetLineChars (i);
+ const size_t nLineLength = pbuf->GetFullLineLength (i);
+ for (size_t j = 0; j < nLineLength; j += U16_IS_SURROGATE (pszChars[j]) ? 2 : 1)
+ {
+ bool bDelimiterOrNewLine = false;
+ tchar_t c = pszChars[j];
+ if (c == quote)
+ bInQuote = !bInQuote;
+ if (!bInQuote && c == sep)
+ {
+ bDelimiterOrNewLine = true;
+ ++nColumnWidth;
+ }
+ else if (c == '\r' || c == '\n')
+ {
+ if (m_bWordWrap)
+ {
+ if (c == '\r')
+ {
+ if (j == nLineLength - 1 || pszChars[j + 1] != '\n')
+ {
+ nColumnWidth += 2;
+ bDelimiterOrNewLine = true;
+ }
+ }
+ else
+ {
+ if (j > 0 && pszChars[j - 1] == '\r')
+ nColumnWidth += 4;
+ else
+ nColumnWidth += 2;
+ bDelimiterOrNewLine = true;
+ }
+ }
+ else
+ nColumnWidth += GetCharCellCountFromChar (pszChars + j);
+ }
+ else if (c == '\t')
+ nColumnWidth ++;
+ else
+ nColumnWidth += GetCharCellCountFromChar (pszChars + j);
+
+ if (bDelimiterOrNewLine)
+ {
+ if (nColumnWidth > nMaxColumnWidth)
+ nColumnWidth = nMaxColumnWidth;
+ if (static_cast<int>(aColumnWidths.size ()) < nColumn2 + 1)
+ aColumnWidths.resize (nColumn2 + 1, nTabSize);
+ if (aColumnWidths[nColumn2] < nColumnWidth)
+ aColumnWidths[nColumn2] = nColumnWidth;
+ nColumnWidth = 0;
+ if (c == sep)
+ ++nColumn2;
+ }
+ }
+ if (nLastColumn < nColumn2)
+ {
+ nLastColumn = nColumn2;
+ nLastColumnWidth = 0;
+ }
+ if (nLastColumnWidth < nColumnWidth)
+ nLastColumnWidth = nColumnWidth;
+ }
+ }
+
+ aColumnWidths.resize (nLastColumn + 1, nTabSize);
+ if (aColumnWidths[nLastColumn] < nLastColumnWidth)
+ aColumnWidths[nLastColumn] = nLastColumnWidth;
+
+ for (size_t nColumn2 = 0; nColumn2 < aColumnWidths.size (); ++nColumn2)
+ {
+ if (nColumn == -1 || nColumn == static_cast<int>(nColumn2))
+ m_pTextBuffer->SetColumnWidth (static_cast<int>(nColumn2), aColumnWidths[nColumn2]);
+ }
+ m_pTextBuffer->InvalidateColumns ();
+}
+
+CCrystalTextView::TextLayoutMode CCrystalTextView::GetTextLayoutMode () const
+{
+ if (m_pTextBuffer && m_pTextBuffer->GetTableEditing ())
+ return m_bWordWrap ? TEXTLAYOUT_TABLE_WORDWRAP : TEXTLAYOUT_TABLE_NOWORDWRAP;
+ return m_bWordWrap ? TEXTLAYOUT_WORDWRAP : TEXTLAYOUT_NOWORDWRAP;
+}
+
////////////////////////////////////////////////////////////////////////////