📄 tview.cpp
字号:
}
void CTView::OnDictSetup() {
CDictSetupDlg dlg;
dlg.DoModal();
}
void CTView::OnUpdateDictSetup(CCmdUI* pCmdUI) {
pCmdUI->Enable();
}
void CTView::OnUpdateFind(CCmdUI* pCmdUI) {
pCmdUI->Enable();
}
void CTView::OnFind() {
CFindDlg dlg(this);
Buffer<wchar_t> sel;
if (GetSelText(sel))
dlg.m_text=Unicode::ToCS(sel);
else
dlg.m_text=Unicode::ToCS(m_Search.searchstr);
dlg.m_matchcase=m_Search.matchcase;
if (dlg.DoModal()==IDOK && dlg.m_text.GetLength()>0) {
m_Search.matchpos=m_formatter->Sof();
m_Search.matchcase=dlg.m_matchcase!=0;
m_Search.searchstr=Unicode::ToWCbuf(dlg.m_text);
if (!m_Search.matchcase)
m_Search.searchstr=Unicode::Lower(m_Search.searchstr);
CTVApp::QueueCmd(ID_DO_FIND);
}
}
void CTView::OnFindnext() {
if (m_Search.searchstr.size()>0 &&
m_Search.matchpos+m_Search.searchstr.size()<m_formatter->Eof()) {
m_Search.matchpos.off+=m_Search.searchstr.size();
DoFind();
}
}
void CTView::OnUpdateFindnext(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_Search.searchstr.size()>0 &&
m_Search.matchpos+m_Search.searchstr.size()<m_formatter->Eof());
}
static Buffer<int> kmptable(const Buffer<wchar_t>& s) {
Buffer<int> b(s.size()+1);
if (s.size()>0) {
int i,j;
i=0;
j=b[0]=-1;
while (i<s.size()) {
while (j>-1 && s[i]!=s[j])
j=b[j];
++i;
++j;
if (i<s.size() && j<s.size() && s[i]==s[j])
b[i]=b[j];
else
b[i]=j;
}
}
return b;
}
static int kmpfind(const wchar_t *s,int len,int off,const wchar_t *pat,
int patlen,int *tab)
{
int i=0,j=off;
while (j<len) {
while (i>-1 && pat[i]!=s[j])
i=tab[i];
++i;
++j;
if (i>=patlen)
return j-i;
}
return -1;
}
void CTView::DoFind() {
if (m_Search.matchpos.para<m_textfile->Length(m_Search.matchpos.docid)) {
CWaitCursor wait;
Buffer<int> tab(kmptable(m_Search.matchcase ? m_Search.searchstr :
Unicode::Lower(m_Search.searchstr)));
while (m_Search.matchpos.para<m_textfile->Length(m_Search.matchpos.docid)) {
Paragraph para(m_textfile->GetParagraph(m_Search.matchpos.docid,
m_Search.matchpos.para));
Buffer<wchar_t> text(m_Search.matchcase ? para.str : Unicode::Lower(para.str));
int pp=kmpfind(text,text.size(),
m_Search.matchpos.off,m_Search.searchstr,m_Search.searchstr.size(),tab);
if (pp>=0) {
m_Search.matchpos.off=pp;
if (m_Search.matchpos<m_formatter->Top() ||
m_Search.matchpos>=m_formatter->Bottom())
{
PushPos();
EnsureVisible(m_Search.matchpos);
}
SetSelection(m_Search.matchpos,m_Search.searchstr.size());
QueueRepaint();
return;
}
++m_Search.matchpos.para;
m_Search.matchpos.off=0;
}
}
// didnt find anything
SetSelection(FilePos(),0);
QueueRepaint();
MessageBeep(MB_OK);
}
void CTView::OnUpdateColors(CCmdUI* pCmdUI) {
pCmdUI->Enable();
}
void CTView::OnColors() {
int gamma=CTVApp::GetInt(_T("Gamma"),DEF_GAMMA);
if (myChooseColors(g_colors,&gamma,this)) {
SaveColors();
CTVApp::SetInt(_T("Gamma"),gamma);
m_textfile->InvalidateImageCache();
QueueRepaint();
}
}
void CTView::OnAddBmk() {
CAddBmDialog dlg(this);
FilePos pos(CurFilePos());
Buffer<wchar_t> sel;
if (m_Sel.start.docid==pos.docid && GetSelText(sel))
pos=m_Sel.start;
dlg.m_text=Unicode::ToCS(sel);
if (dlg.DoModal()==IDOK) {
int nidx=m_textfile->bmk().Add(dlg.m_text,pos);
if (nidx<=m_BP.bmkidx)
++m_BP.bmkidx;
QueueRepaint();
}
}
void CTView::OnUpdateAddBmk(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_formatter->DocId()>=0);
}
void CTView::OnBookmarks() {
if (m_textfile->bmk().GetSize()<=0 && m_textfile->GetSubDocCount()<=1)
return;
CContentsDlg dlg(m_textfile->bmk(),m_textfile.get(),CurFilePos(),this);
if (dlg.DoModal()!=IDOK)
return;
dlg.m_index=m_textfile->bmk().Commit(dlg.m_index);
if (dlg.m_index>=0) {
PushPos();
EnsureVisible(m_textfile->bmk().Ref(dlg.m_index));
DisplayBookmarkPopup(dlg.m_index);
} else if (-dlg.m_index<=m_textfile->GetSubDocCount()) {
PushPos();
EnsureVisible(FilePos(0,0,-dlg.m_index-1));
}
}
void CTView::OnUpdateBookmarks(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_textfile->bmk().GetSize()>0);
}
void CTView::OnKeys() {
Keys::SetupKeys(this);
}
void CTView::OnUpdateKeys(CCmdUI* pCmdUI) {
pCmdUI->Enable();
}
void CTView::OnDestroy()
{
Keys::SetWindow(0);
KillTimer(m_timer);
KillTimer(m_UI.timer);
KillTimer(m_AS.timer);
KillTimer(m_Window.pd_timer);
CWnd::OnDestroy();
}
LRESULT CTView::OnHotkey(WPARAM wp,LPARAM lp) {
UINT cmd;
if (Keys::TranslateKey(wp,cmd))
CTVApp::QueueCmd(cmd);
return 0;
}
void CTView::OnStyles() {
CStylesDlg dlg(this);
if (dlg.DoModal()==IDOK) {
if (dlg.SaveChanges()) {
XMLParser::SaveStyles();
m_textfile->Reparse();
CFDC fdc(m_hWnd);
m_formatter->Reformat(fdc);
QueueRepaint();
}
}
}
void CTView::OnUpdateStyles(CCmdUI* pCmdUI) {
pCmdUI->Enable();
}
bool CTView::LookupAddr(const POINT& vp,FilePos& p) {
int column=vp.x/m_Window.width;
if (column<0 || column>=m_Window.columns) {
if (column<0)
p=m_formatter->Top();
else
p=m_formatter->Bottom();
return false;
}
int off=0;
for (int col=0;col<column;++col)
off+=m_formatter->PageLength(col);
int line=0;
int cury=0;
if (vp.y<0) {
if (m_formatter->PageLength(column)>0)
p=m_formatter->GetLine(off).pos;
else
p=m_formatter->Bottom();
return false;
}
for (;line<m_formatter->PageLength(column);++line) {
const Line& l=m_formatter->GetLine(off+line);
if (vp.y>=cury && vp.y<cury+l.height) { // found line
if (l.flags&Line::image) { // don't bother selecting this
p=l.pos;
return false;
}
int x=vp.x-m_Window.width*column-l.ispace-m_TextDisp.margin_width;
int curx=0;
int sym=0;
if (x<0) {
p=l.pos;
return false;
}
for (;sym<l.real_len;++sym) {
if (x>=curx && x<curx+l.dx[sym]) { // found character
p=l.pos;
p.off+=sym;
return true;
}
curx+=l.dx[sym];
}
p=l.pos;
p.off+=sym;
return false;
}
cury+=l.height;
}
if (m_formatter->PageLength(column)>0) {
const Line& l=m_formatter->GetLine(off+m_formatter->PageLength(column)-1);
p=l.pos;
p.off+=l.real_len;
} else
p=m_formatter->Bottom();
return false;
}
bool CTView::LookupPoint(FilePos p,POINT& pt) {
if (p<m_formatter->Top() || p>=m_formatter->Bottom())
return false;
for (int column=0,max=0,i=0,x=0;column<m_Window.columns;++column,x+=m_Window.width) {
max+=m_formatter->PageLength(column);
for (int y=0;i<max;++i) {
const Line& l1=m_formatter->GetLine(i);
const Line& l2=m_formatter->GetLine(i+1);
if (p>=l1.pos && p<l2.pos) {
x+=l1.ispace+m_TextDisp.margin_width;
int dist=p.off-l1.pos.off;
for (int i=0;i<dist;++i)
x+=l1.dx[i];
pt.x=x;
pt.y=y;
return true;
}
y+=l1.height;
}
}
return false;
}
void CTView::OnLButtonDown(UINT nFlags, CPoint point)
{
StopAS();
m_Mouse.start=m_Mouse.last=m_Mouse.end=point;
m_Mouse.trackmouse=true;
m_Mouse.dmove=m_Sel.len>0;
SetCapture();
TrackMouse();
}
void CTView::OnLButtonUp(UINT nFlags, CPoint point) {
StopAS();
if (m_Mouse.trackmouse) {
m_Mouse.end=point;
TrackMouse();
m_Mouse.trackmouse=false;
ReleaseCapture();
int len;
FilePos start;
CalcSelection(start,len);
if (!m_Mouse.dmove && !len) // position didnt change
HandleMouseDown(point);
else if (len)
DisplaySelectionMenu(point);
}
}
class CCustomMenu : public CWnd, public CRotate
{
public:
CCustomMenu() { }
void AppendMenu(const CString& title,UINT id) {
m_title.Add(title);
m_id.Add(id);
}
UINT TrackPopupMenu(CWnd *parent,int reqx,int reqy,int angle);
protected:
enum { FSZ=13, PAD=2, BORDER=1 };
CStringArray m_title;
CUIntArray m_id;
int m_selection,m_fh,m_fa,m_w,m_h;
void MenuSelect() {
#if 0
PlaySound(_T("hwandsw"),NULL,SND_ASYNC|SND_NODEFAULT); // XXX hack
#endif
EndModalLoop(m_selection<0 ? 0 : m_id[m_selection]);
}
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC) { return FALSE; }
afx_msg void OnMouseMove(UINT nFlags,CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnCaptureChanged(CWnd *pWnd) { EndModalLoop(0); }
afx_msg void OnKillFocus(CWnd* pNewWnd) { EndModalLoop(0); }
};
BEGIN_MESSAGE_MAP(CCustomMenu,CWnd )
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_KEYDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_CAPTURECHANGED()
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
void CCustomMenu::OnMouseMove(UINT nFlags,CPoint point) {
RECT cli;
GetClientRect(&cli);
System2Window(point,cli);
int sel=-1;
if (point.x>=BORDER && point.x<m_w-BORDER && point.y>=BORDER && point.y<m_h-BORDER)
sel=(point.y-BORDER)/m_fh;
if (sel!=m_selection) {
m_selection=sel;
InvalidateRect(NULL);
}
}
void CCustomMenu::OnLButtonDown(UINT nFlags,CPoint point) {
RECT cli;
GetClientRect(&cli);
System2Window(point,cli);
if (point.x<BORDER || point.x>=m_w-BORDER || point.y<BORDER || point.y>=m_h-BORDER)
EndModalLoop(0);
else {
m_selection=(point.y-BORDER)/m_fh;
InvalidateRect(NULL);
}
}
void CCustomMenu::OnLButtonUp(UINT nFlags,CPoint point) {
RECT cli;
GetClientRect(&cli);
System2Window(point,cli);
if (point.x>=BORDER && point.x<m_w-BORDER && point.y>=BORDER && point.y<m_h-BORDER) {
m_selection=(point.y-BORDER)/m_fh;
MenuSelect();
}
}
void CCustomMenu::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
switch (nChar) {
case VK_RETURN:
if (m_selection>=0)
MenuSelect();
break;
case VK_ESCAPE:
EndModalLoop(0);
break;
case VK_UP:
if (--m_selection<0)
m_selection=m_id.GetUpperBound();
InvalidateRect(NULL);
break;
case VK_DOWN:
if (++m_selection>=m_id.GetSize())
m_selection=0;
InvalidateRect(NULL);
break;
case VK_HOME:
if (m_selection!=0) {
m_selection=0;
InvalidateRect(NULL);
}
break;
case VK_END:
if (m_selection!=m_id.GetUpperBound()) {
m_selection=m_id.GetUpperBound();
InvalidateRect(NULL);
}
break;
}
}
void CCustomMenu::OnPaint() {
COLORREF
cMenuText = ::GetSysColor(COLOR_MENUTEXT),
cMenu = ::GetSysColor(COLOR_MENU),
cHlBg = ::GetSysColor(COLOR_HIGHLIGHT),
cHlText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
PAINTSTRUCT ps;
{
CFDC fdc(m_hWnd,&ps);
RECT rc,cli;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -