More wxWidgets in poem demo.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32836 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -56,8 +56,6 @@
|
||||
|
||||
static wxChar *poem_buffer; // Storage for each poem
|
||||
static wxChar line[150]; // Storage for a line
|
||||
static wxChar title[150]; // Remember the title
|
||||
static wxChar *search_string = NULL; // The search string
|
||||
static int pages[30]; // For multipage poems -
|
||||
// store the start of each page
|
||||
static long last_poem_start = 0; // Start of last found poem
|
||||
@@ -89,11 +87,6 @@ wxIcon *Corner2 = NULL;
|
||||
wxIcon *Corner3 = NULL;
|
||||
wxIcon *Corner4 = NULL;
|
||||
|
||||
// Fonts
|
||||
wxFont *NormalFont = NULL;
|
||||
wxFont *BoldFont = NULL;
|
||||
wxFont *ItalicFont = NULL;
|
||||
|
||||
// Pens
|
||||
wxPen *GreyPen = NULL;
|
||||
wxPen *DarkGreyPen = NULL;
|
||||
@@ -109,10 +102,7 @@ bool LoadPoem(wxChar *, long);
|
||||
int GetIndex();
|
||||
int LoadIndex(wxChar *);
|
||||
bool Compile(void);
|
||||
void WritePreferences();
|
||||
void ReadPreferences();
|
||||
void FindMax(int *max_thing, int thing);
|
||||
void CreateFonts();
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
#include "wx/dataobj.h"
|
||||
@@ -128,11 +118,11 @@ IMPLEMENT_APP(MyApp)
|
||||
MainWindow *TheMainWindow = NULL;
|
||||
|
||||
// Create the fonts
|
||||
void CreateFonts()
|
||||
void MainWindow::CreateFonts()
|
||||
{
|
||||
NormalFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxNORMAL, wxNORMAL);
|
||||
BoldFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxNORMAL, wxBOLD);
|
||||
ItalicFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxITALIC, wxNORMAL);
|
||||
m_normalFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxNORMAL, wxNORMAL);
|
||||
m_boldFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxNORMAL, wxBOLD);
|
||||
m_italicFont = wxTheFontList->FindOrCreateFont(pointSize, wxSWISS, wxITALIC, wxNORMAL);
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(MainWindow, wxFrame)
|
||||
@@ -145,6 +135,8 @@ MainWindow::MainWindow(wxFrame *frame, wxWindowID id, const wxString& title,
|
||||
const wxPoint& pos, const wxSize& size, long style):
|
||||
wxFrame(frame, id, title, pos, size, style)
|
||||
{
|
||||
ReadPreferences();
|
||||
CreateFonts();
|
||||
}
|
||||
|
||||
// Read the poetry buffer, either for finding the size
|
||||
@@ -181,31 +173,34 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
}
|
||||
|
||||
// See what ACTUAL char height is
|
||||
dc->SetFont(* NormalFont);
|
||||
if(m_normalFont)
|
||||
dc->SetFont(*m_normalFont);
|
||||
long xx;
|
||||
long yy;
|
||||
dc->GetTextExtent(_T("X"), &xx, &yy);
|
||||
char_height = (int)yy;
|
||||
|
||||
if (current_page == 0)
|
||||
title[0] = 0;
|
||||
else if (title[0] != 0)
|
||||
{
|
||||
dc->SetFont(* BoldFont);
|
||||
dc->GetTextExtent(title, &xx, &yy);
|
||||
m_title = wxEmptyString;
|
||||
}
|
||||
else if (!m_title.empty())
|
||||
{
|
||||
dc->SetFont(* m_boldFont);
|
||||
dc->GetTextExtent(m_title, &xx, &yy);
|
||||
FindMax(&curr_width, (int)xx);
|
||||
|
||||
if (DrawIt)
|
||||
{
|
||||
int x = (width - xx)/2;
|
||||
dc->SetFont(* BoldFont);
|
||||
dc->SetFont(* m_boldFont);
|
||||
|
||||
// Change text to BLACK!
|
||||
dc->SetTextForeground(* wxBLACK);
|
||||
dc->DrawText(title, x, y);
|
||||
dc->DrawText(m_title, x, y);
|
||||
// Change text to WHITE!
|
||||
dc->SetTextForeground(* wxWHITE);
|
||||
dc->DrawText(title, x-SHADOW_OFFSET, y-SHADOW_OFFSET);
|
||||
dc->DrawText(m_title, x-SHADOW_OFFSET, y-SHADOW_OFFSET);
|
||||
}
|
||||
y += char_height;
|
||||
y += char_height;
|
||||
@@ -259,11 +254,11 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
dc->SetFont(* BoldFont);
|
||||
dc->SetFont(* m_boldFont);
|
||||
line_ptr = line+3;
|
||||
|
||||
wxStrcpy(title, line_ptr);
|
||||
wxStrcat(title, _T(" (cont'd)"));
|
||||
m_title = line_ptr;
|
||||
m_title << _T(" (cont'd)");
|
||||
|
||||
dc->GetTextExtent(line_ptr, &xx, &yy);
|
||||
FindMax(&curr_width, (int)xx);
|
||||
@@ -271,7 +266,7 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
if (DrawIt)
|
||||
{
|
||||
int x = (width - xx)/2;
|
||||
dc->SetFont(* BoldFont);
|
||||
dc->SetFont(* m_boldFont);
|
||||
|
||||
// Change text to BLACK!
|
||||
dc->SetTextForeground(* wxBLACK);
|
||||
@@ -286,7 +281,7 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
|
||||
case 'A':
|
||||
line_ptr = line+3;
|
||||
dc->SetFont(* ItalicFont);
|
||||
dc->SetFont(* m_italicFont);
|
||||
|
||||
dc->GetTextExtent(line_ptr, &xx, &yy);
|
||||
FindMax(&curr_width, (int)xx);
|
||||
@@ -306,7 +301,7 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
}
|
||||
else
|
||||
{
|
||||
dc->SetFont(* NormalFont);
|
||||
dc->SetFont(* m_normalFont);
|
||||
|
||||
dc->GetTextExtent(line, &xx, &yy);
|
||||
FindMax(&curr_width, (int)xx);
|
||||
@@ -314,7 +309,7 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
if (DrawIt)
|
||||
{
|
||||
int x = (int)((width - xx)/2.0);
|
||||
dc->SetFont(* NormalFont);
|
||||
dc->SetFont(* m_normalFont);
|
||||
dc->SetTextForeground(* wxBLACK);
|
||||
dc->DrawText(line, x, y);
|
||||
}
|
||||
@@ -328,14 +323,14 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
{
|
||||
wxChar *cont = _T("(cont'd)");
|
||||
|
||||
dc->SetFont(* NormalFont);
|
||||
dc->SetFont(* m_normalFont);
|
||||
|
||||
dc->GetTextExtent(cont, &xx, &yy);
|
||||
FindMax(&curr_width, (int)xx);
|
||||
if (DrawIt)
|
||||
{
|
||||
int x = (int)((width - xx)/2.0);
|
||||
dc->SetFont(* NormalFont);
|
||||
dc->SetFont(* m_normalFont);
|
||||
dc->SetTextForeground(* wxBLACK);
|
||||
dc->DrawText(cont, x, y);
|
||||
}
|
||||
@@ -399,7 +394,6 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
dc->DrawLine(THICK_LINE_BORDER, THICK_LINE_BORDER,
|
||||
width-THICK_LINE_BORDER, THICK_LINE_BORDER);
|
||||
|
||||
//#ifdef __WXMSW__
|
||||
// Draw icons
|
||||
dc->DrawIcon(* Corner1, 0, 0);
|
||||
dc->DrawIcon(* Corner2, int(width-32), 0);
|
||||
@@ -408,7 +402,6 @@ void MainWindow::ScanBuffer(wxDC *dc, bool DrawIt, int *max_x, int *max_y)
|
||||
int x2 = (width-32);
|
||||
dc->DrawIcon(* Corner3, 0, y2);
|
||||
dc->DrawIcon(* Corner4, x2, y2);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +437,7 @@ void MainWindow::Resize(void)
|
||||
memDC.SelectObject(* backingBitmap);
|
||||
|
||||
memDC.Clear();
|
||||
TheMainWindow->ScanBuffer(&memDC, true, &xx, &yy);
|
||||
ScanBuffer(&memDC, true, &xx, &yy);
|
||||
}
|
||||
|
||||
// Which is more?
|
||||
@@ -482,16 +475,19 @@ void MainWindow::Search(bool ask)
|
||||
{
|
||||
long position;
|
||||
|
||||
if (ask || !search_string)
|
||||
if (ask || m_searchString.empty())
|
||||
{
|
||||
wxString s = wxGetTextFromUser( _T("Enter search string"), _T("Search"), (const wxChar*) search_string);
|
||||
wxString s = wxGetTextFromUser( _T("Enter search string"), _T("Search"), m_searchString);
|
||||
if (s != wxEmptyString)
|
||||
{
|
||||
s.MakeLower();
|
||||
if (search_string) delete[] search_string;
|
||||
search_string = wxStrcpy(new wxChar[wxStrlen(s.c_str()) + 1], s.c_str());
|
||||
m_searchString = s;
|
||||
search_ok = true;
|
||||
} else search_ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
search_ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -499,7 +495,7 @@ void MainWindow::Search(bool ask)
|
||||
search_ok = true;
|
||||
}
|
||||
|
||||
if (search_string && search_ok)
|
||||
if (!m_searchString.empty() && search_ok)
|
||||
{
|
||||
position = DoSearch();
|
||||
if (position > -1)
|
||||
@@ -523,10 +519,6 @@ bool MyApp::OnInit()
|
||||
DarkGreyPen = new wxPen(_T("GREY"), THICK_LINE_WIDTH, wxSOLID);
|
||||
WhitePen = new wxPen(_T("WHITE"), THICK_LINE_WIDTH, wxSOLID);
|
||||
|
||||
CreateFonts();
|
||||
|
||||
ReadPreferences();
|
||||
|
||||
// Seed the random number generator
|
||||
#ifdef __WXWINCE__
|
||||
srand((unsigned) CeGetRandomSeed());
|
||||
@@ -550,7 +542,7 @@ bool MyApp::OnInit()
|
||||
|
||||
TheMainWindow->SetIcon(wxICON(wxpoem));
|
||||
|
||||
TheMainWindow->canvas = new MyCanvas(TheMainWindow, 501, wxDefaultPosition, wxDefaultSize);
|
||||
TheMainWindow->canvas = new MyCanvas(TheMainWindow);
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
@@ -598,8 +590,6 @@ int MyApp::OnExit()
|
||||
delete Corner4;
|
||||
|
||||
delete[] poem_buffer;
|
||||
if (search_string)
|
||||
delete[] search_string;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -622,32 +612,32 @@ BEGIN_EVENT_TABLE(MyCanvas, wxWindow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
// Define a constructor for my canvas
|
||||
MyCanvas::MyCanvas(wxFrame *frame, wxWindowID id, const wxPoint& pos, const wxSize& size):
|
||||
wxWindow(frame, id, pos, size)
|
||||
MyCanvas::MyCanvas(wxFrame *frame):
|
||||
wxWindow(frame, wxID_ANY)
|
||||
{
|
||||
popupMenu = new wxMenu;
|
||||
popupMenu->Append(POEM_NEXT, _T("Next poem/page"));
|
||||
popupMenu->Append(POEM_PREVIOUS, _T("Previous page"));
|
||||
popupMenu->AppendSeparator();
|
||||
popupMenu->Append(POEM_SEARCH, _T("Search"));
|
||||
popupMenu->Append(POEM_NEXT_MATCH, _T("Next match"));
|
||||
popupMenu->Append(POEM_COPY, _T("Copy to clipboard"));
|
||||
popupMenu->Append(POEM_MINIMIZE, _T("Minimize"));
|
||||
popupMenu->AppendSeparator();
|
||||
popupMenu->Append(POEM_BIGGER_TEXT, _T("Bigger text"));
|
||||
popupMenu->Append(POEM_SMALLER_TEXT, _T("Smaller text"));
|
||||
popupMenu->AppendSeparator();
|
||||
popupMenu->Append(POEM_ABOUT, _T("About wxPoem"));
|
||||
popupMenu->AppendSeparator();
|
||||
popupMenu->Append(POEM_EXIT, _T("Exit"));
|
||||
m_popupMenu = new wxMenu;
|
||||
m_popupMenu->Append(POEM_NEXT, _T("Next poem/page"));
|
||||
m_popupMenu->Append(POEM_PREVIOUS, _T("Previous page"));
|
||||
m_popupMenu->AppendSeparator();
|
||||
m_popupMenu->Append(POEM_SEARCH, _T("Search"));
|
||||
m_popupMenu->Append(POEM_NEXT_MATCH, _T("Next match"));
|
||||
m_popupMenu->Append(POEM_COPY, _T("Copy to clipboard"));
|
||||
m_popupMenu->Append(POEM_MINIMIZE, _T("Minimize"));
|
||||
m_popupMenu->AppendSeparator();
|
||||
m_popupMenu->Append(POEM_BIGGER_TEXT, _T("Bigger text"));
|
||||
m_popupMenu->Append(POEM_SMALLER_TEXT, _T("Smaller text"));
|
||||
m_popupMenu->AppendSeparator();
|
||||
m_popupMenu->Append(POEM_ABOUT, _T("About wxPoem"));
|
||||
m_popupMenu->AppendSeparator();
|
||||
m_popupMenu->Append(POEM_EXIT, _T("Exit"));
|
||||
}
|
||||
|
||||
MyCanvas::~MyCanvas()
|
||||
{
|
||||
// Note: this must be done before the main window/canvas are destroyed
|
||||
// or we get an error (no parent window for menu item button)
|
||||
delete popupMenu;
|
||||
popupMenu = NULL;
|
||||
delete m_popupMenu;
|
||||
m_popupMenu = NULL;
|
||||
}
|
||||
|
||||
// Define the repainting behaviour
|
||||
@@ -679,7 +669,7 @@ void MyCanvas::OnMouseEvent(wxMouseEvent& event)
|
||||
if (event.RightDown())
|
||||
{
|
||||
// Versions from wxWin 1.67 are probably OK
|
||||
PopupMenu(popupMenu, (int)x, (int)y );
|
||||
PopupMenu(m_popupMenu, (int)x, (int)y );
|
||||
}
|
||||
else if (event.LeftDown())
|
||||
{
|
||||
@@ -717,17 +707,20 @@ void MyCanvas::OnChar(wxKeyEvent& event)
|
||||
// Next match
|
||||
TheMainWindow->Search(false);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
// New search
|
||||
TheMainWindow->Search(true);
|
||||
break;
|
||||
|
||||
case WXK_SPACE:
|
||||
case WXK_RIGHT:
|
||||
case WXK_DOWN:
|
||||
// Another poem
|
||||
TheMainWindow->NextPage();
|
||||
break;
|
||||
|
||||
case WXK_ESCAPE:
|
||||
TheMainWindow->Close(true);
|
||||
default:
|
||||
@@ -779,7 +772,7 @@ int GetIndex()
|
||||
}
|
||||
|
||||
// Read preferences
|
||||
void ReadPreferences()
|
||||
void MainWindow::ReadPreferences()
|
||||
{
|
||||
#if wxUSE_RESOURCES
|
||||
wxGetResource(_T("wxPoem"), _T("FontSize"), &pointSize);
|
||||
@@ -789,7 +782,7 @@ void ReadPreferences()
|
||||
}
|
||||
|
||||
// Write preferences to disk
|
||||
void WritePreferences()
|
||||
void MainWindow::WritePreferences()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
TheMainWindow->GetPosition(&XPos, &YPos);
|
||||
@@ -869,7 +862,7 @@ bool LoadPoem(wxChar *file_name, long position)
|
||||
// Do the search
|
||||
long MainWindow::DoSearch(void)
|
||||
{
|
||||
if (!search_string)
|
||||
if (m_searchString.empty())
|
||||
return false;
|
||||
|
||||
FILE *file;
|
||||
@@ -880,7 +873,7 @@ long MainWindow::DoSearch(void)
|
||||
long previous_poem_start;
|
||||
|
||||
bool found = false;
|
||||
int search_length = wxStrlen(search_string);
|
||||
int search_length = m_searchString.length();
|
||||
|
||||
if (same_search)
|
||||
{
|
||||
@@ -914,7 +907,7 @@ long MainWindow::DoSearch(void)
|
||||
|
||||
// Only match if we're looking at a different poem
|
||||
// (no point in displaying the same poem again)
|
||||
if ((ch == search_string[i]) && (last_poem_start != previous_poem_start))
|
||||
if ((ch == m_searchString[i]) && (last_poem_start != previous_poem_start))
|
||||
{
|
||||
if (i == 0)
|
||||
last_find = ftell(file);
|
||||
@@ -923,7 +916,9 @@ long MainWindow::DoSearch(void)
|
||||
i ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (ch == '#')
|
||||
{
|
||||
@@ -933,13 +928,15 @@ long MainWindow::DoSearch(void)
|
||||
}
|
||||
fclose(file);
|
||||
if (ch == EOF)
|
||||
{
|
||||
last_find = -1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
return last_poem_start;
|
||||
}
|
||||
else
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1058,11 +1055,11 @@ void MainWindow::OnPopup(wxCommandEvent& event)
|
||||
{
|
||||
static wxString s;
|
||||
s = poem_buffer;
|
||||
s.Replace( _T("@P"),_T(""));
|
||||
s.Replace( _T("@A "),_T(""));
|
||||
s.Replace( _T("@A"),_T(""));
|
||||
s.Replace( _T("@T "),_T(""));
|
||||
s.Replace( _T("@T"),_T(""));
|
||||
s.Replace( _T("@P"),wxEmptyString);
|
||||
s.Replace( _T("@A "),wxEmptyString);
|
||||
s.Replace( _T("@A"),wxEmptyString);
|
||||
s.Replace( _T("@T "),wxEmptyString);
|
||||
s.Replace( _T("@T"),wxEmptyString);
|
||||
wxTextDataObject *data = new wxTextDataObject( s.c_str() );
|
||||
if (!wxTheClipboard->SetData( data ))
|
||||
wxMessageBox(_T("Error while copying to the clipboard."));
|
||||
@@ -1074,19 +1071,12 @@ void MainWindow::OnPopup(wxCommandEvent& event)
|
||||
wxTheClipboard->Close();
|
||||
break;
|
||||
#endif
|
||||
case POEM_COMPILE:
|
||||
// Compile index
|
||||
Compile();
|
||||
break;
|
||||
case POEM_BIGGER_TEXT:
|
||||
{
|
||||
pointSize ++;
|
||||
CreateFonts();
|
||||
TheMainWindow->Resize();
|
||||
break;
|
||||
}
|
||||
case POEM_SMALLER_TEXT:
|
||||
{
|
||||
if (pointSize > 2)
|
||||
{
|
||||
pointSize --;
|
||||
@@ -1094,13 +1084,10 @@ void MainWindow::OnPopup(wxCommandEvent& event)
|
||||
TheMainWindow->Resize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case POEM_ABOUT:
|
||||
{
|
||||
(void)wxMessageBox(_T("wxPoem Version 1.1\nJulian Smart (c) 1995"),
|
||||
_T("About wxPoem"), wxOK, TheMainWindow);
|
||||
break;
|
||||
}
|
||||
case POEM_EXIT:
|
||||
// Exit
|
||||
TheMainWindow->Close(true);
|
||||
|
@@ -32,16 +32,17 @@ DECLARE_APP(MyApp)
|
||||
class MyCanvas: public wxWindow
|
||||
{
|
||||
public:
|
||||
MyCanvas(wxFrame *frame, wxWindowID id, const wxPoint& pos, const wxSize& size);
|
||||
MyCanvas(wxFrame *frame);
|
||||
~MyCanvas();
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent& event);
|
||||
void OnChar(wxKeyEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
private:
|
||||
wxMenu *popupMenu;
|
||||
wxMenu *m_popupMenu;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
// Define a new frame
|
||||
@@ -74,21 +75,35 @@ class MainWindow: public wxFrame
|
||||
void GetIndexLoadPoem(void);
|
||||
void Resize(void);
|
||||
|
||||
private:
|
||||
|
||||
wxString m_searchString;
|
||||
wxString m_title;
|
||||
|
||||
// Preferences
|
||||
void WritePreferences();
|
||||
void ReadPreferences();
|
||||
|
||||
// Fonts
|
||||
void CreateFonts();
|
||||
wxFont *m_normalFont;
|
||||
wxFont *m_boldFont;
|
||||
wxFont *m_italicFont;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
// Menu items
|
||||
enum
|
||||
{
|
||||
POEM_NEXT = wxID_HIGHEST,
|
||||
POEM_PREVIOUS,
|
||||
POEM_COPY,
|
||||
POEM_SEARCH,
|
||||
POEM_NEXT_MATCH,
|
||||
POEM_ABOUT,
|
||||
POEM_EXIT,
|
||||
POEM_COMPILE,
|
||||
POEM_BIGGER_TEXT,
|
||||
POEM_SMALLER_TEXT,
|
||||
POEM_MINIMIZE
|
||||
POEM_ABOUT = wxID_ABOUT,
|
||||
POEM_EXIT = wxID_EXIT,
|
||||
POEM_PREVIOUS = wxID_BACKWARD,
|
||||
POEM_COPY = wxID_COPY,
|
||||
POEM_NEXT = wxID_FORWARD,
|
||||
POEM_NEXT_MATCH = wxID_MORE,
|
||||
POEM_BIGGER_TEXT = wxID_ZOOM_IN,
|
||||
POEM_SMALLER_TEXT = wxID_ZOOM_OUT,
|
||||
POEM_SEARCH = wxID_FIND,
|
||||
POEM_MINIMIZE = wxID_ICONIZE_FRAME
|
||||
};
|
||||
|
Reference in New Issue
Block a user