📄 tview.cpp
字号:
m_Search.matchpos=m_formatter->Eof();
}
}
void CTView::PushPos() {
while (m_History.stacktop) {
POSITION tmp=m_History.stacktop;
m_History.pstack.GetNext(m_History.stacktop);
m_History.pstack.RemoveAt(tmp);
}
m_History.pstack.AddTail(m_formatter->Top());
if (m_History.pstack.GetCount()>100)
m_History.pstack.RemoveHead();
}
static CString GetNextFile(const CString& filename,bool fNext) {
CString path(filename);
int p1=path.ReverseFind(_T('\\'));
int p2=path.ReverseFind(_T('/'));
p1=max(p1,p2)+1;
path.Delete(p1,path.GetLength()-p1);
path+=_T("*");
CString file(filename);
file.Delete(0,p1);
CString prev,first;
WIN32_FIND_DATA fd;
HANDLE hFind=::FindFirstFile(path,&fd);
BOOL fFind=hFind!=INVALID_HANDLE_VALUE;
for (;fFind;fFind=::FindNextFile(hFind,&fd)) {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
const TCHAR *ext=fd.cFileName+_tcslen(fd.cFileName);
while (ext>fd.cFileName && ext[-1]!=_T('.'))
--ext;
if (_tcsicmp(ext,_T("jpg")) && _tcsicmp(ext,_T("png")) &&
_tcsicmp(ext,_T("jpeg")))
continue;
if (first.IsEmpty())
first=fd.cFileName;
if (fNext) {
if (file.CompareNoCase(prev)==0) {
prev=fd.cFileName;
break;
}
} else {
if (file.CompareNoCase(fd.cFileName)==0)
break;
}
prev=fd.cFileName;
}
if (hFind!=INVALID_HANDLE_VALUE)
::FindClose(hFind);
if (!fFind) { // looped over all files and didnt find a match
if (fNext && file.CompareNoCase(prev)==0)
prev=first;
}
path.Delete(path.GetLength()-1); // remove last '*'
return prev.IsEmpty() ? prev : path+prev;
}
static TextFile *OpenNextImage(const CString& cur,bool fNext) {
for (CString next(GetNextFile(cur,fNext));!next.IsEmpty() && next!=cur;next=GetNextFile(next,fNext)) {
TextFile *tf=TextFile::Open(next);
if (tf)
return tf;
}
return NULL;
}
void CTView::OnUpdateBack(CCmdUI* pCmdUI) {
if (m_textfile->IsImage()) {
pCmdUI->Enable();
return;
}
pCmdUI->Enable(!m_History.pstack.IsEmpty() &&
m_History.stacktop!=m_History.pstack.GetHeadPosition());
#if POCKETPC
// tweak ok button
// when current view is a dict, and there are !dict items below
if (m_formatter->DocId()<0)
for (POSITION q=m_History.pstack.GetHeadPosition();q && q!=m_History.stacktop;)
if (m_History.pstack.GetNext(q).docid>=0) { // ok, enable
if (!m_Dict.okstate) {
ShowDoneButton(TRUE);
m_Dict.okstate=true;
}
return;
}
if (m_Dict.okstate) {
ShowDoneButton(FALSE);
m_Dict.okstate=false;
}
#endif
}
void CTView::OnBack() {
if (m_textfile->IsImage()) {
TextFile *tf=OpenNextImage(m_textfile->Name(),false);
if (tf) {
AfxGetMainWnd()->SetWindowText(FileName(tf->Name()));
SetFile(kilo::auto_ptr<TextFile>(tf));
}
return;
}
if (!m_History.pstack.IsEmpty() &&
m_History.stacktop!=m_History.pstack.GetHeadPosition())
{
FilePos cur=m_formatter->Top();
if (m_History.stacktop==NULL)
m_History.stacktop=m_History.pstack.GetTailPosition();
else
m_History.pstack.GetPrev(m_History.stacktop);
MoveAbs(m_History.pstack.GetAt(m_History.stacktop));
m_History.pstack.SetAt(m_History.stacktop,cur);
}
}
void CTView::OnNextSection() {
Bookmarks& bm=m_textfile->bmk();
FilePos cur=m_formatter->Bottom();
if (cur<m_formatter->Eof()) {
int index=bm.BFind(cur,Bookmarks::SNEXTCH);
if (index<bm.GetSize()) {
if (cur==bm.Ref(index) && index<bm.GetSize())
++index;
if (cur<bm.Ref(index)) {
PushPos();
EnsureVisible(bm.Ref(index));
}
}
}
}
void CTView::OnPrevSection() {
Bookmarks& bm=m_textfile->bmk();
FilePos cur=m_formatter->Top();
if (cur>FilePos()) {
int index=bm.BFind(cur,Bookmarks::SPREVCH);
if (index<bm.GetSize()) {
if (cur==bm.Ref(index) && index>0)
do --index; while (index>=0 && bm.Flags(index)&Bookmarks::BMK);
if (index<0)
OnStartFile();
else
if (bm.Ref(index)<cur) {
PushPos();
EnsureVisible(bm.Ref(index));
}
}
}
}
void CTView::DisplayBookmarkPopup(int index) {
Bookmarks& bm=m_textfile->bmk();
if (bm.Flags(index) & Bookmarks::BMK) {
POINT pt;
if (LookupPoint(bm.Ref(index),pt))
DisplayBookmarkPopup(pt,Unicode::ToWCbuf(bm.Text(index,m_textfile.get())));
}
m_BP.bmkidx=index;
}
void CTView::OnNextBm() {
Bookmarks& bm=m_textfile->bmk();
int index;
if (m_BP.bmkidx>=0 && m_BP.bmkidx<bm.GetSize()-1) {
index=m_BP.bmkidx+1;
} else {
if (m_formatter->AtEof())
return;
FilePos cur=m_formatter->Bottom();
index=bm.BFind(cur,Bookmarks::SNEXTANY);
if (index>=bm.GetSize())
return;
if (cur==bm.Ref(index) && index<bm.GetSize()-1)
++index;
if (cur>=bm.Ref(index))
return;
}
PushPos();
EnsureVisible(bm.Ref(index));
DisplayBookmarkPopup(index);
}
void CTView::OnPrevBm() {
Bookmarks& bm=m_textfile->bmk();
int index;
if (m_BP.bmkidx>0 && m_BP.bmkidx<bm.GetSize()) {
index=m_BP.bmkidx-1;
} else {
if (m_formatter->AtTop())
return;
FilePos cur=m_formatter->Top();
index=bm.BFind(cur,Bookmarks::SPREVANY);
if (index>=bm.GetSize())
return;
if (cur==bm.Ref(index) && index>0)
--index;
if (bm.Ref(index)>=cur)
return;
}
PushPos();
EnsureVisible(bm.Ref(index));
DisplayBookmarkPopup(index);
}
#if POCKETPC
static bool TryRunLingvo(const TCHAR *path,HWND hWnd) {
// construct shortcut name
CString pp(path);
if (pp.IsEmpty())
return false;
if (pp[pp.GetLength()-1]!=_T('\\'))
pp+=_T('\\');
pp+=_T("ABBYY Lingvo.lnk");
// extract filename from shortcut
CString exe;
TCHAR *cp=exe.GetBuffer(MAX_PATH);
if (!SHGetShortcutTarget(pp,cp,MAX_PATH))
return false;
exe.ReleaseBuffer();
// replace the executable with LingvoCE.exe
int p=exe.ReverseFind(_T('\\'));
int q=exe.ReverseFind(_T('/'));
if (p<q)
p=q;
exe.Delete(p+1,exe.GetLength()-p-1);
exe+=_T("LingvoCE.exe");
// strip leading quote if there is one
if (exe.GetLength()>0 && exe[0]==_T('"'))
exe.Delete(0);
// try to run it
PROCESS_INFORMATION pi;
if (!CreateProcess(exe,_T("-c"),NULL,NULL,FALSE,0,NULL,NULL,NULL,&pi))
return false;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
#endif
void CTView::LookupText(Buffer<wchar_t> text) {
InitDictName();
#ifdef _WIN32_WCE
if (m_Dict.curdict==_T(":SlovoEd")) {
// do a double copy to invoke slovoed resident module
CopyToClipboard(text,text.size(),m_hWnd);
Sleep(200);
CopyToClipboard(text,text.size(),m_hWnd);
m_Dict.lastdictlookup=text;
} else
#endif
if (m_Dict.curdict==_T(":Lingvo")) {
#if POCKETPC
CopyToClipboard(text,text.size(),m_hWnd);
// check if lingvo is already running
HANDLE hMutex = ::CreateMutex(0, 0, _T("Lingvo CE"));
DWORD dwError = ::GetLastError();
::CloseHandle(hMutex);
if(dwError != ERROR_ALREADY_EXISTS) {
TCHAR buffer[MAX_PATH];
// try to run it
if (!::SHGetSpecialFolderPath(m_hWnd,buffer,CSIDL_PROGRAMS,FALSE) ||
!TryRunLingvo(buffer,m_hWnd))
if (::SHGetSpecialFolderPath(m_hWnd,buffer,CSIDL_STARTMENU,FALSE))
TryRunLingvo(buffer,m_hWnd);
} else {
// send command to an existing window
HWND wnd = ::FindWindow(L"Afx:WLV_MainWindow100", 0);
if(wnd)
::PostMessage(wnd, WM_COMMAND, WM_USER + 400, 0);
}
#else
// use automation interface
#endif
m_Dict.lastdictlookup=text;
} else {
if (!OpenDict())
return;
FilePos wp;
// dict interface wants 0 terminated strings, so we create a copy here
Buffer<wchar_t> ztext(text.size()+1);
memcpy(ztext,text,text.size()*sizeof(wchar_t));
ztext[text.size()]=L'\0';
if (m_textfile->LookupDict(ztext,wp)) {
PushPos();
MoveAbs(wp);
m_Dict.lastdictlookup=text;
}
}
}
void CTView::HandleMouseDown(CPoint point) {
if (m_BP.visible) {
HideBookmarkPopup();
return;
}
POINT pt;
FilePos pos;
pt.x=point.x;
pt.y=point.y;
// transform point into virtual coords
System2Window(pt,m_Window.cli);
// check if we are in a progress bar
if (pt.y>=m_Window.rheight-PROGRESS_C && pt.y<m_Window.rheight) {
if (pt.x<PROGRESS_M+PROGRESS_A) { // prev section
OnPrevSection();
} else if (pt.x>=m_Window.rwidth-PROGRESS_M-PROGRESS_A-m_Window.pb_width &&
pt.x<m_Window.rwidth-m_Window.pb_width)
{ // next section
OnNextSection();
} else if (pt.x<m_Window.rwidth-PROGRESS_M-PROGRESS_A-m_Window.pb_width) { // move absolute
PushPos();
int charpos=MulDivS(
m_textfile->GetTotalLength(m_formatter->Top().docid),
pt.x-PROGRESS_M-PROGRESS_A,
m_Window.rwidth-2*PROGRESS_M-2*PROGRESS_A-m_Window.pb_width
);
int para=m_textfile->LookupParagraph(m_formatter->DocId(),charpos);
EnsureVisible(
FilePos(
para,
charpos-m_textfile->GetPStart(m_formatter->DocId(),para),
m_formatter->DocId()
)
);
} else { // right part, back in dict mode
if (m_formatter->DocId()<0)
OnBack();
}
return;
}
if (LookupAddr(pt,pos)) {
// check if there is a bookmark nearby
int bmk=m_textfile->bmk().BFind(pos,Bookmarks::SPREVBMK);
if (bmk>=0) {
FilePos bp(m_textfile->bmk().Ref(bmk));
if (bp.docid==pos.docid && bp.para==pos.para && bp.off>=pos.off-2) {
DisplayBookmarkPopup(pt,Unicode::ToWCbuf(m_textfile->bmk().Text(bmk,m_textfile.get())));
return;
}
}
// check if it is a link
Paragraph p(m_textfile->GetParagraph(pos.docid,pos.para));
for (int link=0;link<p.links.size();++link)
if (p.links[link].off<=(DWORD)pos.off && p.links[link].off+p.links[link].len>(DWORD)pos.off)
{
// found a link
// for now only local links are supported
if (p.links[link].target[0]==_T('#')) {
FilePos dest;
if (m_textfile->LookupReference(p.links[link].target+1,dest)) {
PushPos();
MoveAbs(dest);
} else
goto beep;
} else
beep:
MessageBeep(MB_OK);
return;
}
// lookup a word in the dictionary then
InitDictName();
if (m_Dict.curdict!=_T(":Disable")) {
int start,end;
for (start=pos.off+1;start>0 && (iswalpha(p.str[start-1]) ||
p.str[start-1]==L'\'' ||
p.str[start-1]==L'-');--start) ;
for (end=pos.off+1;end<p.str.size() && (iswalpha(p.str[end]) ||
p.str[end]==L'\'' || p.str[end]==L'-');++end) ;
if (start!=end) {
LookupText(Buffer<wchar_t>(p.str+start,end-start));
return;
}
}
}
// didn't have an action yet, interpret as movement
if (m_Dict.curdict==_T(":Disable")) {
if (pt.y<(m_Window.rheight-PROGRESS_C)/2)
Move(mBack,mPage);
else
Move(mFwd,mPage);
}
}
void CTView::OnLButtonDblClk(UINT nFlags, CPoint point) {
FilePos pos;
System2Window(point,m_Window.cli);
if (point.y<m_Window.rheight-m_Window.progress_height)
CTVApp::QueueCmd(ID_FULLSCREEN);
}
void CTView::MoveAbs(FilePos pos) {
CFDC fdc(m_hWnd);
m_formatter->FormatFwd(fdc,pos);
QueueRepaint();
}
void CTView::EnsureVisible(FilePos pos) {
CFDC fdc(m_hWnd);
if (m_formatter->EnsureVisible(fdc,pos))
QueueRepaint();
}
void CTView::OnLookupSel() {
InitDictName();
if (m_Dict.curdict==_T(":Disable"))
return;
Buffer<wchar_t> sel;
if (!GetSelText(sel))
return;
LookupText(sel);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -