📄 textfile.cpp
字号:
/*
* Copyright (c) 2001,2002,2003 Mike Matsnev. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Absolutely no warranty of function or purpose is made by the author
* Mike Matsnev.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: TextFile.cpp,v 1.45.2.5 2004/07/07 12:04:47 mike Exp $
*
*/
#include <afxwin.h>
#include <afxtempl.h>
#include "resource.h"
#include "TextFile.h"
#include "ZipFile.h"
#include "PDBFile.h"
#include "TCRFile.h"
#include "TextViewNG.h"
#include "ProgressDlg.h"
#include "Unicode.h"
#include "config.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
TextFile::TextFile(RFile *fp,const CString& name) :
m_name(name), m_bookmarks(name), m_dictp(NULL)
{
m_format=m_bookmarks.Format();
m_enc=m_bookmarks.Encoding();
if (m_format>=TextParser::GetNumFormats())
m_format=-1;
if (m_enc>=Unicode::GetNumCodePages())
m_enc=-1;
// create a buffered file for it
m_fp=new CBufFile(kilo::auto_ptr<RFile>(fp));
// and initialize parser
m_bookmarks.LoadFromRegistry();
SetFormatEncodingImp(m_format,m_enc,&m_bookmarks);
m_bookmarks.NormalizeLevels();
}
void TextFile::SaveBookmarks(FilePos cur) {
m_bookmarks.SetStartPos(cur);
if (m_bookmarks.SaveInfo())
m_bookmarks.SaveToRegistry();
}
void TextFile::SetFormatEncodingImp(int format,int enc,Bookmarks *bmk) {
TextParser *np=NULL;
CProgressDlg dlg(Name(),AfxGetMainWnd());
dlg.SetMax(m_fp->size());
if (format<0) {
m_fp->seek(0);
int nf=TextParser::DetectFormat(m_fp.get());
np=TextParser::Create(&dlg,m_fp.get(),nf,enc,bmk);
} else {
if (m_tp.get() && format==m_tp->GetFormat()) {
m_format=format;
return;
}
np=TextParser::Create(&dlg,m_fp.get(),format,enc,bmk);
}
if (np==NULL)
return;
m_tp.reset(np);
m_format=format;
m_enc=enc;
m_bookmarks.SetFormat(m_format);
m_bookmarks.SetEncoding(m_enc);
}
void TextFile::Reparse() {
TextParser *np=NULL;
CProgressDlg dlg(Name(),AfxGetMainWnd());
dlg.SetMax(m_fp->size());
int fmt=m_format<0 ? m_tp->GetFormat() : m_format;
np=TextParser::Create(&dlg,m_fp.get(),fmt,m_enc,NULL);
if (np==NULL)
return;
m_tp.reset(np);
}
const TCHAR *TextFile::GetEncodingName(int enc) {
return enc<0 ? _T("Auto") : Unicode::GetCodePageName(enc);
}
const TCHAR *TextFile::GetFormatName(int format) {
return format<0 ? _T("Auto") : TextParser::GetFormatName(format);
}
class DummyRFile: public RFile {
public:
DummyRFile() : RFile(CString()) { }
// generic file operations
virtual DWORD size() { return 0; }
virtual DWORD read(void *buf) { return 0; }
virtual void seek(DWORD pos) { }
};
TextFile *TextFile::Open(const CString& filename) {
kilo::auto_ptr<RFile> fp;
CString cur(filename);
bool zip=false;
RFile *rf=NULL;
#if !defined(_WIN32_WCE)
CString FILENAME;
// normalize filename
TCHAR buffer[MAX_PATH],*filepart;
DWORD nc=GetFullPathName(cur,sizeof(buffer)/sizeof(TCHAR),buffer,&filepart);
if (nc>0 && nc<sizeof(buffer)/sizeof(TCHAR))
FILENAME=buffer;
else
FILENAME=filename;
#else
#define FILENAME filename
if (filename==_T("NUL")) {
rf=new DummyRFile();
goto ok;
}
#endif
for (;;) {
fp = new RFile(cur);
if (fp->Reopen()) {
if (zip) { // try to decompress fp, if this is not the first try
ZipFile *zf=new ZipFile(cur);
if (!zf->ReadZip()) {
delete zf;
return NULL;
}
// good, now try to find the file in zip
cur=filename.Mid(cur.GetLength());
int spos=cur.ReverseFind(_T('\\'));
if (spos>=0) {
if (spos>0 && !zf->SetDir(cur.Left(spos))) { // no such dir
delete zf;
return NULL;
}
cur=cur.Mid(spos+1);
}
if (!zf->Open(cur)) { // no such file in zip
delete zf;
return NULL;
}
rf=zf;
} else {
if (PDBFile::IsPDB(fp.get()))
rf=new PDBFile(cur);
else if (TCRFile::IsTCR(fp.get()))
rf=new TCRFile(cur);
else
rf=fp.release();
}
goto ok;
} else { // unable to open, chop last piece
int spos=cur.ReverseFind(_T('\\'));
if (spos<=0) // we failed
break;
cur.Delete(spos,cur.GetLength()-spos);
}
zip=true;
}
// when we get here we failed to open any prefix of filename
return NULL;
ok:{
TextFile *tf;
TRY {
tf=new TextFile(rf,FILENAME);
} CATCH_ALL(e) {
tf=NULL;
}
END_CATCH_ALL
if (tf && !tf->Ok()) {
delete tf;
tf=NULL;
}
return tf;
}
}
// these tricks are needed to distinguish between a true end of paragraph
// and position 0, which is difficult when length is also 0
int TextFile::GetPLength(int docid,int para) {
int pl=Parser(docid)->GetPLength(docid,para);
return pl==0 ? 1 : pl;
}
Paragraph TextFile::GetParagraph(int docid,int para) {
Paragraph p(Parser(docid)->GetParagraph(docid,para));
if (p.len==0) {
p.len=1;
p.str=Buffer<wchar_t>(1); p.str[0]=_T(' ');
p.cflags=Buffer<Attr>(1);
p.cflags[0].wa=0;
}
// map ipa extensions to alt font
for (int j=0;j<p.len;++j)
if (p.str[j]>=0x250 && p.str[j]<0x2b0)
p.cflags[j].xfont=1;
return p;
}
bool TextFile::LookupDict(const wchar_t *name,FilePos& dest) {
if (m_dictp && m_dictp->LookupReference(name,dest)) {
dest.docid=-1;
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -