1. wxFontMapper starts to materialise
2. wxFontEnumerator corrections: EnumerateFamilies => EnumerateFacenames git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4363 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -92,9 +92,10 @@ This is the operator version of \helpref{Item}{wxarraystringitem} method.
|
|||||||
|
|
||||||
\membersection{wxArrayString::Add}\label{wxarraystringadd}
|
\membersection{wxArrayString::Add}\label{wxarraystringadd}
|
||||||
|
|
||||||
\func{void}{Add}{\param{const wxString\& }{str}}
|
\func{size\_t}{Add}{\param{const wxString\& }{str}}
|
||||||
|
|
||||||
Appends a new item to the array.
|
Appends a new item to the array and return the index of th new item in the
|
||||||
|
array.
|
||||||
|
|
||||||
{\bf Warning:} For sorted arrays, the index of the inserted item will not be,
|
{\bf Warning:} For sorted arrays, the index of the inserted item will not be,
|
||||||
in general, equal to \helpref{GetCount()}{wxarraystringgetcount} - 1 because
|
in general, equal to \helpref{GetCount()}{wxarraystringgetcount} - 1 because
|
||||||
|
@@ -17,20 +17,20 @@ programs such as terminal emulators and the like) or the fonts available in
|
|||||||
the given \helpref{encoding}{wxfontencodingoverview}.
|
the given \helpref{encoding}{wxfontencodingoverview}.
|
||||||
|
|
||||||
To do this, you just have to call one of EnumerateXXX() functions - either
|
To do this, you just have to call one of EnumerateXXX() functions - either
|
||||||
\helpref{EnumerateFamilies}{wxfontenumeratorenumeratefamilies} or
|
\helpref{EnumerateFacenames}{wxfontenumeratorenumeratefacenames} or
|
||||||
\helpref{EnumerateEncodings}{wxfontenumeratorenumerateencodings} and the
|
\helpref{EnumerateEncodings}{wxfontenumeratorenumerateencodings} and the
|
||||||
corresponding callback (
|
corresponding callback (
|
||||||
\helpref{OnFontFamily}{wxFontEnumeratoronfontfamily} or
|
\helpref{OnFacename}{wxFontEnumeratoronfacename} or
|
||||||
\helpref{OnFontEncoding}{wxfontenumeratoronfontencoding}) will be called
|
\helpref{OnFontEncoding}{wxfontenumeratoronfontencoding}) will be called
|
||||||
repeatedly until either all fonts (satisfying the specified criteria) are
|
repeatedly until either all fonts (satisfying the specified criteria) are
|
||||||
exhausted or the callback returns FALSE.
|
exhausted or the callback returns FALSE.
|
||||||
|
|
||||||
\wxheading{Virtual functions to override}
|
\wxheading{Virtual functions to override}
|
||||||
|
|
||||||
Either \helpref{OnFontFamily}{wxfontenumeratoronfontfamily} or
|
Either \helpref{OnFacename}{wxfontenumeratoronfacename} or
|
||||||
\helpref{OnFontEncoding}{wxfontenumeratoronfontencoding} should be overridden
|
\helpref{OnFontEncoding}{wxfontenumeratoronfontencoding} should be overridden
|
||||||
depending on whether you plan to call
|
depending on whether you plan to call
|
||||||
\helpref{EnumerateFamilies}{wxfontenumeratorenumeratefamilies} or
|
\helpref{EnumerateFacenames}{wxfontenumeratorenumeratefacenames} or
|
||||||
\helpref{EnumerateEncodings}{wxfontenumeratorenumerateencodings}. Of course,
|
\helpref{EnumerateEncodings}{wxfontenumeratorenumerateencodings}. Of course,
|
||||||
if you call both of them, you should override both functions.
|
if you call both of them, you should override both functions.
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ None
|
|||||||
|
|
||||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||||
|
|
||||||
\membersection{wxFontEnumerator::EnumerateFamilies}\label{wxfontenumeratorenumeratefamilies}
|
\membersection{wxFontEnumerator::EnumerateFacenames}\label{wxfontenumeratorenumeratefacenames}
|
||||||
|
|
||||||
\func{virtual bool}{EnumerateFamilies}{
|
\func{virtual bool}{EnumerateFacenames}{
|
||||||
\param{wxFontEncoding }{encoding = wxFONTENCODING\_SYSTEM},
|
\param{wxFontEncoding }{encoding = wxFONTENCODING\_SYSTEM},
|
||||||
\param{bool }{fixedWidthOnly = FALSE}}
|
\param{bool }{fixedWidthOnly = FALSE}}
|
||||||
|
|
||||||
Call \helpref{OnFontFamily}{wxfontenumeratoronfontfamily} for each font which
|
Call \helpref{OnFacename}{wxfontenumeratoronfacename} for each font which
|
||||||
supports given encoding (only if it is not wxFONTENCODING\_SYSTEM) and is of
|
supports given encoding (only if it is not wxFONTENCODING\_SYSTEM) and is of
|
||||||
fixed width (if {\it fixedWidthOnly} is TRUE).
|
fixed width (if {\it fixedWidthOnly} is TRUE).
|
||||||
|
|
||||||
@@ -72,11 +72,11 @@ Call \helpref{OnFontEncoding}{wxfontenumeratoronfontencoding} for each
|
|||||||
encoding supported by the given font - or for each encoding supported by at
|
encoding supported by the given font - or for each encoding supported by at
|
||||||
least some font if {\it font} is not specified.
|
least some font if {\it font} is not specified.
|
||||||
|
|
||||||
\membersection{wxFontEnumerator::OnFontFamily}\label{wxfontenumeratoronfontfamily}
|
\membersection{wxFontEnumerator::OnFacename}\label{wxfontenumeratoronfacename}
|
||||||
|
|
||||||
\func{virtual bool}{OnFontFamily}{\param{const wxString\& }{font}}
|
\func{virtual bool}{OnFacename}{\param{const wxString\& }{font}}
|
||||||
|
|
||||||
Called by \helpref{EnumerateFamilies}{wxfontenumeratorenumeratefamilies} for
|
Called by \helpref{EnumerateFacenames}{wxfontenumeratorenumeratefacenames} for
|
||||||
each match. Return TRUE to continue enumeration or FALSE to stop it.
|
each match. Return TRUE to continue enumeration or FALSE to stop it.
|
||||||
|
|
||||||
\membersection{wxFontEnumerator::OnFontEncoding}\label{wxfontenumeratoronfontencoding}
|
\membersection{wxFontEnumerator::OnFontEncoding}\label{wxfontenumeratoronfontencoding}
|
||||||
|
@@ -89,6 +89,7 @@ enum wxFontEncoding
|
|||||||
wxFONTENCODING_ISO8859_13, // Latin7
|
wxFONTENCODING_ISO8859_13, // Latin7
|
||||||
wxFONTENCODING_ISO8859_14, // Latin8
|
wxFONTENCODING_ISO8859_14, // Latin8
|
||||||
wxFONTENCODING_ISO8859_15, // Latin9 (a.k.a. Latin0, includes euro)
|
wxFONTENCODING_ISO8859_15, // Latin9 (a.k.a. Latin0, includes euro)
|
||||||
|
wxFONTENCODING_ISO8859_MAX,
|
||||||
|
|
||||||
// Cyrillic charset soup (see http://czyborra.com/charsets/cyrillic.html)
|
// Cyrillic charset soup (see http://czyborra.com/charsets/cyrillic.html)
|
||||||
wxFONTENCODING_KOI8, // we don't support any of KOI8 variants
|
wxFONTENCODING_KOI8, // we don't support any of KOI8 variants
|
||||||
@@ -106,6 +107,12 @@ enum wxFontEncoding
|
|||||||
wxFONTENCODING_CP1250, // WinLatin2
|
wxFONTENCODING_CP1250, // WinLatin2
|
||||||
wxFONTENCODING_CP1251, // WinCyrillic
|
wxFONTENCODING_CP1251, // WinCyrillic
|
||||||
wxFONTENCODING_CP1252, // WinLatin1
|
wxFONTENCODING_CP1252, // WinLatin1
|
||||||
|
wxFONTENCODING_CP1253, // WinGreek (8859-7)
|
||||||
|
wxFONTENCODING_CP1254, // WinTurkish
|
||||||
|
wxFONTENCODING_CP1255, // WinHebrew
|
||||||
|
wxFONTENCODING_CP1256, // WinArabic
|
||||||
|
wxFONTENCODING_CP1257, // WinBaltic (same as Latin 7)
|
||||||
|
wxFONTENCODING_CP12_MAX,
|
||||||
|
|
||||||
wxFONTENCODING_MAX
|
wxFONTENCODING_MAX
|
||||||
};
|
};
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
// Name: fontenum.h
|
// Name: fontenum.h
|
||||||
// Purpose: wxFontEnumerator class for getting available fonts
|
// Purpose: wxFontEnumerator class for getting available fonts
|
||||||
// Author: Julian Smart, Vadim Zeitlin
|
// Author: Julian Smart, Vadim Zeitlin
|
||||||
// Modified by: extended to enumerate more than just font families and work ot
|
// Modified by: extended to enumerate more than just font facenames and works
|
||||||
// only on Windows (VZ)
|
// not only on Windows now (VZ)
|
||||||
// Created: 04/01/98
|
// Created: 04/01/98
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) Julian Smart, Vadim Zeitlin
|
// Copyright: (c) Julian Smart, Vadim Zeitlin
|
||||||
@@ -25,31 +25,31 @@
|
|||||||
class WXDLLEXPORT wxFontEnumerator
|
class WXDLLEXPORT wxFontEnumerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// start enumerating font families (either all of them or those which
|
// start enumerating font facenames (either all of them or those which
|
||||||
// support the given encoding) - will result in OnFontFamily() being
|
// support the given encoding) - will result in OnFacename() being
|
||||||
// called for each available font family (until they are exhausted or
|
// called for each available facename (until they are exhausted or
|
||||||
// OnFontFamily returns FALSE)
|
// OnFacename returns FALSE)
|
||||||
virtual bool EnumerateFamilies
|
virtual bool EnumerateFacenames
|
||||||
(
|
(
|
||||||
wxFontEncoding encoding = wxFONTENCODING_SYSTEM, // all
|
wxFontEncoding encoding = wxFONTENCODING_SYSTEM, // all
|
||||||
bool fixedWidthOnly = FALSE
|
bool fixedWidthOnly = FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
// enumerate the different encodings either for given font family or for
|
// enumerate the different encodings either for given font facename or for
|
||||||
// all font families - will result in OnFontEncoding() being called for
|
// all facenames - will result in OnFontEncoding() being called for each
|
||||||
// each available (family, encoding) couple
|
// available (facename, encoding) couple
|
||||||
virtual bool EnumerateEncodings(const wxString& family = wxT(""));
|
virtual bool EnumerateEncodings(const wxString& facename = wxT(""));
|
||||||
|
|
||||||
// callbacks which are called after one of EnumerateXXX() functions from
|
// callbacks which are called after one of EnumerateXXX() functions from
|
||||||
// above is invoked - all of them may return FALSE to stop enumeration or
|
// above is invoked - all of them may return FALSE to stop enumeration or
|
||||||
// TRUE to continue with it
|
// TRUE to continue with it
|
||||||
|
|
||||||
// called by EnumerateFamilies
|
// called by EnumerateFacenames
|
||||||
virtual bool OnFontFamily(const wxString& WXUNUSED(family))
|
virtual bool OnFacename(const wxString& WXUNUSED(facename))
|
||||||
{ return FALSE; }
|
{ return FALSE; }
|
||||||
|
|
||||||
// called by EnumerateEncodings
|
// called by EnumerateEncodings
|
||||||
virtual bool OnFontEncoding(const wxString& WXUNUSED(family),
|
virtual bool OnFontEncoding(const wxString& WXUNUSED(facename),
|
||||||
const wxString& WXUNUSED(encoding))
|
const wxString& WXUNUSED(encoding))
|
||||||
{ return FALSE; }
|
{ return FALSE; }
|
||||||
|
|
||||||
|
108
include/wx/fontmap.h
Normal file
108
include/wx/fontmap.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/fontmap.h
|
||||||
|
// Purpose: wxFontMapper class
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 04.11.99
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Vadim Zeitlin
|
||||||
|
// Licence: wxWindows license
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_FONTMAPPER_H_
|
||||||
|
#define _WX_FONTMAPPER_H_
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface "fontmap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "wx/defs.h" // for wxDEFAULT &c
|
||||||
|
|
||||||
|
#include "wx/font.h" // for wxFontEncoding
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxConfigBase;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxFontMapper manages user-definable correspondence between logical font
|
||||||
|
// names and the fonts present on the machine.
|
||||||
|
//
|
||||||
|
// The default implementations of all functions will ask the user if they are
|
||||||
|
// not capable of finding the answer themselves and store the answer in a
|
||||||
|
// config file (configurable via SetConfigXXX functions). This behaviour may
|
||||||
|
// be disabled by giving the value of FALSE to "interactive" parameter.
|
||||||
|
// However, the functions will always consult the config file to allow the
|
||||||
|
// user-defined values override the default logic and there is no way to
|
||||||
|
// disable this - which shouldn't be ever needed because if "interactive" was
|
||||||
|
// never TRUE, the config file is never created anyhow.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxFontMapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// default ctor
|
||||||
|
wxFontMapper();
|
||||||
|
|
||||||
|
// virtual dtor for a base class
|
||||||
|
virtual ~wxFontMapper();
|
||||||
|
|
||||||
|
// returns the encoding for the given charset (in the form of RFC 2046) or
|
||||||
|
// wxFONTENCODING_SYSTEM if couldn't decode it
|
||||||
|
virtual wxFontEncoding CharsetToEncoding(const wxString& charset,
|
||||||
|
bool interactive = TRUE);
|
||||||
|
|
||||||
|
// configure the appearance of the dialogs we may popup
|
||||||
|
// ----------------------------------------------------
|
||||||
|
|
||||||
|
void SetDialogTitle(const wxString& title) { m_titleDialog = title; }
|
||||||
|
|
||||||
|
// functions which allow to configure the config object used: by default,
|
||||||
|
// the global one (from wxConfigBase::Get() will be used) and the default
|
||||||
|
// root path for the config settings is the string returned by
|
||||||
|
// GetDefaultConfigPath()
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// set the config object to use (may be NULL to use default)
|
||||||
|
void SetConfig(wxConfigBase *config) { m_config = config; }
|
||||||
|
|
||||||
|
// set the root config path to use (should be an absolute path)
|
||||||
|
void SetConfigPath(const wxString& prefix);
|
||||||
|
|
||||||
|
// return default config path
|
||||||
|
static const wxChar *GetDefaultConfigPath();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// get the config object we're using - if it wasn't set explicitly, this
|
||||||
|
// function will use wxConfig::Get() to get the global one
|
||||||
|
wxConfigBase *GetConfig();
|
||||||
|
|
||||||
|
// gets the root path for our settings - if itwasn't set explicitly, use
|
||||||
|
// GetDefaultConfigPath()
|
||||||
|
const wxString& GetConfigPath();
|
||||||
|
|
||||||
|
// change to the given (relative) path in the config, return TRUE if ok
|
||||||
|
// (then GetConfig() will return something !NULL), FALSE if no config
|
||||||
|
// object
|
||||||
|
//
|
||||||
|
// caller should provide a pointer to the string variable which should be
|
||||||
|
// later passed to RestorePath()
|
||||||
|
bool ChangePath(const wxString& pathNew, wxString *pathOld);
|
||||||
|
|
||||||
|
// restore the config path after use
|
||||||
|
void RestorePath(const wxString& pathOld);
|
||||||
|
|
||||||
|
// config object and path (in it) to use
|
||||||
|
wxConfigBase *m_config;
|
||||||
|
wxString m_configRootPath;
|
||||||
|
|
||||||
|
// the title for our dialogs
|
||||||
|
wxString m_titleDialog;
|
||||||
|
|
||||||
|
// the parent window for our dialogs
|
||||||
|
wxWindow *m_windowParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WX_FONTMAPPER_H_
|
@@ -35,6 +35,10 @@
|
|||||||
#define _(str) wxGetTranslation(wxT(str))
|
#define _(str) wxGetTranslation(wxT(str))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// another one which just marks the strings for extraction, but doesn't
|
||||||
|
// perform the translation (use -kwxTRANSLATE with xgettext!)
|
||||||
|
#define wxTRANSLATE(str) (str)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// forward decls
|
// forward decls
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
#include <wx/choicdlg.h>
|
#include <wx/choicdlg.h>
|
||||||
#include <wx/fontdlg.h>
|
#include <wx/fontdlg.h>
|
||||||
#include <wx/fontenum.h>
|
#include <wx/fontenum.h>
|
||||||
|
#include <wx/fontmap.h>
|
||||||
|
#include <wx/textfile.h>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
@@ -81,6 +83,7 @@ public:
|
|||||||
// event handlers (these functions should _not_ be virtual)
|
// event handlers (these functions should _not_ be virtual)
|
||||||
void OnQuit(wxCommandEvent& event);
|
void OnQuit(wxCommandEvent& event);
|
||||||
void OnAbout(wxCommandEvent& event);
|
void OnAbout(wxCommandEvent& event);
|
||||||
|
void OnViewMsg(wxCommandEvent& event);
|
||||||
void OnSelectFont(wxCommandEvent& event);
|
void OnSelectFont(wxCommandEvent& event);
|
||||||
void OnEnumerateFamiliesForEncoding(wxCommandEvent& event);
|
void OnEnumerateFamiliesForEncoding(wxCommandEvent& event);
|
||||||
void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event))
|
void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event))
|
||||||
@@ -117,6 +120,7 @@ enum
|
|||||||
// menu items
|
// menu items
|
||||||
Font_Quit = 1,
|
Font_Quit = 1,
|
||||||
Font_About,
|
Font_About,
|
||||||
|
Font_ViewMsg,
|
||||||
Font_Choose = 100,
|
Font_Choose = 100,
|
||||||
Font_EnumFamiliesForEncoding,
|
Font_EnumFamiliesForEncoding,
|
||||||
Font_EnumFamilies,
|
Font_EnumFamilies,
|
||||||
@@ -135,6 +139,7 @@ enum
|
|||||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_MENU(Font_Quit, MyFrame::OnQuit)
|
EVT_MENU(Font_Quit, MyFrame::OnQuit)
|
||||||
EVT_MENU(Font_About, MyFrame::OnAbout)
|
EVT_MENU(Font_About, MyFrame::OnAbout)
|
||||||
|
EVT_MENU(Font_ViewMsg, MyFrame::OnViewMsg)
|
||||||
EVT_MENU(Font_Choose, MyFrame::OnSelectFont)
|
EVT_MENU(Font_Choose, MyFrame::OnSelectFont)
|
||||||
EVT_MENU(Font_EnumFamiliesForEncoding, MyFrame::OnEnumerateFamiliesForEncoding)
|
EVT_MENU(Font_EnumFamiliesForEncoding, MyFrame::OnEnumerateFamiliesForEncoding)
|
||||||
EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies)
|
EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies)
|
||||||
@@ -187,6 +192,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
|||||||
// create a menu bar
|
// create a menu bar
|
||||||
wxMenu *menuFile = new wxMenu;
|
wxMenu *menuFile = new wxMenu;
|
||||||
|
|
||||||
|
menuFile->Append(Font_ViewMsg, "&View...\tCtrl-V",
|
||||||
|
"View an email message file");
|
||||||
|
menuFile->AppendSeparator();
|
||||||
menuFile->Append(Font_About, "&About...\tCtrl-A", "Show about dialog");
|
menuFile->Append(Font_About, "&About...\tCtrl-A", "Show about dialog");
|
||||||
menuFile->AppendSeparator();
|
menuFile->AppendSeparator();
|
||||||
menuFile->Append(Font_Quit, "E&xit\tAlt-X", "Quit this program");
|
menuFile->Append(Font_Quit, "E&xit\tAlt-X", "Quit this program");
|
||||||
@@ -237,12 +245,12 @@ void MyFrame::OnEnumerateEncodings(wxCommandEvent& WXUNUSED(event))
|
|||||||
const wxString& GetText() const { return m_text; }
|
const wxString& GetText() const { return m_text; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool OnFontEncoding(const wxString& family,
|
virtual bool OnFontEncoding(const wxString& facename,
|
||||||
const wxString& encoding)
|
const wxString& encoding)
|
||||||
{
|
{
|
||||||
wxString text;
|
wxString text;
|
||||||
text.Printf("Encoding %d: %s (available in family '%s')\n",
|
text.Printf("Encoding %d: %s (available in facename '%s')\n",
|
||||||
++m_n, encoding.c_str(), family.c_str());
|
++m_n, encoding.c_str(), facename.c_str());
|
||||||
m_text += text;
|
m_text += text;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -270,9 +278,9 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding)
|
|||||||
const wxArrayString& GetFacenames() const { return m_facenames; }
|
const wxArrayString& GetFacenames() const { return m_facenames; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool OnFontFamily(const wxString& family)
|
virtual bool OnFacename(const wxString& facename)
|
||||||
{
|
{
|
||||||
m_facenames.Add(family);
|
m_facenames.Add(facename);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -281,7 +289,7 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding)
|
|||||||
wxArrayString m_facenames;
|
wxArrayString m_facenames;
|
||||||
} fontEnumerator;
|
} fontEnumerator;
|
||||||
|
|
||||||
fontEnumerator.EnumerateFamilies(encoding, fixedWidthOnly);
|
fontEnumerator.EnumerateFacenames(encoding, fixedWidthOnly);
|
||||||
|
|
||||||
if ( fontEnumerator.GotAny() )
|
if ( fontEnumerator.GotAny() )
|
||||||
{
|
{
|
||||||
@@ -387,6 +395,82 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|||||||
Close(TRUE);
|
Close(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
// first, choose the file
|
||||||
|
static wxString s_dir, s_file;
|
||||||
|
wxFileDialog dialog(this, "Open an email message file",
|
||||||
|
s_dir, s_file);
|
||||||
|
if ( dialog.ShowModal() != wxID_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// save for the next time
|
||||||
|
s_dir = dialog.GetDirectory();
|
||||||
|
s_file = dialog.GetFilename();
|
||||||
|
|
||||||
|
wxString filename = dialog.GetPath();
|
||||||
|
|
||||||
|
// load it and search for Content-Type header
|
||||||
|
wxTextFile file(filename);
|
||||||
|
if ( !file.Open() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString charset;
|
||||||
|
|
||||||
|
static const char *prefix = "Content-Type: text/plain; charset=";
|
||||||
|
const size_t len = strlen(prefix);
|
||||||
|
|
||||||
|
size_t n, count = file.GetLineCount();
|
||||||
|
for ( n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
wxString line = file[n];
|
||||||
|
|
||||||
|
if ( !line )
|
||||||
|
{
|
||||||
|
// if it is an email message, headers are over, no need to parse
|
||||||
|
// all the file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( line.Left(len) == prefix )
|
||||||
|
{
|
||||||
|
// found!
|
||||||
|
const char *pc = line.c_str() + len;
|
||||||
|
if ( *pc == '"' )
|
||||||
|
pc++;
|
||||||
|
|
||||||
|
while ( *pc && *pc != '"' )
|
||||||
|
{
|
||||||
|
charset += *pc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !charset )
|
||||||
|
{
|
||||||
|
wxLogError("The file '%s' doesn't contain charset information.",
|
||||||
|
filename.c_str());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, now get the corresponding encoding
|
||||||
|
wxFontMapper fontMapper;
|
||||||
|
wxFontEncoding fontenc = fontMapper.CharsetToEncoding(charset);
|
||||||
|
if ( fontenc == wxFONTENCODING_SYSTEM )
|
||||||
|
{
|
||||||
|
wxLogError("Charset '%s' is unsupported.", charset.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and now create the correct font
|
||||||
|
m_textctrl->LoadFile(filename);
|
||||||
|
|
||||||
|
DoEnumerateFamilies(FALSE, fontenc);
|
||||||
|
}
|
||||||
|
|
||||||
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
wxMessageBox("wxWindows font demo\n"
|
wxMessageBox("wxWindows font demo\n"
|
||||||
@@ -415,7 +499,7 @@ void MyFrame::Resize(const wxSize& size, const wxFont& font)
|
|||||||
wxClientDC dc(this);
|
wxClientDC dc(this);
|
||||||
dc.SetFont(font);
|
dc.SetFont(font);
|
||||||
|
|
||||||
h = 4*dc.GetCharHeight() + 4;
|
h = 10*(dc.GetCharHeight() + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
349
src/common/fontmap.cpp
Normal file
349
src/common/fontmap.cpp
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: common/fontmap.cpp
|
||||||
|
// Purpose: wxFontMapper class
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 04.11.99
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Vadim Zeitlin
|
||||||
|
// Licence: wxWindows license
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation "fontmap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/log.h"
|
||||||
|
#include "wx/intl.h"
|
||||||
|
#endif // PCH
|
||||||
|
|
||||||
|
#include "wx/fontmap.h"
|
||||||
|
#include "wx/config.h"
|
||||||
|
#include "wx/choicdlg.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// the config paths we use
|
||||||
|
static const char* FONTMAPPER_ROOT_PATH = _T("FontMapper");
|
||||||
|
static const char* FONTMAPPER_CHARSET_PATH = _T("Charsets");
|
||||||
|
static const char* FONTMAPPER_CHARSET_ALIAS_PATH = _T("Aliases");
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ctor and dtor
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxFontMapper::wxFontMapper()
|
||||||
|
{
|
||||||
|
m_config = NULL;
|
||||||
|
m_windowParent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFontMapper::~wxFontMapper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// customisation
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* static */ const wxChar *wxFontMapper::GetDefaultConfigPath()
|
||||||
|
{
|
||||||
|
return FONTMAPPER_ROOT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxFontMapper::SetConfigPath(const wxString& prefix)
|
||||||
|
{
|
||||||
|
wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
|
||||||
|
_T("an absolute path should be given to "
|
||||||
|
"wxFontMapper::SetConfigPath()") );
|
||||||
|
|
||||||
|
m_configRootPath = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// get config object and path for it
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxConfigBase *wxFontMapper::GetConfig()
|
||||||
|
{
|
||||||
|
if ( !m_config )
|
||||||
|
{
|
||||||
|
// try the default
|
||||||
|
m_config = wxConfig::Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString& wxFontMapper::GetConfigPath()
|
||||||
|
{
|
||||||
|
if ( !m_configRootPath )
|
||||||
|
{
|
||||||
|
// use the default
|
||||||
|
m_configRootPath = GetDefaultConfigPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_configRootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld)
|
||||||
|
{
|
||||||
|
wxConfigBase *config = GetConfig();
|
||||||
|
if ( !config )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*pathOld = config->GetPath();
|
||||||
|
|
||||||
|
wxString path = GetConfigPath();
|
||||||
|
if ( path.IsEmpty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
|
||||||
|
{
|
||||||
|
path += wxCONFIG_PATH_SEPARATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
|
||||||
|
_T("should be a relative path") );
|
||||||
|
|
||||||
|
path += pathNew;
|
||||||
|
|
||||||
|
config->SetPath(path);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxFontMapper::RestorePath(const wxString& pathOld)
|
||||||
|
{
|
||||||
|
GetConfig()->SetPath(pathOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// charset/encoding correspondence
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset,
|
||||||
|
bool interactive)
|
||||||
|
{
|
||||||
|
wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
|
||||||
|
|
||||||
|
// we're going to modify it, make a copy
|
||||||
|
wxString cs = charset;
|
||||||
|
|
||||||
|
// first try the user-defined settings
|
||||||
|
wxString pathOld;
|
||||||
|
if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) )
|
||||||
|
{
|
||||||
|
wxConfigBase *config = GetConfig();
|
||||||
|
|
||||||
|
// do we have an encoding for this charset?
|
||||||
|
long value = config->Read(charset, -1l);
|
||||||
|
if ( value != -1 )
|
||||||
|
{
|
||||||
|
if ( value >= 0 && value <= wxFONTENCODING_MAX )
|
||||||
|
{
|
||||||
|
encoding = (wxFontEncoding)value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("corrupted config data - invalid encoding %ld "
|
||||||
|
"for charset '%s'"), value, charset.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( encoding == wxFONTENCODING_SYSTEM )
|
||||||
|
{
|
||||||
|
// may be we have an alias?
|
||||||
|
config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
|
||||||
|
|
||||||
|
wxString alias = config->Read(charset);
|
||||||
|
if ( !!alias )
|
||||||
|
{
|
||||||
|
// yes, we do - use it instead
|
||||||
|
cs = alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RestorePath(pathOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if didn't find it there, try to reckognise it ourselves
|
||||||
|
if ( encoding == wxFONTENCODING_SYSTEM )
|
||||||
|
{
|
||||||
|
cs.MakeUpper();
|
||||||
|
|
||||||
|
if ( !cs || cs == _T("US-ASCII") )
|
||||||
|
encoding = wxFONTENCODING_DEFAULT;
|
||||||
|
else if ( cs == _T("KOI8-R") || cs == _T("KOI8-U") )
|
||||||
|
encoding = wxFONTENCODING_KOI8;
|
||||||
|
else if ( cs.Left(3) == _T("ISO") )
|
||||||
|
{
|
||||||
|
// the dash is optional (or, to be exact, it is not, but
|
||||||
|
// several brokenmails "forget" it)
|
||||||
|
const wxChar *p = cs.c_str() + 3;
|
||||||
|
if ( *p == _T('-') )
|
||||||
|
p++;
|
||||||
|
|
||||||
|
unsigned int value;
|
||||||
|
if ( wxSscanf(p, _T("8859-%u"), &value) == 1 )
|
||||||
|
{
|
||||||
|
if ( value < wxFONTENCODING_ISO8859_MAX -
|
||||||
|
wxFONTENCODING_ISO8859_1 )
|
||||||
|
{
|
||||||
|
// it's a valid ISO8859 encoding
|
||||||
|
value += wxFONTENCODING_ISO8859_1 - 1;
|
||||||
|
encoding = (wxFontEncoding)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( cs.Left(8) == _T("WINDOWS-") )
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
if ( wxSscanf(cs.c_str() + 8, "%u", &value) == 1 )
|
||||||
|
{
|
||||||
|
if ( value >= 1250 )
|
||||||
|
{
|
||||||
|
value -= 1250;
|
||||||
|
if ( value < wxFONTENCODING_CP12_MAX -
|
||||||
|
wxFONTENCODING_CP1250 - 1 )
|
||||||
|
{
|
||||||
|
// a valid Windows code page
|
||||||
|
value += wxFONTENCODING_CP1250;
|
||||||
|
encoding = (wxFontEncoding)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// if still no luck, ask the user - unless disabled
|
||||||
|
if ( (encoding == wxFONTENCODING_SYSTEM) && interactive )
|
||||||
|
{
|
||||||
|
// prepare the dialog data
|
||||||
|
|
||||||
|
// the dialog title
|
||||||
|
wxString title(m_titleDialog);
|
||||||
|
if ( !title )
|
||||||
|
title << wxTheApp->GetAppName() << _(": unknown charset");
|
||||||
|
|
||||||
|
// the message
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf(_("The charset '%s' is unknown. You may select another "
|
||||||
|
"charset to replace it with or choose [Cancel] if it "
|
||||||
|
"cannot be replaced"), charset.c_str());
|
||||||
|
|
||||||
|
// the list of choices
|
||||||
|
static wxFontEncoding encodings[] =
|
||||||
|
{
|
||||||
|
wxFONTENCODING_ISO8859_1,
|
||||||
|
wxFONTENCODING_ISO8859_2,
|
||||||
|
wxFONTENCODING_ISO8859_3,
|
||||||
|
wxFONTENCODING_ISO8859_4,
|
||||||
|
wxFONTENCODING_ISO8859_5,
|
||||||
|
wxFONTENCODING_ISO8859_6,
|
||||||
|
wxFONTENCODING_ISO8859_7,
|
||||||
|
wxFONTENCODING_ISO8859_8,
|
||||||
|
wxFONTENCODING_ISO8859_9,
|
||||||
|
wxFONTENCODING_ISO8859_10,
|
||||||
|
wxFONTENCODING_ISO8859_11,
|
||||||
|
wxFONTENCODING_ISO8859_12,
|
||||||
|
wxFONTENCODING_ISO8859_13,
|
||||||
|
wxFONTENCODING_ISO8859_14,
|
||||||
|
wxFONTENCODING_ISO8859_15,
|
||||||
|
wxFONTENCODING_KOI8,
|
||||||
|
wxFONTENCODING_CP1250,
|
||||||
|
wxFONTENCODING_CP1251,
|
||||||
|
wxFONTENCODING_CP1252,
|
||||||
|
wxFONTENCODING_CP1253,
|
||||||
|
wxFONTENCODING_CP1254,
|
||||||
|
wxFONTENCODING_CP1255,
|
||||||
|
wxFONTENCODING_CP1256,
|
||||||
|
wxFONTENCODING_CP1257,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const wxChar* encodingNames[] =
|
||||||
|
{
|
||||||
|
"West European (ISO-8859-1/Latin 1)",
|
||||||
|
"Central European (ISO-8859-2/Latin 2)",
|
||||||
|
"Esperanto (ISO-8859-3)",
|
||||||
|
"Baltic (ISO-8859-4)",
|
||||||
|
"Cyrillic (Latin 5)",
|
||||||
|
"Arabic (ISO-8859-6)"
|
||||||
|
"Greek (ISO-8859-7)",
|
||||||
|
"Hebrew (ISO-8859-8)",
|
||||||
|
"Turkish (ISO-8859-9)",
|
||||||
|
"Baltic II (ISO-8859-10)",
|
||||||
|
"Thai (ISO-8859-11)",
|
||||||
|
"ISO-8859-12",
|
||||||
|
"ISO-8859-13",
|
||||||
|
"ISO-8859-14",
|
||||||
|
"West European new (ISO-8859-15/Latin 0)",
|
||||||
|
"KOI8-R",
|
||||||
|
"Windows Latin 2 (CP 1250)",
|
||||||
|
"Windows Cyrillic (CP 1251)",
|
||||||
|
"Windows Latin 1 (CP 1252)",
|
||||||
|
"Windows Greek (CP 1253)",
|
||||||
|
"Windows Turkish (CP 1254)",
|
||||||
|
"Windows Hebrew (CP 1255)",
|
||||||
|
"Windows Arabic (CP 1256)",
|
||||||
|
"Windows Baltic (CP 1257)",
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t count = WXSIZEOF(encodingNames);
|
||||||
|
|
||||||
|
wxASSERT_MSG( count == WXSIZEOF(encodings),
|
||||||
|
_T("inconsitency detected - forgot to update one of "
|
||||||
|
"the arrays?") );
|
||||||
|
|
||||||
|
wxString *encodingNamesTranslated = new wxString[count];
|
||||||
|
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
encodingNamesTranslated[n] = wxGetTranslation(encodingNames[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the parent window
|
||||||
|
wxWindow *parent = m_windowParent;
|
||||||
|
if ( !parent )
|
||||||
|
parent = wxTheApp->GetTopWindow();
|
||||||
|
|
||||||
|
// do ask the user and get back the index in encodings table
|
||||||
|
int n = wxGetSingleChoiceIndex(msg, title,
|
||||||
|
count,
|
||||||
|
encodingNamesTranslated,
|
||||||
|
parent);
|
||||||
|
|
||||||
|
delete [] encodingNamesTranslated;
|
||||||
|
|
||||||
|
if ( n != -1 )
|
||||||
|
{
|
||||||
|
encoding = encodings[n];
|
||||||
|
}
|
||||||
|
//else: cancelled
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
@@ -145,15 +145,15 @@ bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_fontEnum->OnFontFamily(lf->lfFaceName);
|
return m_fontEnum->OnFacename(lf->lfFaceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxFontEnumerator
|
// wxFontEnumerator
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxFontEnumerator::EnumerateFamilies(wxFontEncoding encoding,
|
bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
|
||||||
bool fixedWidthOnly)
|
bool fixedWidthOnly)
|
||||||
{
|
{
|
||||||
wxFontEnumeratorHelper fe(this);
|
wxFontEnumeratorHelper fe(this);
|
||||||
if ( fe.SetEncoding(encoding) )
|
if ( fe.SetEncoding(encoding) )
|
||||||
|
@@ -39,7 +39,7 @@ static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
|
|||||||
int *nFonts);
|
int *nFonts);
|
||||||
|
|
||||||
// extract all font families from the given font list and call our
|
// extract all font families from the given font list and call our
|
||||||
// OnFontFamily() for each of them
|
// OnFacename() for each of them
|
||||||
static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
|
static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
|
||||||
char **fonts,
|
char **fonts,
|
||||||
int nFonts);
|
int nFonts);
|
||||||
@@ -86,7 +86,7 @@ static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
|
|||||||
// it's not a full font name (probably an alias)
|
// it's not a full font name (probably an alias)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *dash = strchr(font + 1, '-');
|
char *dash = strchr(font + 1, '-');
|
||||||
char *family = dash + 1;
|
char *family = dash + 1;
|
||||||
dash = strchr(family, '-');
|
dash = strchr(family, '-');
|
||||||
@@ -95,7 +95,7 @@ static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
|
|||||||
|
|
||||||
if ( families.Index(fam) == wxNOT_FOUND )
|
if ( families.Index(fam) == wxNOT_FOUND )
|
||||||
{
|
{
|
||||||
if ( !This->OnFontFamily(fam) )
|
if ( !This->OnFacename(fam) )
|
||||||
{
|
{
|
||||||
// stop enumerating
|
// stop enumerating
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -113,8 +113,8 @@ static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
|
|||||||
// wxFontEnumerator
|
// wxFontEnumerator
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxFontEnumerator::EnumerateFamilies(wxFontEncoding encoding,
|
bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
|
||||||
bool fixedWidthOnly)
|
bool fixedWidthOnly)
|
||||||
{
|
{
|
||||||
int nFonts;
|
int nFonts;
|
||||||
char **fonts;
|
char **fonts;
|
||||||
|
Reference in New Issue
Block a user