⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bookmarks.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * 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: Bookmarks.cpp,v 1.42.2.6 2005/06/18 19:44:12 mike Exp $
 * 
 */

#include <afxwin.h>
#include <afxtempl.h>

#include "config.h"
#include "ptr.h"
#include "FilePos.h"
#include "Bookmarks.h"
#include "TextViewNG.h"
#include "Unicode.h"
#include "TextFile.h"

struct Goodch {
  static bool isgoodch(TCHAR ch) { return (ch>=_T('0') && ch<=_T('9')) || (ch>=_T('a') && ch<=_T('z')) || (ch>=_T('A') && ch<=_T('Z')) || ch==_T('.') || ch==_T('-') || ch==_T('_') || ch==_T(' '); }
};
struct Goodch2 {
  static bool isgoodch(TCHAR ch) { return ch!=_T('%') && ch!=_T('/') && ch!=_T('\\'); }
};
struct Goodch3 {
  static bool isgoodch(TCHAR ch) { return ch!=_T('%') && ch!=_T('\r') && ch!=_T('\n'); }
};

template<class T>
static CString	param_escape(const CString& str) {
  int	  rlen;
  int	  i;
  CString ret;
  TCHAR	  *cp;

  for (i=rlen=0;i<str.GetLength();++i)
    if (T::isgoodch(str[i]))
      ++rlen;
    else
      rlen+=5;
  cp=ret.GetBuffer(rlen);
  for (i=0;i<str.GetLength();++i)
    if (T::isgoodch(str[i]))
      *cp++=str[i];
    else {
      _stprintf(cp,_T("%%%04X"),((unsigned)str[i])&0xffff);
      cp+=5;
    }
  ret.ReleaseBuffer(rlen);
  return ret;
}

#define	escape(x)   param_escape<Goodch>(x)
#define	escape2(x)  param_escape<Goodch2>(x)
#define	escape3(x)  param_escape<Goodch3>(x)

static CString	unescape(const CString& str) {
  int	  rlen;
  int	  i,j,n;
  CString ret;
  TCHAR	  *cp;

  for (i=rlen=0;i<str.GetLength();++i) {
    if (str[i]==_T('%')) {
      if (i+4<str.GetLength())
	i+=4;
      else
	break;
    }
    ++rlen;
  }
  cp=ret.GetBuffer(rlen);
  for (i=0;i<str.GetLength();++i) {
    if (str[i]==_T('%')) {
      if (i+4>=str.GetLength())
	break;
      for (j=1+i,n=0;j<5+i;++j) {
	n<<=4;
	if (str[j]>=_T('0') && str[j]<=_T('9'))
	  n+=str[j]-_T('0');
	else if (str[j]>=_T('A') && str[j]<=_T('F'))
	  n+=str[j]-_T('A')+10;
	else if (str[j]>=_T('a') && str[j]<=_T('f'))
	  n+=str[j]-_T('a')+10;
      }
      *cp++=n==0 ? _T(' ') : n;
      i+=4;
    } else
      *cp++=str[i];
  }
  ret.ReleaseBuffer(rlen);
  return ret;
}

Bookmarks::Bookmarks(const CString& filename) : m_filename(filename),
  m_shortname(filename), m_changed(true), m_topbmk(0), m_ubmk(0)
{
  // extract filename
  int	last=max(m_shortname.ReverseFind(_T('\\')),m_shortname.ReverseFind(_T('/')));
  m_shortname.Delete(0,last+1);
  // find info in registry
  CString info=AfxGetApp()->GetProfileString(_T("Bookmarks"),escape2(m_shortname));
  DWORD	dummy;
  if (!info.GetLength() || _stscanf(info,_T("%d,%d,%u,%u"),
				    &m_format,&m_encoding,&dummy,&dummy)!=4)
  {
    m_format=-1;
    m_encoding=CTVApp::GetInt(_T("DefEncoding"),-1);
    m_startpos.off=m_startpos.para=0;
  }
}

Bookmarks::~Bookmarks() {
  SaveInfo();
}

CString	Bookmarks::Text(int idx,TextFile *parser) {
  if (m_bmk[idx].flags & BMK) {
    // return changed text if possible
    if (m_bmk[idx].flags & BMCHG && m_bmk[idx].tmp)
      return *m_bmk[idx].tmp;
    return m_bmk[idx].text;
  }
  if (m_bmk[idx].text.GetLength()>0)
    return m_bmk[idx].text;
  FilePos p(m_bmk[idx].text_ref);
  if (p.off==0 || !parser)
    return CString();
  // ok, here we extract the bookmark from the file
  CString ret;
  int	  ps=p.para;
  int	  pe=p.para+p.off;
  while (ps<pe) {
    if (p.para!=ps)
      ret+=_T(" ");
    ret+=Unicode::ToCS(parser->GetParagraph(p.docid,ps).str);
    ++ps;
  }
  return ret;
}

int  Bookmarks::AddImp(int para_start,int para_count,int docid,const CString *text,
		       FilePos pos,DWORD flags,int level)
{
  m_changed=true;
  BE	be;
  if (text)
    be.text=*text;
  be.ref=pos;
  be.text_ref.para=para_start;
  be.text_ref.off=para_count;
  be.text_ref.docid=docid;
  ASSERT(docid>=0);
  be.flags=flags;
  be.level=level;
  int index=BFind(pos,SNEXTICH);
  if (index>=m_bmk.GetSize())
    m_bmk.Add(be);
  else
    m_bmk.InsertAt(index,be);
  if (flags&BMK)
    ++m_topbmk,++m_ubmk;
  else if (level==0)
    ++m_topbmk;
  return index;
}

void  Bookmarks::Remove(int index) {
  Check(index);
  if (m_bmk[index].flags&BMK)
    m_bmk[index].flags|=BMDEL;
}

void  Bookmarks::Change(int index,const CString& text) {
  Check(index);
  if (m_bmk[index].flags&BMK) {
    if (m_bmk[index].flags&BMCHG)
      *m_bmk[index].tmp=text;
    else
      m_bmk[index].tmp=new CString(text);
    m_bmk[index].flags|=BMCHG;
  }
}

int  Bookmarks::Commit(int cidx) {
  for (int i=0;i<m_bmk.GetSize();) {
    if (m_bmk[i].flags&BMCHG) {
      m_changed = true;
      m_bmk[i].text=*m_bmk[i].tmp;
      delete m_bmk[i].tmp;
      m_bmk[i].flags&=~BMCHG;
      m_bmk[i].flags|=BMNEW;
    }
    if (m_bmk[i].flags&BMDEL) {
      m_changed = true;
      m_bmk.RemoveAt(i);
      if (cidx>i)
	--cidx;
      --m_topbmk;
      --m_ubmk;
    } else
      ++i;
  }
  return cidx;
}

void  Bookmarks::Rollback() {
  for (int i=0;i<m_bmk.GetSize();++i) {
    if (m_bmk[i].flags&BMCHG)
      delete m_bmk[i].tmp;
    m_bmk[i].flags&=~(BMCHG|BMDEL);
  }
}

void  Bookmarks::SaveToRegistry() {
  if (m_shortname==_T("NUL"))
    return;
  HKEY	  hBmk=AfxGetApp()->GetSectionKey(_T("Bookmarks"));
  if (!hBmk)
    return;
  CString sect(escape2(m_shortname));
  RegDeleteKey(hBmk,sect);
  HKEY	res;
  DWORD	disp;
  CString name,value;
  if (RegCreateKeyEx(hBmk,sect,0,REG_NONE,0,HR_REG_PERM,NULL,&res,&disp)==ERROR_SUCCESS) {
    value.Format(_T("%d,%d,%d"),m_startpos.para,m_startpos.off,m_startpos.docid);
    RegSetValueEx(res,NULL,0,REG_SZ,(LPBYTE)(const TCHAR *)value,
      (value.GetLength()+1)*sizeof(TCHAR));
    int	n=0;
    for (int i=0;i<m_bmk.GetSize();++i) {
      if (!(m_bmk[i].flags&BMK))
	continue;
      name.Format(_T("%d"),n);
      value.Format(_T("%d,%d,%d,%s"),m_bmk[i].ref.para,m_bmk[i].ref.off,
	m_bmk[i].ref.docid,(const TCHAR *)m_bmk[i].text);
      RegSetValueEx(res,name,0,REG_SZ,(LPBYTE)(const TCHAR *)value,
	(value.GetLength()+1)*sizeof(TCHAR));
      ++n;
    }
    RegCloseKey(res);
  }
  RegCloseKey(hBmk);
}

bool  Bookmarks::SaveInfo() {
  if (m_changed) {
    if (m_shortname==_T("NUL"))
      return false;
    SYSTEMTIME	tm;
    FILETIME	ftm;
    GetLocalTime(&tm);
    SystemTimeToFileTime(&tm,&ftm);
    CString	info;
    info.Format(_T("%d,%d,%u,%u,%s"),m_format,m_encoding,
      ftm.dwLowDateTime,ftm.dwHighDateTime,m_filename);
    AfxGetApp()->WriteProfileString(_T("Bookmarks"),escape2(m_shortname),info);
    m_changed=false;
    return true;
  }
  return false;
}

void  Bookmarks::LoadFromRegistry() {
  HKEY	  hBmk=AfxGetApp()->GetSectionKey(_T("Bookmarks"));
  if (!hBmk)
    return;
  CString sect(escape2(m_shortname));
  HKEY	res;
  CString name,value;
  if (RegOpenKeyEx(hBmk,sect,0,HR_REG_PERM,&res)==ERROR_SUCCESS) {
    TCHAR     buf[4096];
    DWORD     type,len=sizeof(buf);
    if (RegQueryValueEx(res,NULL,0,&type,(LPBYTE)buf,&len)==ERROR_SUCCESS && type==REG_SZ) {
      FilePos	pp;
      if (_stscanf(buf,_T("%d,%d,%d"),&pp.para,&pp.off,&pp.docid)>=2)
	SetStartPos(pp);
    }
    for (int i=0;;++i) {
      name.Format(_T("%d"),i);
      len=sizeof(buf);
      if (RegQueryValueEx(res,name,0,&type,(LPBYTE)buf,&len)==ERROR_SUCCESS && type==REG_SZ) {
	FilePos	pp;
	TCHAR	*cp=value.GetBuffer(sizeof(buf)/sizeof(TCHAR));
	if (_stscanf(buf,_T("%d,%d,%d,%[^\001]"),&pp.para,&pp.off,&pp.docid,cp)==4 ||
	    _stscanf(buf,_T("%d,%d,%[^\001]"),&pp.para,&pp.off,cp)==3)
	{
	  value.ReleaseBuffer();
	  Add(value,pp);
	} else
	  value.ReleaseBuffer(0);
      } else
	break;
    }
    RegCloseKey(res);
  }
  RegCloseKey(hBmk);
}

CString	Bookmarks::find_last_file() {
  HKEY	    hKey=AfxGetApp()->GetSectionKey(_T("Bookmarks"));
  if (!hKey)
    return CString();
  CString   filename,tmp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -