📄 tview.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: TView.cpp,v 1.164.2.65 2005/09/28 15:44:21 mike Exp $
*
*/
#include <afxcmn.h>
#include <afxtempl.h>
#include <afxext.h>
#include <shlobj.h>
#include <shellapi.h>
#include <mmsystem.h>
#include "config.h"
#include "resource.h"
#include "ptr.h"
#include "FilePos.h"
#include "Colors.h"
#include "OptionsDialog.h"
#include "FileFormatDialog.h"
#include "InputBox.h"
#include "ColorSelector.h"
#include "XMLParser.h"
#include "StylesDlg.h"
#include "MiscOptDlg.h"
#include "DictSetupDlg.h"
#include "Keys.h"
#include "Unicode.h"
#include "TextFile.h"
#include "TextFormatter.h"
#include "TextViewNG.h"
#include "TVFrame.h"
#include "Rotate.h"
#include "TView.h"
#include "Bookmarks.h"
#include "ContentsDlg.h"
#include "Dictionary.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef CSIDL_STARTMENU
#define CSIDL_STARTMENU 0x000b
#endif
#define DO_CLIP 0
#define PROGRESS_M 3
#define PROGRESS_A 11
#define PROGRESS_C 10
#define PROGRESS_F 6
#define FRAME_SIZE 3
#ifdef _WIN32_WCE
// can overflow, so take care
static inline int MulDivS(int x,int y,int z) {
__int64 m=(__int64)x*y;
return (int)(m/z);
}
#endif
// colors
ColorItem g_colors[]={
{ _T("Text"), RGB(0,0,0) },
{ _T("Highlight 1") , RGB(0,0,192) },
{ _T("Highlight 2"), RGB(129,0,0) },
{ _T("Highlight 3"), RGB(192,0,192) },
{ _T("Highlight 4"), RGB(0,112,0) },
{ _T("Highlight 5"), RGB(0,112,112) },
{ _T("Highlight 6"), RGB(0,192,0) },
{ _T("Highlight 7"), RGB(128,128,128) },
{ _T("Background"), RGB(255,255,255) },
{ _T("Highlighted Background"), RGB(16,192,255) },
{ _T("Gauge"), RGB(150,150,150) },
{ _T("Section Tick"), RGB(0,0,0) },
{ _T("Bookmark Tick"), RGB(255,0,0) },
{ _T("User input color"), RGB(0,128,0) },
{ _T("User input background"), RGB(203,224,199) },
{ _T("Autoscroll underline"), RGB(0,0,0) },
{ NULL }
};
int g_color_profile;
enum {
TM_SAVEINFO=1,
TM_USERTEXT,
TM_AS,
TM_PD,
};
enum {
MAXUSERINPUTWIDTH=400,
USERINPUTFLAGS=Attr::BOLD,
USERINPUTSIZE=3
};
COLORREF CTView::v_C_BG() { return m_textfile->IsImage() ? RGB(0,0,0) : C_BG; }
/////////////////////////////////////////////////////////////////////////////
// CTView
CTView::CTView()
{
LoadColors();
// read other params
CFDC::SetCacheSize(CTVApp::GetInt(_T("FontCacheSize"),6));
SetRotAngle(m_TextDisp.angle);
}
// colors support
void SaveColors() {
AfxGetApp()->WriteProfileInt(_T("Colors"),_T("Profile"),g_color_profile);
if (g_color_profile != 0) {
CString name;
for (int i=0;g_colors[i].name;++i) {
name.Format(_T("%s_%d"),g_colors[i].name,g_color_profile);
AfxGetApp()->WriteProfileInt(_T("Colors"),name,g_colors[i].value);
}
} else
for (int i=0;g_colors[i].name;++i)
AfxGetApp()->WriteProfileInt(_T("Colors"),g_colors[i].name,
g_colors[i].value);
}
void LoadColors() {
// read color profile id
g_color_profile = AfxGetApp()->GetProfileInt(_T("Colors"),_T("Profile"),0);
// read colors
if (g_color_profile != 0) {
CString name;
for (int i=0;g_colors[i].name;++i) {
name.Format(_T("%s_%d"),g_colors[i].name,g_color_profile);
g_colors[i].value=AfxGetApp()->GetProfileInt(_T("Colors"),
name,g_colors[i].value);
}
} else
for (int i=0;g_colors[i].name;++i)
g_colors[i].value=AfxGetApp()->GetProfileInt(_T("Colors"),
g_colors[i].name,g_colors[i].value);
}
bool NextColorProfile() {
HKEY hKey = AfxGetApp()->GetSectionKey(_T("Colors"));
if (hKey == NULL)
return false;
int next_id = 0;
bool found = false;
TCHAR name[16];
for (DWORD idx = 0; ; ++idx) {
DWORD namesize = sizeof(name)/sizeof(name[0]);
DWORD type;
if (RegEnumValue(hKey,idx,name,&namesize,0,&type,NULL,NULL) != ERROR_SUCCESS)
break;
int id;
if (_stscanf(name,_T("%d"),&id) != 1)
continue;
if (found) {
next_id = id;
break;
}
if (g_color_profile == id)
found = true;
if (g_color_profile == 0) {
next_id = id;
break;
}
}
RegCloseKey(hKey);
if (next_id == g_color_profile)
return false;
AfxGetApp()->WriteProfileInt(_T("Colors"),_T("Profile"),next_id);
LoadColors();
return true;
}
void AddColorProfileNames(void *vmenu,int startpos) {
CMenu *menu = (CMenu *)vmenu;
menu->InsertMenu(startpos,MF_BYPOSITION|MF_STRING,COLORS_BASE,_T("Default"));
if (0 == g_color_profile)
menu->CheckMenuRadioItem(startpos,startpos,startpos,MF_BYPOSITION);
++startpos;
HKEY hKey = AfxGetApp()->GetSectionKey(_T("Colors"));
if (hKey == NULL)
return;
TCHAR name[16];
for (DWORD idx = 0; ; ++idx) {
DWORD namesize = sizeof(name)/sizeof(name[0]);
DWORD type;
if (RegEnumValue(hKey,idx,name,&namesize,0,&type,NULL,NULL) != ERROR_SUCCESS)
break;
int id;
if (_stscanf(name,_T("%d"),&id) != 1)
continue;
TCHAR data[64];
DWORD dsize = sizeof(data);
if (RegQueryValueEx(hKey,name,0,&type,(BYTE*)data,&dsize) == ERROR_SUCCESS && type == REG_SZ) {
menu->InsertMenu(startpos,MF_BYPOSITION|MF_STRING,COLORS_BASE + id,data);
if (id == g_color_profile)
menu->CheckMenuRadioItem(startpos,startpos,startpos,MF_BYPOSITION);
++startpos;
}
}
RegCloseKey(hKey);
}
void CTView::xx_Window::LoadSettings() {
columns=CTVApp::GetInt(_T("Columns"),DEF_COLUMNS);
rotbuttons=CTVApp::GetInt(_T("RotateButtons"),DEF_ROTB)!=0;
autorepeatlimit=CTVApp::GetInt(_T("AutoRepeatLimit"),DEF_AUTOREPEATLIMIT)!=0;
showprog=CTVApp::GetInt(_T("ShowProgress"),DEF_SHOWPROGRESS)!=0;
pb.flags=CTVApp::GetInt(_T("ProgressBar"),DEF_PROGRESSBAR);
if (columns<1 || columns>4)
columns=1;
}
void CTView::xx_Window::SaveSettings() {
CTVApp::SetInt(_T("ShowProgress"),showprog);
CTVApp::SetInt(_T("ProgressBar"),pb.flags);
CTVApp::SetInt(_T("Columns"),columns);
CTVApp::SetInt(_T("RotateButtons"),rotbuttons);
CTVApp::SetInt(_T("AutoRepeatLimit"),autorepeatlimit);
}
void CTView::xx_TextDisp::LoadSettings() {
angle=CTVApp::GetInt(_T("Orientation"),DEF_ORIENTATION);
margin_width=CTVApp::GetInt(_T("Margins"),DEF_MARGINS);
justify=CTVApp::GetInt(_T("Justify"),DEF_JUSTIFY)!=0;
hyphenate=CTVApp::GetInt(_T("Hyphenate"),DEF_HYPHENATE)!=0;
SetFont(CTVApp::GetStr(_T("FontFace"),DEF_FACE),
CTVApp::GetInt(_T("FontBold"),DEF_BOLD)!=0,
CTVApp::GetInt(_T("FontSize"),DEF_SIZE),
CTVApp::GetInt(_T("FontCleartype"),DEF_CLEARTYPE));
}
void CTView::xx_TextDisp::SaveSettings()
{
CTVApp::SetStr(_T("FontFace"),fontface);
CTVApp::SetInt(_T("FontSize"),fontsize);
CTVApp::SetInt(_T("FontBold"),bold);
CTVApp::SetInt(_T("FontCleartype"),cleartype);
CTVApp::SetInt(_T("Orientation"),angle);
CTVApp::SetInt(_T("Margins"),margin_width);
CTVApp::SetInt(_T("Justify"),justify);
CTVApp::SetInt(_T("Hyphenate"),hyphenate);
}
void CTView::xx_TextDisp::SetFont(const CString &face, bool pbold,
int size, int pct)
{
bold=pbold;
cleartype=pct;
fontface=face;
fontsize=size;
SetDefFont();
}
void CTView::xx_TextDisp::SetDefFont()
{
CFDC::SetDefaultFont(fontface,fontsize,bold,cleartype,angle);
}
void CTView::xx_AS::LoadSettings() {
delay=CTVApp::GetInt(_T("AutoScrollDelay"),DEF_AS_DELAY);
}
void CTView::xx_AS::SaveSettings() {
CTVApp::SetInt(_T("AutoScrollDelay"),delay);
}
CTView::~CTView() {
SaveInfo();
Bookmarks::CleanupRegistry(CTVApp::GetInt(_T("NumBookmarks"),DEF_BOOKMARKS));
}
void CTView::SaveInfo() {
if (m_textfile.get() && m_formatter.get())
m_textfile->SaveBookmarks(CurFilePos());
}
void CTView::Init() {
GetClientRect(&m_Window.cli);
CalcSizes();
Keys::SetWindow(m_hWnd);
m_timer=SetTimer(TM_SAVEINFO,DEF_SAVEINTERVAL,0);
StartWindowPDTimer();
// initialize progress bar height
CFDC dc(m_hWnd);
dc.SelectFontAbs(MulDivS(PROGRESS_F, GetDeviceCaps(dc.DC(), LOGPIXELSY), 72),CFDC::FORCENORMALWEIGHT|CFDC::FORCETAHOMA,true);
int dummy;
dc.GetFontSize(m_Window.progress_height,dummy);
m_Window.progress_height-=2; // XXX no inter-line spacing
}
void CTView::SetFile(kilo::auto_ptr<TextFile> tfile) {
if (!tfile.get())
return;
SaveInfo();
m_textfile=tfile;
m_Window.progoverride=!m_textfile->IsImage();
m_formatter=new TextFormatter(m_textfile.get());
m_formatter->SetJustified(m_TextDisp.justify);
m_formatter->SetHyphenate(m_TextDisp.hyphenate);
m_formatter->SetTop(m_textfile->bmk().StartPos());
m_Search.matchpos=m_formatter->Eof();
m_History.Clear();
SaveInfo();
// and format the page
CalcSizes();
QueueRepaint();
StartWindowPDTimer();
}
BEGIN_MESSAGE_MAP(CTView,CWnd )
//{{AFX_MSG_MAP(CTView)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_KEYDOWN()
ON_WM_ERASEBKGND()
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_UPDATE_COMMAND_UI(ID_DISP_OPTIONS, OnUpdateOptions)
ON_COMMAND(ID_DISP_OPTIONS, OnOptions)
ON_UPDATE_COMMAND_UI(ID_FILEFORMAT, OnUpdateFileformat)
ON_COMMAND(ID_FILEFORMAT, OnFileformat)
ON_UPDATE_COMMAND_UI(ID_BACK, OnUpdateBack)
ON_COMMAND(ID_BACK, OnBack)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_DICT_SETUP, OnDictSetup)
ON_UPDATE_COMMAND_UI(ID_DICT_SETUP, OnUpdateDictSetup)
ON_UPDATE_COMMAND_UI(ID_FIND, OnUpdateFind)
ON_COMMAND(ID_FIND, OnFind)
ON_COMMAND(ID_FINDNEXT, OnFindnext)
ON_UPDATE_COMMAND_UI(ID_FINDNEXT, OnUpdateFindnext)
ON_UPDATE_COMMAND_UI(ID_COLORS, OnUpdateColors)
ON_COMMAND(ID_COLORS, OnColors)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_ADD_BMK, OnAddBmk)
ON_UPDATE_COMMAND_UI(ID_ADD_BMK, OnUpdateAddBmk)
ON_COMMAND(ID_BOOKMARKS, OnBookmarks)
ON_UPDATE_COMMAND_UI(ID_BOOKMARKS, OnUpdateBookmarks)
ON_COMMAND(ID_LINE_UP, OnLineUp)
ON_COMMAND(ID_LINE_DOWN, OnLineDown)
ON_COMMAND(ID_PAGE_UP, OnPageUp)
ON_COMMAND(ID_PAGE_DOWN, OnPageDown)
ON_COMMAND(ID_START_OF_FILE, OnStartFile)
ON_COMMAND(ID_END_OF_FILE, OnEndFile)
ON_COMMAND(ID_KEYS, OnKeys)
ON_UPDATE_COMMAND_UI(ID_KEYS, OnUpdateKeys)
ON_WM_DESTROY()
ON_COMMAND(ID_STYLES, OnStyles)
ON_UPDATE_COMMAND_UI(ID_STYLES, OnUpdateStyles)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_MISCOPT, OnMiscopt)
ON_UPDATE_COMMAND_UI(ID_MISCOPT, OnUpdateMiscopt)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_COMMAND(ID_ROTATE,OnRotate)
ON_WM_TIMER()
ON_COMMAND(ID_NEXTCH,OnNextSection)
ON_COMMAND(ID_PREVCH,OnPrevSection)
ON_COMMAND(ID_NEXTBM,OnNextBm)
ON_COMMAND(ID_PREVBM,OnPrevBm)
ON_WM_CHAR()
ON_COMMAND(ID_FORWARD, OnForward)
ON_UPDATE_COMMAND_UI(ID_FORWARD, OnUpdateForward)
ON_COMMAND(ID_LOOKUP_SEL,OnLookupSel)
ON_COMMAND(ID_DO_FIND, DoFind)
ON_COMMAND(IDOK,OnOK)
ON_WM_KILLFOCUS()
ON_WM_SETFOCUS()
ON_COMMAND(ID_AS_STOP,StopAS)
ON_COMMAND(ID_AS_START,StartAS)
ON_COMMAND(ID_AS_SLOWER,SlowerAS)
ON_COMMAND(ID_AS_FASTER,FasterAS)
ON_COMMAND(ID_AS_SLOWER_FINE,SlowerASFine)
ON_COMMAND(ID_AS_FASTER_FINE,FasterASFine)
ON_COMMAND(ID_AS_TOGGLE,ToggleAS)
ON_UPDATE_COMMAND_UI(ID_PB_TOGGLE, OnUpdateTogglePB)
ON_COMMAND(ID_PB_TOGGLE, OnTogglePB)
ON_UPDATE_COMMAND_UI(ID_PB_POS, OnUpdateTogglePBPos)
ON_COMMAND(ID_PB_POS, OnTogglePBPos)
ON_UPDATE_COMMAND_UI(ID_PB_CHAPTER, OnUpdateTogglePBChapter)
ON_COMMAND(ID_PB_CHAPTER, OnTogglePBChapter)
ON_UPDATE_COMMAND_UI(ID_PB_TOP, OnUpdateTogglePBTop)
ON_COMMAND(ID_PB_TOP, OnTogglePBTop)
ON_UPDATE_COMMAND_UI(ID_PB_TIME, OnUpdateTogglePBTime)
ON_COMMAND(ID_PB_TIME, OnTogglePBTime)
ON_UPDATE_COMMAND_UI(ID_PB_AS, OnUpdateTogglePBAS)
ON_COMMAND(ID_PB_AS, OnTogglePBAS)
ON_UPDATE_COMMAND_UI(ID_PB_BATTERY, OnUpdateTogglePBBat)
ON_COMMAND(ID_PB_BATTERY, OnTogglePBBat)
ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTBMK, OnUpdateExportBmk)
ON_COMMAND(ID_FILE_EXPORTBMK, OnExportBmk)
ON_UPDATE_COMMAND_UI(ID_COLORS_ADDP, OnUpdateNewColorProfile)
ON_COMMAND(ID_COLORS_ADDP, OnNewColorProfile)
ON_UPDATE_COMMAND_UI(ID_COLORS_DELP, OnUpdateDelColorProfile)
ON_COMMAND(ID_COLORS_DELP, OnDelColorProfile)
ON_UPDATE_COMMAND_UI(ID_NEXT_PROFILE, OnUpdateNextColorProfile)
ON_COMMAND(ID_NEXT_PROFILE, OnNextColorProfile)
//}}AFX_MSG_MAP
#ifndef _WIN32_WCE
ON_WM_MOUSEWHEEL()
#endif
ON_MESSAGE(WM_HOTKEY, OnHotkey)
ON_COMMAND_RANGE(DICT_BASE,DICT_BASE+DICT_FILES,OnDict)
ON_UPDATE_COMMAND_UI_RANGE(DICT_BASE,DICT_BASE+DICT_FILES,OnUpdateDict)
ON_COMMAND_RANGE(COLORS_BASE,COLORS_BASE+COLORS_MAX,OnSelColor)
ON_UPDATE_COMMAND_UI_RANGE(COLORS_BASE,COLORS_BASE+COLORS_MAX,OnUpdateSelColor)
#ifdef WM_POWERBROADCAST
ON_MESSAGE(WM_POWERBROADCAST, OnPower)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -