1032 lines
35 KiB
C++
1032 lines
35 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
// File: contrib/samples/stc/edit.cpp
|
|
// Purpose: STC test module
|
|
// Maintainer: Wyo
|
|
// Created: 2003-09-01
|
|
// Copyright: (c) wxGuide
|
|
// Licence: wxWindows licence
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//----------------------------------------------------------------------------
|
|
// informations
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// headers
|
|
//----------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
// for all others, include the necessary headers (this file is usually all you
|
|
// need because it includes almost all 'standard' wxWidgets headers)
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#include "wx/textdlg.h"
|
|
#endif
|
|
|
|
//! wxWidgets headers
|
|
#include "wx/file.h" // raw file io support
|
|
#include "wx/filename.h" // filename support
|
|
|
|
//! application headers
|
|
#include "defsext.h" // additional definitions
|
|
|
|
#include "edit.h" // edit module
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// resources
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
//============================================================================
|
|
// declarations
|
|
//============================================================================
|
|
|
|
// The (uniform) style used for the annotations.
|
|
const int ANNOTATION_STYLE = wxSTC_STYLE_LASTPREDEFINED + 1;
|
|
|
|
// A small image of a hashtag symbol used in the autocompletion window.
|
|
const char* hashtag_xpm[] = {
|
|
"10 10 2 1",
|
|
" c None",
|
|
". c #BD08F9",
|
|
" .. .. ",
|
|
" .. .. ",
|
|
"..........",
|
|
"..........",
|
|
" .. .. ",
|
|
" .. .. ",
|
|
"..........",
|
|
"..........",
|
|
" .. .. ",
|
|
" .. .. "};
|
|
|
|
//============================================================================
|
|
// implementation
|
|
//============================================================================
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Edit
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxBEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
|
|
// common
|
|
EVT_SIZE ( Edit::OnSize)
|
|
// edit
|
|
EVT_MENU (wxID_CLEAR, Edit::OnEditClear)
|
|
EVT_MENU (wxID_CUT, Edit::OnEditCut)
|
|
EVT_MENU (wxID_COPY, Edit::OnEditCopy)
|
|
EVT_MENU (wxID_PASTE, Edit::OnEditPaste)
|
|
EVT_MENU (myID_INDENTINC, Edit::OnEditIndentInc)
|
|
EVT_MENU (myID_INDENTRED, Edit::OnEditIndentRed)
|
|
EVT_MENU (wxID_SELECTALL, Edit::OnEditSelectAll)
|
|
EVT_MENU (myID_SELECTLINE, Edit::OnEditSelectLine)
|
|
EVT_MENU (wxID_REDO, Edit::OnEditRedo)
|
|
EVT_MENU (wxID_UNDO, Edit::OnEditUndo)
|
|
// find
|
|
EVT_MENU (wxID_FIND, Edit::OnFind)
|
|
EVT_MENU (myID_FINDNEXT, Edit::OnFindNext)
|
|
EVT_MENU (myID_REPLACE, Edit::OnReplace)
|
|
EVT_MENU (myID_REPLACENEXT, Edit::OnReplaceNext)
|
|
EVT_MENU (myID_BRACEMATCH, Edit::OnBraceMatch)
|
|
EVT_MENU (myID_GOTO, Edit::OnGoto)
|
|
// view
|
|
EVT_MENU_RANGE (myID_HIGHLIGHTFIRST, myID_HIGHLIGHTLAST,
|
|
Edit::OnHighlightLang)
|
|
EVT_MENU (myID_DISPLAYEOL, Edit::OnDisplayEOL)
|
|
EVT_MENU (myID_INDENTGUIDE, Edit::OnIndentGuide)
|
|
EVT_MENU (myID_LINENUMBER, Edit::OnLineNumber)
|
|
EVT_MENU (myID_LONGLINEON, Edit::OnLongLineOn)
|
|
EVT_MENU (myID_WHITESPACE, Edit::OnWhiteSpace)
|
|
EVT_MENU (myID_FOLDTOGGLE, Edit::OnFoldToggle)
|
|
EVT_MENU (myID_OVERTYPE, Edit::OnSetOverType)
|
|
EVT_MENU (myID_READONLY, Edit::OnSetReadOnly)
|
|
EVT_MENU (myID_WRAPMODEON, Edit::OnWrapmodeOn)
|
|
EVT_MENU (myID_CHARSETANSI, Edit::OnUseCharset)
|
|
EVT_MENU (myID_CHARSETMAC, Edit::OnUseCharset)
|
|
// annotations
|
|
EVT_MENU (myID_ANNOTATION_ADD, Edit::OnAnnotationAdd)
|
|
EVT_MENU (myID_ANNOTATION_REMOVE, Edit::OnAnnotationRemove)
|
|
EVT_MENU (myID_ANNOTATION_CLEAR, Edit::OnAnnotationClear)
|
|
EVT_MENU (myID_ANNOTATION_STYLE_HIDDEN, Edit::OnAnnotationStyle)
|
|
EVT_MENU (myID_ANNOTATION_STYLE_STANDARD, Edit::OnAnnotationStyle)
|
|
EVT_MENU (myID_ANNOTATION_STYLE_BOXED, Edit::OnAnnotationStyle)
|
|
// extra
|
|
EVT_MENU (myID_CHANGELOWER, Edit::OnChangeCase)
|
|
EVT_MENU (myID_CHANGEUPPER, Edit::OnChangeCase)
|
|
EVT_MENU (myID_CONVERTCR, Edit::OnConvertEOL)
|
|
EVT_MENU (myID_CONVERTCRLF, Edit::OnConvertEOL)
|
|
EVT_MENU (myID_CONVERTLF, Edit::OnConvertEOL)
|
|
EVT_MENU(myID_MULTIPLE_SELECTIONS, Edit::OnMultipleSelections)
|
|
EVT_MENU(myID_MULTI_PASTE, Edit::OnMultiPaste)
|
|
EVT_MENU(myID_MULTIPLE_SELECTIONS_TYPING, Edit::OnMultipleSelectionsTyping)
|
|
EVT_MENU(myID_CUSTOM_POPUP, Edit::OnCustomPopup)
|
|
EVT_MENU(myID_TECHNOLOGY_DEFAULT, Edit::OnTechnology)
|
|
EVT_MENU(myID_TECHNOLOGY_DIRECTWRITE, Edit::OnTechnology)
|
|
// stc
|
|
EVT_STC_MARGINCLICK (wxID_ANY, Edit::OnMarginClick)
|
|
EVT_STC_CHARADDED (wxID_ANY, Edit::OnCharAdded)
|
|
EVT_STC_CALLTIP_CLICK(wxID_ANY, Edit::OnCallTipClick)
|
|
|
|
EVT_KEY_DOWN( Edit::OnKeyDown )
|
|
wxEND_EVENT_TABLE()
|
|
|
|
Edit::Edit (wxWindow *parent, wxWindowID id,
|
|
const wxPoint &pos,
|
|
const wxSize &size,
|
|
long style)
|
|
: wxStyledTextCtrl (parent, id, pos, size, style) {
|
|
|
|
m_LineNrID = 0;
|
|
m_DividerID = 1;
|
|
m_FoldingID = 2;
|
|
|
|
// initialize language
|
|
m_language = NULL;
|
|
|
|
// default font for all styles
|
|
SetViewEOL (g_CommonPrefs.displayEOLEnable);
|
|
SetIndentationGuides (g_CommonPrefs.indentGuideEnable);
|
|
SetEdgeMode (g_CommonPrefs.longLineOnEnable?
|
|
wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
|
|
SetViewWhiteSpace (g_CommonPrefs.whiteSpaceEnable?
|
|
wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
|
|
SetOvertype (g_CommonPrefs.overTypeInitial);
|
|
SetReadOnly (g_CommonPrefs.readOnlyInitial);
|
|
SetWrapMode (g_CommonPrefs.wrapModeInitial?
|
|
wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
|
|
wxFont font(wxFontInfo(10).Family(wxFONTFAMILY_MODERN));
|
|
StyleSetFont (wxSTC_STYLE_DEFAULT, font);
|
|
StyleSetForeground (wxSTC_STYLE_DEFAULT, *wxBLACK);
|
|
StyleSetBackground (wxSTC_STYLE_DEFAULT, *wxWHITE);
|
|
StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour ("DARK GREY"));
|
|
StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
|
|
StyleSetForeground(wxSTC_STYLE_INDENTGUIDE, wxColour ("DARK GREY"));
|
|
InitializePrefs (DEFAULT_LANGUAGE);
|
|
|
|
// set visibility
|
|
SetVisiblePolicy (wxSTC_VISIBLE_STRICT|wxSTC_VISIBLE_SLOP, 1);
|
|
SetXCaretPolicy (wxSTC_CARET_EVEN|wxSTC_VISIBLE_STRICT|wxSTC_CARET_SLOP, 1);
|
|
SetYCaretPolicy (wxSTC_CARET_EVEN|wxSTC_VISIBLE_STRICT|wxSTC_CARET_SLOP, 1);
|
|
|
|
// markers
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDER, wxSTC_MARK_DOTDOTDOT, "BLACK", "BLACK");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_ARROWDOWN, "BLACK", "BLACK");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY, "BLACK", "BLACK");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_DOTDOTDOT, "BLACK", "WHITE");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_ARROWDOWN, "BLACK", "WHITE");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY, "BLACK", "BLACK");
|
|
MarkerDefine (wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY, "BLACK", "BLACK");
|
|
|
|
// annotations
|
|
AnnotationSetVisible(wxSTC_ANNOTATION_BOXED);
|
|
|
|
// autocompletion
|
|
wxBitmap bmp(hashtag_xpm);
|
|
RegisterImage(0, bmp);
|
|
|
|
// call tips
|
|
CallTipSetBackground(*wxYELLOW);
|
|
m_calltipNo = 1;
|
|
|
|
// miscellaneous
|
|
m_LineNrMargin = TextWidth (wxSTC_STYLE_LINENUMBER, "_999999");
|
|
m_FoldingMargin = FromDIP(16);
|
|
CmdKeyClear (wxSTC_KEY_TAB, 0); // this is done by the menu accelerator key
|
|
SetLayoutCache (wxSTC_CACHE_PAGE);
|
|
UsePopUp(wxSTC_POPUP_ALL);
|
|
}
|
|
|
|
Edit::~Edit () {}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// common event handlers
|
|
void Edit::OnSize( wxSizeEvent& event ) {
|
|
int x = GetClientSize().x +
|
|
(g_CommonPrefs.lineNumberEnable? m_LineNrMargin: 0) +
|
|
(g_CommonPrefs.foldEnable? m_FoldingMargin: 0);
|
|
if (x > 0) SetScrollWidth (x);
|
|
event.Skip();
|
|
}
|
|
|
|
// edit event handlers
|
|
void Edit::OnEditRedo (wxCommandEvent &WXUNUSED(event)) {
|
|
if (!CanRedo()) return;
|
|
Redo ();
|
|
}
|
|
|
|
void Edit::OnEditUndo (wxCommandEvent &WXUNUSED(event)) {
|
|
if (!CanUndo()) return;
|
|
Undo ();
|
|
}
|
|
|
|
void Edit::OnEditClear (wxCommandEvent &WXUNUSED(event)) {
|
|
if (GetReadOnly()) return;
|
|
Clear ();
|
|
}
|
|
|
|
void Edit::OnKeyDown (wxKeyEvent &event)
|
|
{
|
|
if (CallTipActive())
|
|
CallTipCancel();
|
|
if (event.GetKeyCode() == WXK_SPACE && event.ControlDown() && event.ShiftDown())
|
|
{
|
|
// Show our first call tip at the current position of the caret.
|
|
m_calltipNo = 1;
|
|
ShowCallTipAt(GetCurrentPos());
|
|
return;
|
|
}
|
|
event.Skip();
|
|
}
|
|
|
|
void Edit::OnEditCut (wxCommandEvent &WXUNUSED(event)) {
|
|
if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return;
|
|
Cut ();
|
|
}
|
|
|
|
void Edit::OnEditCopy (wxCommandEvent &WXUNUSED(event)) {
|
|
if (GetSelectionEnd()-GetSelectionStart() <= 0) return;
|
|
Copy ();
|
|
}
|
|
|
|
void Edit::OnEditPaste (wxCommandEvent &WXUNUSED(event)) {
|
|
if (!CanPaste()) return;
|
|
Paste ();
|
|
}
|
|
|
|
void Edit::OnFind (wxCommandEvent &WXUNUSED(event)) {
|
|
}
|
|
|
|
void Edit::OnFindNext (wxCommandEvent &WXUNUSED(event)) {
|
|
}
|
|
|
|
void Edit::OnReplace (wxCommandEvent &WXUNUSED(event)) {
|
|
}
|
|
|
|
void Edit::OnReplaceNext (wxCommandEvent &WXUNUSED(event)) {
|
|
}
|
|
|
|
void Edit::OnBraceMatch (wxCommandEvent &WXUNUSED(event)) {
|
|
int min = GetCurrentPos ();
|
|
int max = BraceMatch (min);
|
|
if (max > (min+1)) {
|
|
BraceHighlight (min+1, max);
|
|
SetSelection (min+1, max);
|
|
}else{
|
|
BraceBadLight (min);
|
|
}
|
|
}
|
|
|
|
void Edit::OnGoto (wxCommandEvent &WXUNUSED(event)) {
|
|
}
|
|
|
|
void Edit::OnEditIndentInc (wxCommandEvent &WXUNUSED(event)) {
|
|
CmdKeyExecute (wxSTC_CMD_TAB);
|
|
}
|
|
|
|
void Edit::OnEditIndentRed (wxCommandEvent &WXUNUSED(event)) {
|
|
CmdKeyExecute (wxSTC_CMD_DELETEBACK);
|
|
}
|
|
|
|
void Edit::OnEditSelectAll (wxCommandEvent &WXUNUSED(event)) {
|
|
SetSelection (0, GetTextLength ());
|
|
}
|
|
|
|
void Edit::OnEditSelectLine (wxCommandEvent &WXUNUSED(event)) {
|
|
int lineStart = PositionFromLine (GetCurrentLine());
|
|
int lineEnd = PositionFromLine (GetCurrentLine() + 1);
|
|
SetSelection (lineStart, lineEnd);
|
|
}
|
|
|
|
void Edit::OnHighlightLang (wxCommandEvent &event) {
|
|
InitializePrefs (g_LanguagePrefs [event.GetId() - myID_HIGHLIGHTFIRST].name);
|
|
}
|
|
|
|
void Edit::OnDisplayEOL (wxCommandEvent &WXUNUSED(event)) {
|
|
SetViewEOL (!GetViewEOL());
|
|
}
|
|
|
|
void Edit::OnIndentGuide (wxCommandEvent &WXUNUSED(event)) {
|
|
SetIndentationGuides (!GetIndentationGuides());
|
|
}
|
|
|
|
void Edit::OnLineNumber (wxCommandEvent &WXUNUSED(event)) {
|
|
SetMarginWidth (m_LineNrID,
|
|
GetMarginWidth (m_LineNrID) == 0? m_LineNrMargin: 0);
|
|
}
|
|
|
|
void Edit::OnLongLineOn (wxCommandEvent &WXUNUSED(event)) {
|
|
SetEdgeMode (GetEdgeMode() == 0? wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
|
|
}
|
|
|
|
void Edit::OnWhiteSpace (wxCommandEvent &WXUNUSED(event)) {
|
|
SetViewWhiteSpace (GetViewWhiteSpace() == 0?
|
|
wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
|
|
}
|
|
|
|
void Edit::OnFoldToggle (wxCommandEvent &WXUNUSED(event)) {
|
|
ToggleFold (GetFoldParent(GetCurrentLine()));
|
|
}
|
|
|
|
void Edit::OnSetOverType (wxCommandEvent &WXUNUSED(event)) {
|
|
SetOvertype (!GetOvertype());
|
|
}
|
|
|
|
void Edit::OnSetReadOnly (wxCommandEvent &WXUNUSED(event)) {
|
|
SetReadOnly (!GetReadOnly());
|
|
}
|
|
|
|
void Edit::OnWrapmodeOn (wxCommandEvent &WXUNUSED(event)) {
|
|
SetWrapMode (GetWrapMode() == 0? wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
|
|
}
|
|
|
|
void Edit::OnUseCharset (wxCommandEvent &event) {
|
|
int Nr;
|
|
int charset = GetCodePage();
|
|
switch (event.GetId()) {
|
|
case myID_CHARSETANSI: {charset = wxSTC_CHARSET_ANSI; break;}
|
|
case myID_CHARSETMAC: {charset = wxSTC_CHARSET_ANSI; break;}
|
|
}
|
|
for (Nr = 0; Nr < wxSTC_STYLE_LASTPREDEFINED; Nr++) {
|
|
StyleSetCharacterSet (Nr, charset);
|
|
}
|
|
SetCodePage (charset);
|
|
}
|
|
|
|
void Edit::OnAnnotationAdd(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
const int line = GetCurrentLine();
|
|
|
|
wxString ann = AnnotationGetText(line);
|
|
ann = wxGetTextFromUser
|
|
(
|
|
wxString::Format("Enter annotation for the line %d", line),
|
|
"Edit annotation",
|
|
ann,
|
|
this
|
|
);
|
|
if ( ann.empty() )
|
|
return;
|
|
|
|
AnnotationSetText(line, ann);
|
|
AnnotationSetStyle(line, ANNOTATION_STYLE);
|
|
|
|
// Scintilla doesn't update the scroll width for annotations, even with
|
|
// scroll width tracking on, so do it manually.
|
|
const int width = GetScrollWidth();
|
|
|
|
// NB: The following adjustments are only needed when using
|
|
// wxSTC_ANNOTATION_BOXED annotations style, but we apply them always
|
|
// in order to make things simpler and not have to redo the width
|
|
// calculations when the annotations visibility changes. In a real
|
|
// program you'd either just stick to a fixed annotations visibility or
|
|
// update the width when it changes.
|
|
|
|
// Take into account the fact that the annotation is shown indented, with
|
|
// the same indent as the line it's attached to.
|
|
int indent = GetLineIndentation(line);
|
|
|
|
// This is just a hack to account for the width of the box, there doesn't
|
|
// seem to be any way to get it directly from Scintilla.
|
|
indent += 3;
|
|
|
|
const int widthAnn = TextWidth(ANNOTATION_STYLE, ann + wxString(indent, ' '));
|
|
|
|
if (widthAnn > width)
|
|
SetScrollWidth(widthAnn);
|
|
}
|
|
|
|
void Edit::OnAnnotationRemove(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
AnnotationSetText(GetCurrentLine(), wxString());
|
|
}
|
|
|
|
void Edit::OnAnnotationClear(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
AnnotationClearAll();
|
|
}
|
|
|
|
void Edit::OnAnnotationStyle(wxCommandEvent& event)
|
|
{
|
|
int style = 0;
|
|
switch (event.GetId()) {
|
|
case myID_ANNOTATION_STYLE_HIDDEN:
|
|
style = wxSTC_ANNOTATION_HIDDEN;
|
|
break;
|
|
|
|
case myID_ANNOTATION_STYLE_STANDARD:
|
|
style = wxSTC_ANNOTATION_STANDARD;
|
|
break;
|
|
|
|
case myID_ANNOTATION_STYLE_BOXED:
|
|
style = wxSTC_ANNOTATION_BOXED;
|
|
break;
|
|
}
|
|
|
|
AnnotationSetVisible(style);
|
|
}
|
|
|
|
void Edit::OnChangeCase (wxCommandEvent &event) {
|
|
switch (event.GetId()) {
|
|
case myID_CHANGELOWER: {
|
|
CmdKeyExecute (wxSTC_CMD_LOWERCASE);
|
|
break;
|
|
}
|
|
case myID_CHANGEUPPER: {
|
|
CmdKeyExecute (wxSTC_CMD_UPPERCASE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Edit::OnConvertEOL (wxCommandEvent &event) {
|
|
int eolMode = GetEOLMode();
|
|
switch (event.GetId()) {
|
|
case myID_CONVERTCR: { eolMode = wxSTC_EOL_CR; break;}
|
|
case myID_CONVERTCRLF: { eolMode = wxSTC_EOL_CRLF; break;}
|
|
case myID_CONVERTLF: { eolMode = wxSTC_EOL_LF; break;}
|
|
}
|
|
ConvertEOLs (eolMode);
|
|
SetEOLMode (eolMode);
|
|
}
|
|
|
|
void Edit::OnMultipleSelections(wxCommandEvent& WXUNUSED(event)) {
|
|
bool isSet = GetMultipleSelection();
|
|
SetMultipleSelection(!isSet);
|
|
}
|
|
|
|
void Edit::OnMultiPaste(wxCommandEvent& WXUNUSED(event)) {
|
|
int pasteMode = GetMultiPaste();
|
|
if (wxSTC_MULTIPASTE_EACH == pasteMode) {
|
|
SetMultiPaste(wxSTC_MULTIPASTE_ONCE);
|
|
}
|
|
else {
|
|
SetMultiPaste(wxSTC_MULTIPASTE_EACH);
|
|
}
|
|
}
|
|
|
|
void Edit::OnMultipleSelectionsTyping(wxCommandEvent& WXUNUSED(event)) {
|
|
bool isSet = GetAdditionalSelectionTyping();
|
|
SetAdditionalSelectionTyping(!isSet);
|
|
}
|
|
|
|
void Edit::OnCustomPopup(wxCommandEvent& evt)
|
|
{
|
|
UsePopUp(evt.IsChecked() ? wxSTC_POPUP_NEVER : wxSTC_POPUP_ALL);
|
|
}
|
|
|
|
void Edit::OnTechnology(wxCommandEvent& event)
|
|
{
|
|
SetTechnology(event.GetId() == myID_TECHNOLOGY_DIRECTWRITE ? wxSTC_TECHNOLOGY_DIRECTWRITE : wxSTC_TECHNOLOGY_DEFAULT);
|
|
}
|
|
|
|
//! misc
|
|
void Edit::OnMarginClick (wxStyledTextEvent &event) {
|
|
if (event.GetMargin() == 2) {
|
|
int lineClick = LineFromPosition (event.GetPosition());
|
|
int levelClick = GetFoldLevel (lineClick);
|
|
if ((levelClick & wxSTC_FOLDLEVELHEADERFLAG) > 0) {
|
|
ToggleFold (lineClick);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Edit::OnCharAdded (wxStyledTextEvent &event) {
|
|
char chr = (char)event.GetKey();
|
|
int currentLine = GetCurrentLine();
|
|
// Change this if support for mac files with \r is needed
|
|
if (chr == '\n') {
|
|
int lineInd = 0;
|
|
if (currentLine > 0) {
|
|
lineInd = GetLineIndentation(currentLine - 1);
|
|
}
|
|
if (lineInd == 0) return;
|
|
SetLineIndentation (currentLine, lineInd);
|
|
GotoPos(PositionFromLine (currentLine) + lineInd);
|
|
}
|
|
else if (chr == '#') {
|
|
wxString s = "define?0 elif?0 else?0 endif?0 error?0 if?0 ifdef?0 "
|
|
"ifndef?0 include?0 line?0 pragma?0 undef?0";
|
|
AutoCompShow(0,s);
|
|
}
|
|
}
|
|
|
|
void Edit::OnCallTipClick(wxStyledTextEvent &event)
|
|
{
|
|
if ( event.GetPosition() == 1 ) {
|
|
// If position=1, the up arrow has been clicked. Show the next tip.
|
|
m_calltipNo = m_calltipNo==3?1:(m_calltipNo+1);
|
|
ShowCallTipAt(CallTipPosAtStart());
|
|
}
|
|
else if ( event.GetPosition() == 2 ) {
|
|
// If position=2, the down arrow has been clicked. Show previous tip.
|
|
m_calltipNo = m_calltipNo==1?3:(m_calltipNo-1);
|
|
ShowCallTipAt(CallTipPosAtStart());
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// private functions
|
|
void Edit::ShowCallTipAt(int position)
|
|
{
|
|
// In a call tip string, the character '\001' will become a clickable
|
|
// up arrow and '\002' will become a clickable down arrow.
|
|
wxString ctString = wxString::Format("\001 %d of 3 \002 ", m_calltipNo);
|
|
if ( m_calltipNo == 1 )
|
|
ctString += "This is a call tip. Try clicking the up or down buttons.";
|
|
else if ( m_calltipNo == 2 )
|
|
ctString += "It is meant to be a context sensitive popup helper for "
|
|
"the user.";
|
|
else
|
|
ctString += "This is a call tip with multiple lines.\n"
|
|
"You can provide slightly longer help with "
|
|
"call tips like these.";
|
|
|
|
if ( CallTipActive() )
|
|
CallTipCancel();
|
|
CallTipShow(position, ctString);
|
|
}
|
|
|
|
wxString Edit::DeterminePrefs (const wxString &filename) {
|
|
|
|
LanguageInfo const* curInfo;
|
|
|
|
// determine language from filepatterns
|
|
int languageNr;
|
|
for (languageNr = 0; languageNr < g_LanguagePrefsSize; languageNr++) {
|
|
curInfo = &g_LanguagePrefs [languageNr];
|
|
wxString filepattern = curInfo->filepattern;
|
|
filepattern.Lower();
|
|
while (!filepattern.empty()) {
|
|
wxString cur = filepattern.BeforeFirst (';');
|
|
if ((cur == filename) ||
|
|
(cur == (filename.BeforeLast ('.') + ".*")) ||
|
|
(cur == ("*." + filename.AfterLast ('.')))) {
|
|
return curInfo->name;
|
|
}
|
|
filepattern = filepattern.AfterFirst (';');
|
|
}
|
|
}
|
|
return wxEmptyString;
|
|
|
|
}
|
|
|
|
bool Edit::InitializePrefs (const wxString &name) {
|
|
|
|
// initialize styles
|
|
StyleClearAll();
|
|
LanguageInfo const* curInfo = NULL;
|
|
|
|
// determine language
|
|
bool found = false;
|
|
int languageNr;
|
|
for (languageNr = 0; languageNr < g_LanguagePrefsSize; languageNr++) {
|
|
curInfo = &g_LanguagePrefs [languageNr];
|
|
if (curInfo->name == name) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) return false;
|
|
|
|
// set lexer and language
|
|
SetLexer (curInfo->lexer);
|
|
m_language = curInfo;
|
|
|
|
// set margin for line numbers
|
|
SetMarginType (m_LineNrID, wxSTC_MARGIN_NUMBER);
|
|
StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour ("DARK GREY"));
|
|
StyleSetBackground (wxSTC_STYLE_LINENUMBER, *wxWHITE);
|
|
SetMarginWidth (m_LineNrID, 0); // start out not visible
|
|
|
|
// annotations style
|
|
StyleSetBackground(ANNOTATION_STYLE, wxColour(244, 220, 220));
|
|
StyleSetForeground(ANNOTATION_STYLE, *wxBLACK);
|
|
StyleSetSizeFractional(ANNOTATION_STYLE,
|
|
(StyleGetSizeFractional(wxSTC_STYLE_DEFAULT)*4)/5);
|
|
|
|
// default fonts for all styles!
|
|
int Nr;
|
|
for (Nr = 0; Nr < wxSTC_STYLE_LASTPREDEFINED; Nr++) {
|
|
wxFont font(wxFontInfo(10).Family(wxFONTFAMILY_MODERN));
|
|
StyleSetFont (Nr, font);
|
|
}
|
|
|
|
// set common styles
|
|
StyleSetForeground (wxSTC_STYLE_DEFAULT, wxColour ("DARK GREY"));
|
|
StyleSetForeground (wxSTC_STYLE_INDENTGUIDE, wxColour ("DARK GREY"));
|
|
|
|
// initialize settings
|
|
if (g_CommonPrefs.syntaxEnable) {
|
|
int keywordnr = 0;
|
|
for (Nr = 0; Nr < STYLE_TYPES_COUNT; Nr++) {
|
|
if (curInfo->styles[Nr].type == -1) continue;
|
|
const StyleInfo &curType = g_StylePrefs [curInfo->styles[Nr].type];
|
|
wxFont font(wxFontInfo(curType.fontsize)
|
|
.Family(wxFONTFAMILY_MODERN)
|
|
.FaceName(curType.fontname));
|
|
StyleSetFont (Nr, font);
|
|
if (curType.foreground.length()) {
|
|
StyleSetForeground (Nr, wxColour (curType.foreground));
|
|
}
|
|
if (curType.background.length()) {
|
|
StyleSetBackground (Nr, wxColour (curType.background));
|
|
}
|
|
StyleSetBold (Nr, (curType.fontstyle & mySTC_STYLE_BOLD) > 0);
|
|
StyleSetItalic (Nr, (curType.fontstyle & mySTC_STYLE_ITALIC) > 0);
|
|
StyleSetUnderline (Nr, (curType.fontstyle & mySTC_STYLE_UNDERL) > 0);
|
|
StyleSetVisible (Nr, (curType.fontstyle & mySTC_STYLE_HIDDEN) == 0);
|
|
StyleSetCase (Nr, curType.lettercase);
|
|
const char *pwords = curInfo->styles[Nr].words;
|
|
if (pwords) {
|
|
SetKeyWords (keywordnr, pwords);
|
|
keywordnr += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// set margin as unused
|
|
SetMarginType (m_DividerID, wxSTC_MARGIN_SYMBOL);
|
|
SetMarginWidth (m_DividerID, 0);
|
|
SetMarginSensitive (m_DividerID, false);
|
|
|
|
// folding
|
|
SetMarginType (m_FoldingID, wxSTC_MARGIN_SYMBOL);
|
|
SetMarginMask (m_FoldingID, wxSTC_MASK_FOLDERS);
|
|
StyleSetBackground (m_FoldingID, *wxWHITE);
|
|
SetMarginWidth (m_FoldingID, 0);
|
|
SetMarginSensitive (m_FoldingID, false);
|
|
if (g_CommonPrefs.foldEnable) {
|
|
SetMarginWidth (m_FoldingID, curInfo->folds != 0? m_FoldingMargin: 0);
|
|
SetMarginSensitive (m_FoldingID, curInfo->folds != 0);
|
|
SetProperty ("fold", curInfo->folds != 0? "1": "0");
|
|
SetProperty ("fold.comment",
|
|
(curInfo->folds & mySTC_FOLD_COMMENT) > 0? "1": "0");
|
|
SetProperty ("fold.compact",
|
|
(curInfo->folds & mySTC_FOLD_COMPACT) > 0? "1": "0");
|
|
SetProperty ("fold.preprocessor",
|
|
(curInfo->folds & mySTC_FOLD_PREPROC) > 0? "1": "0");
|
|
SetProperty ("fold.html",
|
|
(curInfo->folds & mySTC_FOLD_HTML) > 0? "1": "0");
|
|
SetProperty ("fold.html.preprocessor",
|
|
(curInfo->folds & mySTC_FOLD_HTMLPREP) > 0? "1": "0");
|
|
SetProperty ("fold.comment.python",
|
|
(curInfo->folds & mySTC_FOLD_COMMENTPY) > 0? "1": "0");
|
|
SetProperty ("fold.quotes.python",
|
|
(curInfo->folds & mySTC_FOLD_QUOTESPY) > 0? "1": "0");
|
|
}
|
|
SetFoldFlags (wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED |
|
|
wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED);
|
|
|
|
// set spaces and indentation
|
|
SetTabWidth (4);
|
|
SetUseTabs (false);
|
|
SetTabIndents (true);
|
|
SetBackSpaceUnIndents (true);
|
|
SetIndent (g_CommonPrefs.indentEnable? 4: 0);
|
|
|
|
// others
|
|
SetViewEOL (g_CommonPrefs.displayEOLEnable);
|
|
SetIndentationGuides (g_CommonPrefs.indentGuideEnable);
|
|
SetEdgeColumn (80);
|
|
SetEdgeMode (g_CommonPrefs.longLineOnEnable? wxSTC_EDGE_LINE: wxSTC_EDGE_NONE);
|
|
SetViewWhiteSpace (g_CommonPrefs.whiteSpaceEnable?
|
|
wxSTC_WS_VISIBLEALWAYS: wxSTC_WS_INVISIBLE);
|
|
SetOvertype (g_CommonPrefs.overTypeInitial);
|
|
SetReadOnly (g_CommonPrefs.readOnlyInitial);
|
|
SetWrapMode (g_CommonPrefs.wrapModeInitial?
|
|
wxSTC_WRAP_WORD: wxSTC_WRAP_NONE);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Edit::LoadFile ()
|
|
{
|
|
#if wxUSE_FILEDLG
|
|
// get filename
|
|
if (!m_filename) {
|
|
wxFileDialog dlg (this, "Open file", wxEmptyString, wxEmptyString,
|
|
"Any file (*)|*", wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR);
|
|
if (dlg.ShowModal() != wxID_OK) return false;
|
|
m_filename = dlg.GetPath();
|
|
}
|
|
|
|
// load file
|
|
return LoadFile (m_filename);
|
|
#else
|
|
return false;
|
|
#endif // wxUSE_FILEDLG
|
|
}
|
|
|
|
bool Edit::LoadFile (const wxString &filename) {
|
|
|
|
// load file in edit and clear undo
|
|
if (!filename.empty()) m_filename = filename;
|
|
|
|
wxStyledTextCtrl::LoadFile(m_filename);
|
|
|
|
EmptyUndoBuffer();
|
|
|
|
// determine lexer language
|
|
wxFileName fname (m_filename);
|
|
InitializePrefs (DeterminePrefs (fname.GetFullName()));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Edit::SaveFile ()
|
|
{
|
|
#if wxUSE_FILEDLG
|
|
// return if no change
|
|
if (!Modified()) return true;
|
|
|
|
// get filename
|
|
if (!m_filename) {
|
|
wxFileDialog dlg (this, "Save file", wxEmptyString, wxEmptyString, "Any file (*)|*",
|
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
|
if (dlg.ShowModal() != wxID_OK) return false;
|
|
m_filename = dlg.GetPath();
|
|
}
|
|
|
|
// save file
|
|
return SaveFile (m_filename);
|
|
#else
|
|
return false;
|
|
#endif // wxUSE_FILEDLG
|
|
}
|
|
|
|
bool Edit::SaveFile (const wxString &filename) {
|
|
|
|
// return if no change
|
|
if (!Modified()) return true;
|
|
|
|
// // save edit in file and clear undo
|
|
// if (!filename.empty()) m_filename = filename;
|
|
// wxFile file (m_filename, wxFile::write);
|
|
// if (!file.IsOpened()) return false;
|
|
// wxString buf = GetText();
|
|
// bool okay = file.Write (buf);
|
|
// file.Close();
|
|
// if (!okay) return false;
|
|
// EmptyUndoBuffer();
|
|
// SetSavePoint();
|
|
|
|
// return true;
|
|
|
|
return wxStyledTextCtrl::SaveFile(filename);
|
|
|
|
}
|
|
|
|
bool Edit::Modified () {
|
|
|
|
// return modified state
|
|
return (GetModify() && !GetReadOnly());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// EditProperties
|
|
//----------------------------------------------------------------------------
|
|
|
|
EditProperties::EditProperties (Edit *edit,
|
|
long style)
|
|
: wxDialog (edit, wxID_ANY, wxEmptyString,
|
|
wxDefaultPosition, wxDefaultSize,
|
|
style | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
|
|
|
|
// sets the application title
|
|
SetTitle (_("Properties"));
|
|
wxString text;
|
|
|
|
// full name
|
|
wxBoxSizer *fullname = new wxBoxSizer (wxHORIZONTAL);
|
|
fullname->Add (10, 0);
|
|
fullname->Add (new wxStaticText (this, wxID_ANY, _("Full filename"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
|
|
fullname->Add (new wxStaticText (this, wxID_ANY, edit->GetFilename()),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
|
|
|
|
// text info
|
|
wxGridSizer *textinfo = new wxGridSizer (4, 0, 2);
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, _("Language"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, edit->m_language->name),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, _("Lexer-ID: "),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
text = wxString::Format ("%d", edit->GetLexer());
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, text),
|
|
0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
wxString EOLtype;
|
|
switch (edit->GetEOLMode()) {
|
|
case wxSTC_EOL_CR: {EOLtype = "CR (Unix)"; break; }
|
|
case wxSTC_EOL_CRLF: {EOLtype = "CRLF (Windows)"; break; }
|
|
case wxSTC_EOL_LF: {EOLtype = "CR (Macintosh)"; break; }
|
|
}
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, _("Line endings"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
textinfo->Add (new wxStaticText (this, wxID_ANY, EOLtype),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
|
|
// text info box
|
|
wxStaticBoxSizer *textinfos = new wxStaticBoxSizer (
|
|
new wxStaticBox (this, wxID_ANY, _("Information")),
|
|
wxVERTICAL);
|
|
textinfos->Add (textinfo, 0, wxEXPAND);
|
|
textinfos->Add (0, 6);
|
|
|
|
// statistic
|
|
wxGridSizer *statistic = new wxGridSizer (4, 0, 2);
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, _("Total lines"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
text = wxString::Format ("%d", edit->GetLineCount());
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, text),
|
|
0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, _("Total chars"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
text = wxString::Format ("%d", edit->GetTextLength());
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, text),
|
|
0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, _("Current line"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
text = wxString::Format ("%d", edit->GetCurrentLine());
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, text),
|
|
0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, _("Current pos"),
|
|
wxDefaultPosition, wxSize(80, wxDefaultCoord)),
|
|
0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 4);
|
|
text = wxString::Format ("%d", edit->GetCurrentPos());
|
|
statistic->Add (new wxStaticText (this, wxID_ANY, text),
|
|
0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 4);
|
|
|
|
// char/line statistics
|
|
wxStaticBoxSizer *statistics = new wxStaticBoxSizer (
|
|
new wxStaticBox (this, wxID_ANY, _("Statistics")),
|
|
wxVERTICAL);
|
|
statistics->Add (statistic, 0, wxEXPAND);
|
|
statistics->Add (0, 6);
|
|
|
|
// total pane
|
|
wxBoxSizer *totalpane = new wxBoxSizer (wxVERTICAL);
|
|
totalpane->Add (fullname, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10);
|
|
totalpane->Add (0, 6);
|
|
totalpane->Add (textinfos, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
|
|
totalpane->Add (0, 10);
|
|
totalpane->Add (statistics, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
|
|
totalpane->Add (0, 6);
|
|
wxButton *okButton = new wxButton (this, wxID_OK, _("OK"));
|
|
okButton->SetDefault();
|
|
totalpane->Add (okButton, 0, wxALIGN_CENTER | wxALL, 10);
|
|
|
|
SetSizerAndFit (totalpane);
|
|
|
|
ShowModal();
|
|
}
|
|
|
|
#if wxUSE_PRINTING_ARCHITECTURE
|
|
|
|
//----------------------------------------------------------------------------
|
|
// EditPrint
|
|
//----------------------------------------------------------------------------
|
|
|
|
EditPrint::EditPrint (Edit *edit, const wxString& title)
|
|
: wxPrintout(title)
|
|
, m_edit(edit)
|
|
{
|
|
}
|
|
|
|
bool EditPrint::OnPrintPage (int page) {
|
|
|
|
wxDC *dc = GetDC();
|
|
if (!dc) return false;
|
|
|
|
// scale DC
|
|
PrintScaling (dc);
|
|
|
|
// print page
|
|
m_edit->FormatRange(true, page == 1 ? 0 : m_pageEnds[page-2], m_pageEnds[page-1],
|
|
dc, dc, m_printRect, m_pageRect);
|
|
return true;
|
|
}
|
|
|
|
bool EditPrint::OnBeginDocument (int startPage, int endPage) {
|
|
|
|
if (!wxPrintout::OnBeginDocument (startPage, endPage)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void EditPrint::GetPageInfo (int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) {
|
|
|
|
// initialize values
|
|
*minPage = 0;
|
|
*maxPage = 0;
|
|
*selPageFrom = 0;
|
|
*selPageTo = 0;
|
|
|
|
// scale DC if possible
|
|
wxDC *dc = GetDC();
|
|
if (!dc) return;
|
|
PrintScaling (dc);
|
|
|
|
// get print page informations and convert to printer pixels
|
|
wxSize ppiScr;
|
|
GetPPIScreen (&ppiScr.x, &ppiScr.y);
|
|
wxSize page = g_pageSetupData->GetPaperSize();
|
|
page.x = static_cast<int> (page.x * ppiScr.x / 25.4);
|
|
page.y = static_cast<int> (page.y * ppiScr.y / 25.4);
|
|
// In landscape mode we need to swap the width and height
|
|
if ( g_pageSetupData->GetPrintData().GetOrientation() == wxLANDSCAPE )
|
|
{
|
|
wxSwap(page.x, page.y);
|
|
}
|
|
|
|
m_pageRect = wxRect (0,
|
|
0,
|
|
page.x,
|
|
page.y);
|
|
|
|
// get margins informations and convert to printer pixels
|
|
wxPoint pt = g_pageSetupData->GetMarginTopLeft();
|
|
int left = pt.x;
|
|
int top = pt.y;
|
|
pt = g_pageSetupData->GetMarginBottomRight();
|
|
int right = pt.x;
|
|
int bottom = pt.y;
|
|
|
|
top = static_cast<int> (top * ppiScr.y / 25.4);
|
|
bottom = static_cast<int> (bottom * ppiScr.y / 25.4);
|
|
left = static_cast<int> (left * ppiScr.x / 25.4);
|
|
right = static_cast<int> (right * ppiScr.x / 25.4);
|
|
|
|
m_printRect = wxRect (left,
|
|
top,
|
|
page.x - (left + right),
|
|
page.y - (top + bottom));
|
|
|
|
// count pages
|
|
m_pageEnds.Clear();
|
|
int printed = 0;
|
|
while ( printed < m_edit->GetLength() ) {
|
|
printed = m_edit->FormatRange(false, printed, m_edit->GetLength(),
|
|
dc, dc, m_printRect, m_pageRect);
|
|
m_pageEnds.Add(printed);
|
|
*maxPage += 1;
|
|
}
|
|
if (*maxPage > 0) *minPage = 1;
|
|
*selPageFrom = *minPage;
|
|
*selPageTo = *maxPage;
|
|
}
|
|
|
|
bool EditPrint::HasPage (int page)
|
|
{
|
|
return page <= (int)m_pageEnds.Count();
|
|
}
|
|
|
|
bool EditPrint::PrintScaling (wxDC *dc){
|
|
|
|
// check for dc, return if none
|
|
if (!dc) return false;
|
|
|
|
// get printer and screen sizing values
|
|
wxSize ppiScr;
|
|
GetPPIScreen (&ppiScr.x, &ppiScr.y);
|
|
if (ppiScr.x == 0) { // most possible guess 96 dpi
|
|
ppiScr.x = 96;
|
|
ppiScr.y = 96;
|
|
}
|
|
wxSize ppiPrt;
|
|
GetPPIPrinter (&ppiPrt.x, &ppiPrt.y);
|
|
if (ppiPrt.x == 0) { // scaling factor to 1
|
|
ppiPrt.x = ppiScr.x;
|
|
ppiPrt.y = ppiScr.y;
|
|
}
|
|
wxSize dcSize = dc->GetSize();
|
|
wxSize pageSize;
|
|
GetPageSizePixels (&pageSize.x, &pageSize.y);
|
|
|
|
// set user scale
|
|
float scale_x = (float)(ppiPrt.x * dcSize.x) /
|
|
(float)(ppiScr.x * pageSize.x);
|
|
float scale_y = (float)(ppiPrt.y * dcSize.y) /
|
|
(float)(ppiScr.y * pageSize.y);
|
|
dc->SetUserScale (scale_x, scale_y);
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif // wxUSE_PRINTING_ARCHITECTURE
|