diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 2c9a780..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.22) -project(wallet) -# add_subdirectory(libsodium) -# add_subdirectory(mpir) -add_subdirectory(wxWidgets) -# include( ${libsodium_USE_FILE} ) -# include( ${mpir_USE_FILE} ) -# include( ${wxWidgets_USE_FILE} ) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED True) -# Whenever this glob's value changes, cmake will rerun and update the build with the -# new/removed files. -file(GLOB walletcpp CONFIGURE_DEPENDS "*.cpp" ) -file(GLOB walletc CONFIGURE_DEPENDS "*.c" ) -file(GLOB walletmanifest CONFIGURE_DEPENDS "*.manifest" ) -file(GLOB walletmanifest CONFIGURE_DEPENDS "*.rc" ) -add_executable(${PROJECT_NAME} - ${walletcpp} - ${walletc} - ${walletmanifest} - ${walletrc} -) -target_link_libraries(${PROJECT_NAME} - ${wxWidgets_LIBRARIES} - ${libsodium_LIBRARIES} - ${mpir_LIBRARIES} -) diff --git a/msvc/wallet.manifest b/msvc/wallet.manifest index 984fdd6..144353e 100644 --- a/msvc/wallet.manifest +++ b/msvc/wallet.manifest @@ -1,14 +1,8 @@ - - - - - - UTF-8 - \ No newline at end of file + diff --git a/msvc/wallet.rc b/msvc/wallet.rc index 9e1a334..87b84f0 100644 --- a/msvc/wallet.rc +++ b/msvc/wallet.rc @@ -4,10 +4,26 @@ // this icon is used with wxFrame::SetIcon() AAArho ICON "../docs/rho.ico" -// set this to 1 if you don't want to use manifest resource (manifest resource -// is needed to enable visual styles on Windows XP - see docs/msw/winxp.txt -// for more information) +// and alphabetically (!), so put this icon first and give it a name +// starting with "a" +aaaaaaaa ICON "../docs/rho.ico" + +// this icon is used with wxFrame::SetIcon() +sample ICON "../docs/rho.ico" + +// set this to 1 if you don't want to use manifest resource provided by wxWidgets. +// An application manifest is needed for the application UI to look properly and other +// things - see docs/msw/winxp.md for more information) #define wxUSE_NO_MANIFEST 0 -// this is not always needed but doesn't hurt (except making the executable -// very slightly larger): this file contains the standard icons, cursors, ... -#include "wx/msw/wx.rc" + +// to enable full High DPI suppport, we need to opt in into Per-Monitor (V2) DPI awareness, +// see section Issues/MSW in programming guide High DPI Support in wxWidgets +#ifndef wxUSE_DPI_AWARE_MANIFEST +#define wxUSE_DPI_AWARE_MANIFEST 2 +#endif + +// this file contains the standard icons, cursors etc. and also includes the application +// manifest mentioned above +#include "../wxWidgets/include/wx/msw/wx.rc" + + diff --git a/msvc/winConfigWidgets.bat b/msvc/winConfigWidgets.bat new file mode 100644 index 0000000..e369691 --- /dev/null +++ b/msvc/winConfigWidgets.bat @@ -0,0 +1,29 @@ +echo on +call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat +call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +echo on +cd wxWidgets\build\msw +echo on +msbuild wx_vc17.sln -m -p:Configuration=Debug;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) + +echo on +cd ..\..\.. +msbuild wallet.sln -p:Configuration=Debug;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +.\build\Debug\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on debug build +) ELSE ( + echo passed unit test on debug build +) diff --git a/samples/README.txt b/samples/README.txt new file mode 100644 index 0000000..e67e474 --- /dev/null +++ b/samples/README.txt @@ -0,0 +1,3 @@ +This directory contains other people's sample code that I have +modified a little or a lot to conforming to my actual code + diff --git a/samples/config/app.cpp b/samples/config/app.cpp new file mode 100644 index 0000000..6ded2d8 --- /dev/null +++ b/samples/config/app.cpp @@ -0,0 +1,62 @@ +#include "stdafx.h" + +wxIMPLEMENT_APP(MyApp); + +// `Main program' equivalent, creating windows and returning main app frame +bool MyApp::OnInit() +{ + if (!wxApp::OnInit()) + return false; + + // we're using wxConfig's "create-on-demand" feature: it will create the + // config object when it's used for the first time. It has a number of + // advantages compared with explicitly creating our wxConfig: + // 1) we don't pay for it if we don't use it + // 2) there is no danger to create it twice + + // application and vendor name are used by wxConfig to construct the name + // of the config file/registry key and must be set before the first call + // to Get() if you want to override the default values (the application + // name is the name of the executable and the vendor name is the same) + SetVendorName("wxWidgets"); + SetAppName("conftest"); // not needed, it's the default value + + wxConfigBase* pConfig = wxConfigBase::Get(); + + // uncomment this to force writing back of the defaults for all values + // if they're not present in the config - this can give the user an idea + // of all possible settings for this program + pConfig->SetRecordDefaults(); + + // or you could also write something like this: + // wxFileConfig *pConfig = new wxFileConfig("conftest"); + // wxConfigBase::Set(pConfig); + // where you can also specify the file names explicitly if you wish. + // Of course, calling Set() is optional and you only must do it if + // you want to later retrieve this pointer with Get(). + + // create the main program window + Frame* frame = new Frame; + frame->Show(true); + + // use our config object... + if (pConfig->Read("/Controls/Check", 1l) != 0) { + wxMessageBox("You can disable this message box by unchecking\n" + "the checkbox in the main window (of course, a real\n" + "program would have a checkbox right here but we\n" + "keep it simple)", "Welcome to wxConfig demo", + wxICON_INFORMATION | wxOK); + } + + return true; +} + +int MyApp::OnExit() +{ + // clean up: Set() returns the active config object as Get() does, but unlike + // Get() it doesn't try to create one if there is none (definitely not what + // we want here!) + delete wxConfigBase::Set((wxConfigBase*)NULL); + + return 0; +} diff --git a/samples/config/app.h b/samples/config/app.h new file mode 100644 index 0000000..8b899cc --- /dev/null +++ b/samples/config/app.h @@ -0,0 +1,26 @@ +#pragma once +/////////////////////////////////////////////////////////////////////////////// +// Name: conftest.cpp +// Purpose: demo of wxConfig and related classes +// Author: Vadim Zeitlin +// Modified by: +// Created: 03.08.98 +// Copyright: (c) 1998 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ +#include "stdafx.h" +// ---------------------------------------------------------------------------- +// classes +// ---------------------------------------------------------------------------- + +class MyApp : public wxApp +{ +public: + // implement base class virtuals + virtual bool OnInit() wxOVERRIDE; + virtual int OnExit() wxOVERRIDE; +}; diff --git a/samples/config/config.rc b/samples/config/config.rc new file mode 100644 index 0000000..644b5c3 --- /dev/null +++ b/samples/config/config.rc @@ -0,0 +1,20 @@ +// This is wxWidgets style resource file. ;; +// The visual studio resource editor will screw it up. +#pragma code_page(65001) // UTF-8 +// this icon is used with wxFrame::SetIcon() +AAArho ICON "../../docs/rho.ico" + +// set this to 1 if you don't want to use manifest resource provided by wxWidgets. +// An aplication manifest is needed for the application UI to look properly and other +// things - see docs/msw/winxp.md for more information) +#define wxUSE_NO_MANIFEST 0 + +// to enable full High DPI suppport, we need to opt in into Per-Monitor (V2) DPI awareness, +// see section Issues/MSW in programming guide High DPI Support in wxWidgets +#ifndef wxUSE_DPI_AWARE_MANIFEST +#define wxUSE_DPI_AWARE_MANIFEST 2 +#endif + +// this file contains the standard icons, cursors etc. and also includes the application +// manifest mentioned above +#include "../../wxWidgets/include/wx/msw/wx.rc" diff --git a/samples/config/config.sln b/samples/config/config.sln new file mode 100644 index 0000000..78b85f8 --- /dev/null +++ b/samples/config/config.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34031.279 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "config", "config.vcxproj", "{D2B749B3-2C84-506D-B503-5049D1C8A6B1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Debug|x64.ActiveCfg = Debug|x64 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Debug|x64.Build.0 = Debug|x64 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Debug|x86.ActiveCfg = Debug|Win32 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Debug|x86.Build.0 = Debug|Win32 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Release|x64.ActiveCfg = Release|x64 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Release|x64.Build.0 = Release|x64 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Release|x86.ActiveCfg = Release|Win32 + {D2B749B3-2C84-506D-B503-5049D1C8A6B1}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {34E5A526-21E7-4EEC-966A-AA04B8F1DC79} + EndGlobalSection +EndGlobal diff --git a/samples/config/config.vcxproj b/samples/config/config.vcxproj new file mode 100644 index 0000000..25b9c4e --- /dev/null +++ b/samples/config/config.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 17.0 + config + {D2B749B3-2C84-506D-B503-5049D1C8A6B1} + 10.0 + + + + Application + v143 + false + Unicode + true + + + Application + v143 + false + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34031.279 + + + ..\..\build\$(Configuration)\ + ..\..\build\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\build\$(Configuration)\ + ..\..\build\$(Configuration)\$(ProjectName)\ + false + true + + + + WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + .\..\..\lib\vc_x64_lib\mswud;.\..\..\include;.;.\..\..\samples;%(AdditionalIncludeDirectories) + + + /Zc:__cplusplus /utf-8 + Disabled + ..\..\wxWidgets\lib\vc_x64_lib\mswud;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + Sync + EnableFastChecks + MultiThreadedDebugDLL + true + true + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level4 + true + ProgramDatabase + Use + stdcpp20 + stdc17 + + + _DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + 0x0409 + ..\..\wxWidgets\lib\vc_x64_lib\mswud;.\..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories) + + + wxmsw32ud_core.lib;wxbase32ud.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;wxregexud.lib;wxexpatd.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;winspool.lib;winmm.lib;shell32.lib;shlwapi.lib;comctl32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;advapi32.lib;version.lib;ws2_32.lib;wininet.lib;%(AdditionalDependencies) + true + true + Windows + MachineX64 + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib %(AdditionalOptions) + ../../wxWidgets/lib/vc_x64_lib;%(AdditionalLibraryDirectories) + + + true + + + + + WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + .\..\..\lib\vc_x64_lib\mswu;.\..\..\include;.;.\..\..\samples;%(AdditionalIncludeDirectories) + + + MaxSpeed + ..\..\wxWidgets\lib\vc_x64_lib\mswu;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories) + WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + Sync + MultiThreadedDLL + true + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level4 + true + ProgramDatabase + Use + /Zc:__cplusplus /utf-8 + stdcpp20 + stdc17 + + + _CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + 0x0409 + ..\..\wxWidgets\lib\vc_x64_lib\mswu;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories) + + + wxmsw32u_core.lib;wxbase32u.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;winspool.lib;winmm.lib;shell32.lib;shlwapi.lib;comctl32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;advapi32.lib;version.lib;ws2_32.lib;wininet.lib;%(AdditionalDependencies) + true + true + Windows + MachineX64 + true + true + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib %(AdditionalOptions) + ../../wxWidgets/lib/vc_x64_lib;%(AdditionalLibraryDirectories) + + + true + + + + + Use + + + Use + + + Create + Create + + + + + + + + + + + + + + + + + diff --git a/samples/config/frame.cpp b/samples/config/frame.cpp new file mode 100644 index 0000000..56e424a --- /dev/null +++ b/samples/config/frame.cpp @@ -0,0 +1,161 @@ +#include "stdafx.h" + +void Frame::RestorePositionFromConfig(const wxSize& bestSize) { + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig) { + // SetPath() understands ".." but you should probably never use it. + pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; + // restore frame position and size + int x = pConfig->ReadLong(wxT("x"), scr.x / 4); + int y = pConfig->ReadLong(wxT("y"), scr.y / 4); + int w = pConfig->ReadLong(wxT("w"), scr.x / 2); + int h = pConfig->ReadLong(wxT("h"), scr.y / 2); + w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9); + h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5); + x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12)); + y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10)); + this->Move(x, y); + this->Maximize(pConfig->ReadBool(wxT("Maximized"), false)); + this->SetSize(w, h); + pConfig->SetPath(wxT("/")); + } +} + +void Frame::StorePositionToConfig() { + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig) { + pConfig->SetPath(wxT("/MainFrame")); + if (this->IsMaximized()) { + pConfig->Write(wxT("Maximized"), true); + } + else { + // save the frame position + int x, y, w, h; + this->GetSize(&w, &h); + this->GetPosition(&x, &y); + pConfig->Write(wxT("x"), (long)x); + pConfig->Write(wxT("y"), (long)y); + pConfig->Write(wxT("w"), (long)w); + pConfig->Write(wxT("h"), (long)h); + pConfig->Write(wxT("Maximized"), false); + } + pConfig->SetPath(wxT("/")); + } +} + +// main frame ctor +Frame::Frame() + : wxFrame((wxFrame*)NULL, wxID_ANY, "wxConfig Demo") +{ + SetIcon(wxICON(sample)); + + // menu + wxMenu* menuFile = new wxMenu; + + menuFile->Append(wxID_DELETE, "&Delete", "Delete config file"); + menuFile->Bind(wxEVT_MENU, &Frame::OnQuit, this, wxID_EXIT); + menuFile->AppendSeparator(); + menuFile->Append(wxID_ABOUT, "&About\tF1", "About this sample"); + menuFile->Bind(wxEVT_MENU, &Frame::OnAbout, this, wxID_ABOUT); + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT, "E&xit\tAlt-X", "Exit the program"); + menuFile->Bind(wxEVT_MENU, &Frame::OnDelete, this, wxID_DELETE); + wxMenuBar* menuBar = new wxMenuBar; + menuBar->Append(menuFile, "&File"); + SetMenuBar(menuBar); + +#if wxUSE_STATUSBAR + CreateStatusBar(); +#endif // wxUSE_STATUSBAR + + // child controls + wxPanel* panel = new wxPanel(this); + wxStaticText* st = new wxStaticText(panel, wxID_ANY, "These controls remember their values!"); + m_text = new wxTextCtrl(panel, wxID_ANY); + m_check = new wxCheckBox(panel, wxID_ANY, "show welcome message box at startup"); + + // put everything in a sizer + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(st, wxSizerFlags().Border(wxLEFT | wxBOTTOM | wxTOP, 10)); + sizer->Add(m_text, wxSizerFlags().Border(wxLEFT | wxBOTTOM | wxRIGHT, 10).Expand()); + sizer->Add(m_check, wxSizerFlags().Border(wxLEFT, 10)); + panel->SetSizer(sizer); + + // restore the control's values from the config + + // NB: in this program, the config object is already created at this moment + // because we had called Get() from MyApp::OnInit(). However, if you later + // change the code and don't create it before this line, it won't break + // anything - unlike if you manually create wxConfig object with Create() + // or in any other way (then you must be sure to create it before using it!). + wxConfigBase* pConfig = wxConfigBase::Get(); + + // we could write Read("/Controls/Text") as well, it's just to show SetPath() + pConfig->SetPath("/Controls"); + + m_text->SetValue(pConfig->Read("Text", "")); + m_check->SetValue(pConfig->Read("Check", 1l) != 0); + pConfig->SetPath("/"); + wxString s; + if (pConfig->Read("TestValue", &s)) + { + wxLogStatus(this, "TestValue from config is '%s'", s); + } + else + { + wxLogStatus(this, "TestValue not found in the config"); + } + this->RestorePositionFromConfig(ClientToWindowSize(panel->GetBestSize())); + SetClientSize(GetClientSize()); +} + +void Frame::OnQuit(wxCommandEvent&) +{ + Close(true); +} + +void Frame::OnAbout(wxCommandEvent&) +{ + wxMessageBox("wxConfig demo\n(c) 1998-2001 Vadim Zeitlin", "About", + wxICON_INFORMATION | wxOK); +} + +void Frame::OnDelete(wxCommandEvent&) +{ + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig == NULL) + { + wxLogError("No config to delete!"); + return; + } + + if (pConfig->DeleteAll()) + { + wxLogMessage("Config file/registry key successfully deleted."); + + delete wxConfigBase::Set(NULL); + wxConfigBase::DontCreateOnDemand(); + } + else + { + wxLogError("Deleting config file/registry key failed."); + } +} + +Frame::~Frame() +{ + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig == NULL) + return; + + // save the control's values to the config + auto text = m_text->GetValue(); + std::string str = m_text->GetValue().utf8_string(); + pConfig->Write("/Controls/Text", str.c_str()); + pConfig->Write("/Controls/Check", m_check->GetValue()); + + StorePositionToConfig(); + + pConfig->Write("/TestValue", "A test value"); +} + diff --git a/samples/config/frame.h b/samples/config/frame.h new file mode 100644 index 0000000..82d8c17 --- /dev/null +++ b/samples/config/frame.h @@ -0,0 +1,19 @@ +#pragma once + +class Frame : public wxFrame +{ +public: + Frame(); + virtual ~Frame(); + + // callbacks + void OnQuit(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + void OnDelete(wxCommandEvent& event); + void StorePositionToConfig(void); + void RestorePositionFromConfig(const wxSize&); + +private: + wxTextCtrl* m_text; + wxCheckBox* m_check; +}; diff --git a/samples/config/stdafx.cpp b/samples/config/stdafx.cpp new file mode 100644 index 0000000..d1303f3 --- /dev/null +++ b/samples/config/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/samples/config/stdafx.h b/samples/config/stdafx.h new file mode 100644 index 0000000..63e96df --- /dev/null +++ b/samples/config/stdafx.h @@ -0,0 +1,22 @@ +#pragma once + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- +#include "wx/wxprec.h" + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif //precompiled headers + +#include "wx/log.h" +#include "wx/config.h" + +#ifndef wxHAS_IMAGES_IN_RESOURCES +#include "../../src/rho.xpm" +#endif + +#include "frame.h" +#include "app.h" + diff --git a/samples/dialogs/app.cpp b/samples/dialogs/app.cpp new file mode 100644 index 0000000..1de0621 --- /dev/null +++ b/samples/dialogs/app.cpp @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dialogs.cpp +// Purpose: updating to make it more relevant to my code +// and more similar to my code. +// +// Leaving most of useless to me examples in place +// unless I am completely sure they are will never +// be useful. +// +// Some of the stuff here does not quite work +// Only half implemented. Eg, log message +// The primary child of Frame is a scrollable +// window "MyCanvas" to which nothing ever gets +// written after it is created. And the tip +// of the day dialog fails sould be under help) +// +// On the other hand, lots of cool bits of code +// that really deserve to be copied, like +// hooking the windows system menu of +// a window. +// +///////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" + +wxIMPLEMENT_APP(MyApp); + +wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) +EVT_PAINT(MyCanvas::OnPaint) +wxEND_EVENT_TABLE() + +#if wxUSE_CMDLINE_PARSER +static const char* PROGRESS_SWITCH = "progress"; + +void MyApp::OnInitCmdLine(wxCmdLineParser& parser) +{ + wxApp::OnInitCmdLine(parser); + + parser.AddOption("", PROGRESS_SWITCH, + "Style for the startup progress dialog (wxPD_XXX)", + wxCMD_LINE_VAL_NUMBER); +} + +bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser) +{ + if (!wxApp::OnCmdLineParsed(parser)) + return false; + + parser.Found(PROGRESS_SWITCH, &m_startupProgressStyle); + + return true; +} + +#endif // wxUSE_CMDLINE_PARSER + +// `Main program' equivalent, creating windows and returning main app frame +bool MyApp::OnInit() +{ + if (!wxApp::OnInit()) + return false; + +#if wxUSE_PROGRESSDLG + if (m_startupProgressStyle != -1) + { + // Show a test progress dialog before the main event loop is started: + // it should still work. + const int PROGRESS_COUNT = 100; + wxProgressDialog dlg + ( + "Progress in progress", + "Please wait, starting...", + PROGRESS_COUNT, + NULL, + m_startupProgressStyle|wxPD_AUTO_HIDE + ); + for (int i = 0; i <= PROGRESS_COUNT; i++) + { + wxString msg; + switch (i) + { + case 15: + msg = "And the same dialog but with a very, very, very long" + " message, just to test how it appears in this case."; + break; + + case 30: + msg = "Back to brevity"; + break; + + case 80: + msg = "Back and adjusted"; + dlg.Fit(); + break; + } + + if (!dlg.Update(i, msg)) + break; + + wxMilliSleep(50); + } + } +#endif // wxUSE_PROGRESSDLG + +#if wxUSE_IMAGE + wxInitAllImageHandlers(); +#endif + const char* szUtf8Test = " 🙃tick ✔ Pi Π π ϖ π °"; + + // Create the main frame window + Frame* frame = new Frame(szUtf8Test); + frame->Show(true); +#if wxUSE_STARTUP_TIPS + if (frame->m_showTipsAtStartup) { + auto event = new wxCommandEvent(wxEVT_MENU, DIALOGS_TIP); + wxQueueEvent(frame, event); + } +#endif // wxUSE_STARTUP_TIPS + + return true; +} + +// ---------------------------------------------------------------------------- +// MyCanvas +// ---------------------------------------------------------------------------- + +void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); + const char* szUtf8Test = R"|(wxWidgets common dialogs “(✔ +🙃 ✔ π ° )” test application)|"; + dc.DrawText(szUtf8Test, 10, 10); + dc.DrawText("fred fred", 10, 40); +} + diff --git a/samples/dialogs/app.h b/samples/dialogs/app.h new file mode 100644 index 0000000..c2d756b --- /dev/null +++ b/samples/dialogs/app.h @@ -0,0 +1,38 @@ +#pragma once + +#if wxUSE_LOG +// Custom application traits class which we use to override the default log +// target creation +class MyAppTraits : public wxGUIAppTraits +{ +public: + virtual wxLog* CreateLogTarget() wxOVERRIDE; +}; + +#endif // wxUSE_LOG + +// Define a new application type +class MyApp : public wxApp +{ +public: + MyApp() { m_startupProgressStyle = -1; } + + virtual bool OnInit() wxOVERRIDE; + +#if wxUSE_CMDLINE_PARSER + virtual void OnInitCmdLine(wxCmdLineParser& parser) wxOVERRIDE; + virtual bool OnCmdLineParsed(wxCmdLineParser& parser) wxOVERRIDE; +#endif // wxUSE_CMDLINE_PARSER + +protected: +#if wxUSE_LOG + virtual wxAppTraits* CreateTraits() wxOVERRIDE { return new MyAppTraits; } +#endif // wxUSE_LOG + +private: + // Flag set to a valid value if command line option "progress" is used, + // this allows testing of wxProgressDialog before the main event loop is + // started. If this option is not specified it is set to -1 by default + // meaning that progress dialog shouldn't be shown at all. + long m_startupProgressStyle; +}; diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp new file mode 100644 index 0000000..7b6ec5c --- /dev/null +++ b/samples/dialogs/dialogs.cpp @@ -0,0 +1,893 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dialogs.cpp +// Purpose: updating to make it more relevant to my code +// and more similar to my code. +// +// Leaving most of useless to me examples in place +// unless I am completely sure they are will never +// be useful. +// +// Some of the stuff here does not quite work +// Only half implemented. +// +///////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" + +#if USE_MODAL_PRESENTATION + +// ---------------------------------------------------------------------------- +// MyModelessDialog +// ---------------------------------------------------------------------------- + +MyModelessDialog::MyModelessDialog(wxWindow *parent) + : wxDialog(parent, wxID_ANY, wxString("Modeless dialog")) +{ + wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); + + wxButton *btn = new wxButton(this, DIALOGS_MODELESS_BTN, "Press me"); + wxCheckBox *check = new wxCheckBox(this, wxID_ANY, "Should be disabled"); + check->Disable(); + + sizerTop->Add(btn, 1, wxEXPAND | wxALL, 5); + sizerTop->Add(check, 1, wxEXPAND | wxALL, 5); + + SetSizerAndFit(sizerTop); +} + +void MyModelessDialog::OnButton(wxCommandEvent& WXUNUSED(event)) +{ + wxMessageBox("Button pressed in modeless dialog", "Info", + wxOK | wxICON_INFORMATION, this); +} + +void MyModelessDialog::OnClose(wxCloseEvent& event) +{ + if ( event.CanVeto() ) + { + wxMessageBox("Use the menu item to close this dialog", + "Modeless dialog", + wxOK | wxICON_INFORMATION, this); + + event.Veto(); + } +} + +// ---------------------------------------------------------------------------- +// MyModalDialog +// ---------------------------------------------------------------------------- + +MyModalDialog::MyModalDialog(wxWindow *parent) + : wxDialog(parent, wxID_ANY, wxString("Modal dialog")) +{ + wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL); + + m_btnModal = new wxButton(this, wxID_ANY, "&Modal dialog..."); + m_btnModeless = new wxButton(this, wxID_ANY, "Mode&less dialog"); + m_btnDelete = new wxButton(this, wxID_ANY, "&Delete button"); + + sizerTop->Add(m_btnModal, 0, wxALIGN_CENTER | wxALL, 5); + sizerTop->Add(m_btnModeless, 0, wxALIGN_CENTER | wxALL, 5); + sizerTop->Add(m_btnDelete, 0, wxALIGN_CENTER | wxALL, 5); + sizerTop->Add(new wxButton(this, wxID_CLOSE), 0, wxALIGN_CENTER | wxALL, 5); + + SetSizerAndFit(sizerTop); + + SetEscapeId(wxID_CLOSE); + + m_btnModal->SetFocus(); + m_btnModal->SetDefault(); +} + +void MyModalDialog::OnButton(wxCommandEvent& event) +{ + if ( event.GetEventObject() == m_btnDelete ) + { + wxDELETE(m_btnModal); + m_btnDelete->Disable(); + } + else if ( event.GetEventObject() == m_btnModal ) + { +#if wxUSE_TEXTDLG + wxGetTextFromUser("Dummy prompt", + "Modal dialog called from dialog", + wxEmptyString, this); +#else + wxMessageBox("Modal dialog called from dialog"); +#endif // wxUSE_TEXTDLG + } + else if ( event.GetEventObject() == m_btnModeless ) + { + (new MyModelessDialog(this))->Show(); + } + else + { + event.Skip(); + } +} + +#endif // USE_MODAL_PRESENTATION + +// ---------------------------------------------------------------------------- +// StdButtonSizerDialog +// ---------------------------------------------------------------------------- + +StdButtonSizerDialog::StdButtonSizerDialog(wxWindow *parent) + : wxDialog(parent, wxID_ANY, wxString("StdButtonSizer dialog"), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), + m_buttonsSizer(NULL) +{ + wxBoxSizer *const sizerTop = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer *const sizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *const sizerInside1 = new wxBoxSizer(wxVERTICAL); + + m_chkboxAffirmativeButton = new wxCheckBox(this, wxID_ANY, "Enable Affirmative Button"); + + wxStaticBoxSizer *const sizer1 = new wxStaticBoxSizer(wxVERTICAL, this, "Affirmative Button"); + + m_radiobtnOk = new wxRadioButton(this, wxID_ANY, "Ok", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + m_radiobtnYes = new wxRadioButton(this, wxID_ANY, "Yes"); + + wxBoxSizer *const sizerInside2 = new wxBoxSizer(wxVERTICAL); + + m_chkboxDismissButton = new wxCheckBox(this, wxID_ANY, "Enable Dismiss Button"); + + wxStaticBoxSizer *const sizer2 = new wxStaticBoxSizer(wxVERTICAL, this, "Dismiss Button"); + + m_radiobtnCancel = new wxRadioButton(this, wxID_ANY, "Cancel", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + m_radiobtnClose = new wxRadioButton(this, wxID_ANY, "Close"); + + wxBoxSizer *const sizer3 = new wxBoxSizer(wxHORIZONTAL); + + m_chkboxNo = new wxCheckBox(this, wxID_ANY, "No"); + m_chkboxHelp = new wxCheckBox(this, wxID_ANY, "Help"); + m_chkboxApply = new wxCheckBox(this, wxID_ANY, "Apply"); + + m_chkboxNoDefault = new wxCheckBox(this, wxID_ANY, "No Default"); + + sizer1->Add(m_radiobtnOk, 0, wxALL, 5); + sizer1->Add(m_radiobtnYes, 0, wxALL, 5); + + sizer->Add(sizerInside1, 0, 0, 0); + sizerInside1->Add(m_chkboxAffirmativeButton, 0, wxALL, 5); + sizerInside1->Add(sizer1, 0, wxALL, 5); + sizerInside1->SetItemMinSize(sizer1, sizer1->GetStaticBox()->GetBestSize()); // to prevent wrapping of static box label + + sizer2->Add(m_radiobtnCancel, 0, wxALL, 5); + sizer2->Add(m_radiobtnClose, 0, wxALL, 5); + + sizer->Add(sizerInside2, 0, 0, 0); + sizerInside2->Add(m_chkboxDismissButton, 0, wxALL, 5); + sizerInside2->Add(sizer2, 0, wxALL, 5); + sizerInside2->SetItemMinSize(sizer2, sizer2->GetStaticBox()->GetBestSize()); // to prevent wrapping of static box label + + sizerTop->Add(sizer, 0, wxALL, 5); + + sizer3->Add(m_chkboxNo, 0, wxALL, 5); + sizer3->Add(m_chkboxHelp, 0, wxALL, 5); + sizer3->Add(m_chkboxApply, 0, wxALL, 5); + + sizerTop->Add(sizer3, 0, wxALL, 5); + + sizerTop->Add(m_chkboxNoDefault, 0, wxLEFT|wxRIGHT, 10); + + EnableDisableControls(); + + SetSizerAndFit(sizerTop); + + wxCommandEvent ev; + OnEvent(ev); +} + +void StdButtonSizerDialog::OnEvent(wxCommandEvent& WXUNUSED(event)) +{ + if (m_buttonsSizer) + { + m_buttonsSizer->DeleteWindows(); + GetSizer()->Remove(m_buttonsSizer); + } + + EnableDisableControls(); + + long flags = 0; + unsigned long numButtons = 0; + + if (m_chkboxAffirmativeButton->IsChecked()) + { + if (m_radiobtnOk->GetValue()) + { + flags |= wxOK; + numButtons ++; + } + else if (m_radiobtnYes->GetValue()) + { + flags |= wxYES; + numButtons ++; + } + } + + if (m_chkboxDismissButton->IsChecked()) + { + if (m_radiobtnCancel->GetValue()) + { + flags |= wxCANCEL; + numButtons ++; + } + + else if (m_radiobtnClose->GetValue()) + { + flags |= wxCLOSE; + numButtons ++; + } + + } + + if (m_chkboxApply->IsChecked()) + { + flags |= wxAPPLY; + numButtons ++; + } + + if (m_chkboxNo->IsChecked()) + { + flags |= wxNO; + numButtons ++; + } + + if (m_chkboxHelp->IsChecked()) + { + flags |= wxHELP; + numButtons ++; + } + + if (m_chkboxNoDefault->IsChecked()) + { + flags |= wxNO_DEFAULT; + } + + m_buttonsSizer = CreateStdDialogButtonSizer(flags); + GetSizer()->Add(m_buttonsSizer, 0, wxGROW|wxALL, 5); + + Layout(); + GetSizer()->SetSizeHints(this); +} + +void StdButtonSizerDialog::EnableDisableControls() +{ + const bool affButtonEnabled = m_chkboxAffirmativeButton->IsChecked(); + + m_radiobtnOk->Enable(affButtonEnabled); + m_radiobtnYes->Enable(affButtonEnabled); + + const bool dismissButtonEnabled = m_chkboxDismissButton->IsChecked(); + + m_radiobtnCancel->Enable(dismissButtonEnabled); + m_radiobtnClose->Enable(dismissButtonEnabled); +} + +#if USE_SETTINGS_DIALOG +// ---------------------------------------------------------------------------- +// SettingsDialog +// ---------------------------------------------------------------------------- + +wxIMPLEMENT_CLASS(SettingsDialog, wxPropertySheetDialog); + +wxBEGIN_EVENT_TABLE(SettingsDialog, wxPropertySheetDialog) +wxEND_EVENT_TABLE() + +SettingsDialog::SettingsDialog(wxWindow* win, SettingsData& settingsData, int dialogType) + : m_settingsData(settingsData) +{ + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + + int tabImage1 = -1; + int tabImage2 = -1; + + bool useToolBook = (dialogType == DIALOGS_PROPERTY_SHEET_TOOLBOOK || dialogType == DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK); + int resizeBorder = wxRESIZE_BORDER; + + if (useToolBook) + { + resizeBorder = 0; + tabImage1 = 0; + tabImage2 = 1; + + int sheetStyle = wxPROPSHEET_SHRINKTOFIT; + if (dialogType == DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK) + sheetStyle |= wxPROPSHEET_BUTTONTOOLBOOK; + else + sheetStyle |= wxPROPSHEET_TOOLBOOK; + + SetSheetStyle(sheetStyle); + SetSheetInnerBorder(0); + SetSheetOuterBorder(0); + + // create a dummy image list with a few icons + const wxSize imageSize(32, 32); + + m_imageList = new wxImageList(imageSize.GetWidth(), imageSize.GetHeight()); + m_imageList-> + Add(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize)); + m_imageList-> + Add(wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, imageSize)); + m_imageList-> + Add(wxArtProvider::GetIcon(wxART_WARNING, wxART_OTHER, imageSize)); + m_imageList-> + Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, imageSize)); + } + else + m_imageList = NULL; + + Create(win, wxID_ANY, "Preferences", wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | resizeBorder); + + // If using a toolbook, also follow Mac style and don't create buttons + if (!useToolBook) + CreateButtons(wxOK | wxCANCEL | wxHELP); + + wxBookCtrlBase* notebook = GetBookCtrl(); + notebook->SetImageList(m_imageList); + + wxPanel* generalSettings = CreateGeneralSettingsPage(notebook); + wxPanel* aestheticSettings = CreateAestheticSettingsPage(notebook); + + notebook->AddPage(generalSettings, "General", true, tabImage1); + notebook->AddPage(aestheticSettings, "Aesthetics", false, tabImage2); + + LayoutDialog(); +} + +SettingsDialog::~SettingsDialog() +{ + delete m_imageList; +} + +wxPanel* SettingsDialog::CreateGeneralSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + //// LOAD LAST FILE + + wxBoxSizer* itemSizer3 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox3 = new wxCheckBox(panel, ID_LOAD_LAST_PROJECT, "&Load last project on startup", wxDefaultPosition, wxDefaultSize); + checkBox3->SetValidator(wxGenericValidator(&m_settingsData.m_loadLastOnStartup)); + itemSizer3->Add(checkBox3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer3, 0, wxGROW|wxALL, 0); + + //// AUTOSAVE + + wxString autoSaveLabel = "&Auto-save every"; + wxString minsLabel = "mins"; + + wxBoxSizer* itemSizer12 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox12 = new wxCheckBox(panel, ID_AUTO_SAVE, autoSaveLabel, wxDefaultPosition, wxDefaultSize); + +#if wxUSE_SPINCTRL + wxSpinCtrl* spinCtrl12 = new wxSpinCtrl(panel, ID_AUTO_SAVE_MINS, wxEmptyString, + wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 60, 1); + spinCtrl12->SetValidator(wxGenericValidator(&m_settingsData.m_autoSaveInterval)); +#endif + + itemSizer12->Add(checkBox12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); +#if wxUSE_SPINCTRL + itemSizer12->Add(spinCtrl12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); +#endif + itemSizer12->Add(new wxStaticText(panel, wxID_STATIC, minsLabel), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer12, 0, wxGROW|wxALL, 0); + + //// TOOLTIPS + + wxBoxSizer* itemSizer8 = new wxBoxSizer( wxHORIZONTAL ); + wxCheckBox* checkBox6 = new wxCheckBox(panel, ID_SHOW_TOOLTIPS, "Show &tooltips", wxDefaultPosition, wxDefaultSize); + checkBox6->SetValidator(wxGenericValidator(&m_settingsData.m_showToolTips)); + itemSizer8->Add(checkBox6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + item0->Add(itemSizer8, 0, wxGROW|wxALL, 0); + + topSizer->Add( item0, wxSizerFlags(1).Expand().Border(wxALL, 5) ); + + panel->SetSizerAndFit(topSizer); + + return panel; +} + +wxPanel* SettingsDialog::CreateAestheticSettingsPage(wxWindow* parent) +{ + wxPanel* panel = new wxPanel(parent, wxID_ANY); + + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); + + //// PROJECT OR GLOBAL + wxString globalOrProjectChoices[2]; + globalOrProjectChoices[0] = "&New projects"; + globalOrProjectChoices[1] = "&This project"; + + wxRadioBox* projectOrGlobal = new wxRadioBox(panel, ID_APPLY_SETTINGS_TO, "&Apply settings to:", + wxDefaultPosition, wxDefaultSize, 2, globalOrProjectChoices); + projectOrGlobal->SetValidator(wxGenericValidator(&m_settingsData.m_applyTo)); + item0->Add(projectOrGlobal, 0, wxGROW|wxALL, 5); + + projectOrGlobal->SetSelection(0); + + //// BACKGROUND STYLE + wxArrayString backgroundStyleChoices; + backgroundStyleChoices.Add("Colour"); + backgroundStyleChoices.Add("Image"); + wxStaticBox* staticBox3 = new wxStaticBox(panel, wxID_ANY, "Background style:"); + + wxBoxSizer* styleSizer = new wxStaticBoxSizer( staticBox3, wxVERTICAL ); + item0->Add(styleSizer, 0, wxGROW|wxALL, 5); + + wxBoxSizer* itemSizer2 = new wxBoxSizer( wxHORIZONTAL ); + + wxChoice* choice2 = new wxChoice(panel, ID_BACKGROUND_STYLE, wxDefaultPosition, wxDefaultSize, backgroundStyleChoices); + choice2->SetValidator(wxGenericValidator(&m_settingsData.m_bgStyle)); + + itemSizer2->Add(new wxStaticText(panel, wxID_ANY, "&Window:"), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + itemSizer2->Add(5, 5, 1, wxALL, 0); + itemSizer2->Add(choice2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + styleSizer->Add(itemSizer2, 0, wxGROW|wxALL, 5); + +#if wxUSE_SPINCTRL + //// FONT SIZE SELECTION + + wxStaticBox* staticBox1 = new wxStaticBox(panel, wxID_ANY, "Tile font size:"); + wxBoxSizer* itemSizer5 = new wxStaticBoxSizer( staticBox1, wxHORIZONTAL ); + + wxSpinCtrl* spinCtrl = new wxSpinCtrl(panel, ID_FONT_SIZE, wxEmptyString); + spinCtrl->SetValidator(wxGenericValidator(&m_settingsData.m_titleFontSize)); + itemSizer5->Add(spinCtrl, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + + item0->Add(itemSizer5, 0, wxGROW|wxLEFT|wxRIGHT, 5); +#endif + + topSizer->Add( item0, wxSizerFlags(1).Expand().Border(wxALL, 5) ); + topSizer->AddSpacer(5); + + panel->SetSizerAndFit(topSizer); + + return panel; +} + +#endif // USE_SETTINGS_DIALOG + +#if wxUSE_MSGDLG +// ---------------------------------------------------------------------------- +// TestMessageBoxDialog +// ---------------------------------------------------------------------------- + +/* static */ +const TestMessageBoxDialog::BtnInfo TestMessageBoxDialog::ms_btnInfo[] = +{ + { wxYES, "&Yes" }, + { wxNO, "&No" }, + { wxOK, "&Ok" }, + { wxCANCEL, "&Cancel" }, + { wxHELP, "&Help" }, +}; + +wxBEGIN_EVENT_TABLE(TestMessageBoxDialog, wxDialog) + EVT_BUTTON(wxID_APPLY, TestMessageBoxDialog::OnApply) + EVT_BUTTON(wxID_CLOSE, TestMessageBoxDialog::OnClose) +wxEND_EVENT_TABLE() + +TestMessageBoxDialog::TestMessageBoxDialog(wxWindow *parent) + : wxDialog(parent, wxID_ANY, "Message Box Test Dialog", + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ +} + +bool TestMessageBoxDialog::Create() +{ + wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); + + // this sizer allows to configure the messages shown in the message box + wxSizer * const + sizerMsgs = new wxStaticBoxSizer(wxVERTICAL, this, "&Messages"); + sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Title:")); + m_textTitle = new wxTextCtrl(this, wxID_ANY, "Test Message Box"); + sizerMsgs->Add(m_textTitle, wxSizerFlags().Expand().Border(wxBOTTOM)); + + sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Main message:")); + m_textMsg = new wxTextCtrl(this, wxID_ANY, "Hello from a box!", + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + sizerMsgs->Add(m_textMsg, wxSizerFlags(1).Expand().Border(wxBOTTOM)); + + sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Extended message:")); + m_textExtMsg = new wxTextCtrl(this, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + sizerMsgs->Add(m_textExtMsg, wxSizerFlags().Expand()); + + sizerTop->Add(sizerMsgs, wxSizerFlags(1).Expand().Border()); + + // if a derived class provides more message configurations, add these. + AddAdditionalTextOptions(sizerTop); + + // this one is for configuring the buttons + wxSizer * const + sizerBtnsBox = new wxStaticBoxSizer(wxVERTICAL, this, "&Buttons"); + + wxFlexGridSizer * const sizerBtns = new wxFlexGridSizer(2, 5, 5); + sizerBtns->AddGrowableCol(1); + + sizerBtns->Add(new wxStaticText(this, wxID_ANY, "Button(s)")); + sizerBtns->Add(new wxStaticText(this, wxID_ANY, "Custom label")); + + for ( int n = 0; n < Btn_Max; n++ ) + { + m_buttons[n] = new wxCheckBox(this, wxID_ANY, ms_btnInfo[n].name); + sizerBtns->Add(m_buttons[n], wxSizerFlags().Centre().Left()); + + m_labels[n] = new wxTextCtrl(this, wxID_ANY); + sizerBtns->Add(m_labels[n], wxSizerFlags().Expand()); + + m_labels[n]->Bind(wxEVT_UPDATE_UI, + &TestMessageBoxDialog::OnUpdateLabelUI, this); + } + + sizerBtnsBox->Add(sizerBtns, wxSizerFlags().Expand()); + sizerTop->Add(sizerBtnsBox, wxSizerFlags().Expand().Border()); + + + // icon choice + const wxString icons[] = + { + "&Not specified", + "E&xplicitly none", + "&Information icon", + "&Question icon", + "&Warning icon", + "&Error icon", + "A&uth needed icon" + }; + + wxCOMPILE_TIME_ASSERT( WXSIZEOF(icons) == MsgDlgIcon_Max, IconMismatch ); + + m_icons = new wxRadioBox(this, wxID_ANY, "&Icon style", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(icons), icons, + 2, wxRA_SPECIFY_ROWS); + // Make the 'Information' icon the default one: + m_icons->SetSelection(MsgDlgIcon_Info); + sizerTop->Add(m_icons, wxSizerFlags().Expand().Border()); + + + // miscellaneous other stuff + wxSizer * const + sizerFlags = new wxStaticBoxSizer(wxHORIZONTAL, this, "&Other flags"); + + m_chkNoDefault = new wxCheckBox(this, wxID_ANY, "Make \"No\" &default"); + m_chkNoDefault->Bind(wxEVT_UPDATE_UI, + &TestMessageBoxDialog::OnUpdateNoDefaultUI, this); + sizerFlags->Add(m_chkNoDefault, wxSizerFlags().Border()); + + m_chkCentre = new wxCheckBox(this, wxID_ANY, "Centre on &parent"); + sizerFlags->Add(m_chkCentre, wxSizerFlags().Border()); + + // add any additional flag from subclasses + AddAdditionalFlags(sizerFlags); + + sizerTop->Add(sizerFlags, wxSizerFlags().Expand().Border()); + + // add the currently unused zone for displaying the dialog result + m_labelResult = new wxStaticText(this, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, + wxST_NO_AUTORESIZE | wxALIGN_CENTRE); + m_labelResult->SetForegroundColour(*wxBLUE); + sizerTop->Add(m_labelResult, wxSizerFlags().Expand().DoubleBorder()); + + // finally buttons to show the resulting message box and close this dialog + sizerTop->Add(CreateStdDialogButtonSizer(wxAPPLY | wxCLOSE), + wxSizerFlags().Right().Border()); + + SetSizerAndFit(sizerTop); + + m_buttons[Btn_Ok]->SetValue(true); + + CentreOnScreen(); + + return true; +} + +void TestMessageBoxDialog::OnUpdateLabelUI(wxUpdateUIEvent& event) +{ + for ( int n = 0; n < Btn_Max; n++ ) + { + if ( event.GetEventObject() == m_labels[n] ) + { + event.Enable( m_buttons[n]->IsChecked() ); + return; + } + } + + wxFAIL_MSG( "called for unknown label" ); +} + +void TestMessageBoxDialog::OnUpdateNoDefaultUI(wxUpdateUIEvent& event) +{ + event.Enable( m_buttons[Btn_No]->IsChecked() ); +} + +long TestMessageBoxDialog::GetStyle() +{ + long style = 0; + + for ( int n = 0; n < Btn_Max; n++ ) + { + if ( m_buttons[n]->IsChecked() ) + style |= ms_btnInfo[n].flag; + } + + switch ( m_icons->GetSelection() ) + { + case MsgDlgIcon_Max: + wxFAIL_MSG( "unexpected selection" ); + wxFALLTHROUGH; + + case MsgDlgIcon_No: + break; + + case MsgDlgIcon_None: + style |= wxICON_NONE; + break; + + case MsgDlgIcon_Info: + style |= wxICON_INFORMATION; + break; + + case MsgDlgIcon_Question: + style |= wxICON_QUESTION; + break; + + case MsgDlgIcon_Warning: + style |= wxICON_WARNING; + break; + + case MsgDlgIcon_Error: + style |= wxICON_ERROR; + break; + + case MsgDlgIcon_AuthNeeded: + style |= wxICON_AUTH_NEEDED; + break; + } + + if ( m_chkCentre->IsChecked() ) + style |= wxCENTRE; + + if ( m_chkNoDefault->IsEnabled() && m_chkNoDefault->IsChecked() ) + style |= wxNO_DEFAULT; + + return style; +} + +void TestMessageBoxDialog::PrepareMessageDialog(wxMessageDialogBase &dlg) +{ + long style = dlg.GetMessageDialogStyle(); + + if ( !m_textExtMsg->IsEmpty() ) + dlg.SetExtendedMessage(m_textExtMsg->GetValue()); + + if ( style & wxYES_NO ) + { + if ( style & wxCANCEL ) + { + dlg.SetYesNoCancelLabels(m_labels[Btn_Yes]->GetValue(), + m_labels[Btn_No]->GetValue(), + m_labels[Btn_Cancel]->GetValue()); + } + else + { + dlg.SetYesNoLabels(m_labels[Btn_Yes]->GetValue(), + m_labels[Btn_No]->GetValue()); + } + } + else + { + if ( style & wxCANCEL ) + { + dlg.SetOKCancelLabels(m_labels[Btn_Ok]->GetValue(), + m_labels[Btn_Cancel]->GetValue()); + } + else + { + dlg.SetOKLabel(m_labels[Btn_Ok]->GetValue()); + } + } + + if ( style & wxHELP ) + { + dlg.SetHelpLabel(m_labels[Btn_Help]->GetValue()); + } +} + +void TestMessageBoxDialog::OnApply(wxCommandEvent& WXUNUSED(event)) +{ + wxMessageDialog dlg(this, GetMessage(), GetBoxTitle(), GetStyle()); + PrepareMessageDialog(dlg); + + ShowResult(dlg.ShowModal()); +} + +void TestMessageBoxDialog::ShowResult(int res) +{ + wxString btnName; + switch ( res ) + { + case wxID_OK: + btnName = "OK"; + break; + + case wxID_CANCEL: + btnName = "Cancel"; + break; + + case wxID_YES: + btnName = "Yes"; + break; + + case wxID_NO: + btnName = "No"; + break; + + case wxID_HELP: + btnName = "Help"; + break; + + default: + btnName = "Unknown"; + } + + m_labelResult->SetLabel( + wxString::Format("Dialog was closed with the \"%s\" button.", btnName) + ); +} + +void TestMessageBoxDialog::OnClose(wxCommandEvent& WXUNUSED(event)) +{ + EndModal(wxID_CANCEL); +} +#endif // wxUSE_MSGDLG + +#if wxUSE_RICHMSGDLG +// ---------------------------------------------------------------------------- +// TestRichMessageDialog +// ---------------------------------------------------------------------------- + +wxBEGIN_EVENT_TABLE(TestRichMessageDialog, TestMessageBoxDialog) + EVT_BUTTON(wxID_APPLY, TestRichMessageDialog::OnApply) +wxEND_EVENT_TABLE() + +TestRichMessageDialog::TestRichMessageDialog(wxWindow *parent) + : TestMessageBoxDialog(parent) +{ + SetTitle("Rich Message Dialog Test Dialog"); +} + +void TestRichMessageDialog::AddAdditionalTextOptions(wxSizer *sizer) +{ + wxSizer * const sizerMsgs = new wxStaticBoxSizer(wxVERTICAL, this, + "&Additional Elements"); + + // add an option to show a check box. + wxSizer * const sizerCheckBox = new wxBoxSizer(wxHORIZONTAL); + sizerCheckBox->Add(new wxStaticText(this, wxID_ANY, "&Check box:"), + wxSizerFlags().Centre().Border(wxRIGHT)); + m_textCheckBox = new wxTextCtrl(this, wxID_ANY); + sizerCheckBox->Add(m_textCheckBox, wxSizerFlags(1).Centre()); + sizerMsgs->Add(sizerCheckBox, wxSizerFlags().Expand().Border(wxBOTTOM)); + + // add option to show a detailed text. + sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Detailed message:")); + m_textDetailed = new wxTextCtrl(this, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + sizerMsgs->Add(m_textDetailed, wxSizerFlags().Expand()); + + // add option to show footer text + wxSizer * const sizerFooter = new wxBoxSizer(wxHORIZONTAL); + sizerFooter->Add(new wxStaticText(this, wxID_ANY, "&Footer Text:"), + wxSizerFlags().Centre().Border(wxRIGHT)); + m_textFooter = new wxTextCtrl(this, wxID_ANY); + sizerFooter->Add(m_textFooter, wxSizerFlags(1).Centre()); + + // add option to select footer icon + const wxString icons[] = + { + "None", + "Info", + "Warning", + "Error", + "Auth needed" + }; + + sizerFooter->Add(new wxStaticText(this, wxID_ANY, "Icon:"), + wxSizerFlags().Centre().Border(wxLEFT)); + m_iconsFooter = new wxChoice(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(icons), icons); + // Make the None the default: + m_iconsFooter->SetSelection(0); + sizerFooter->Add(m_iconsFooter, wxSizerFlags().Expand().Border()); + + sizerMsgs->Add(sizerFooter, wxSizerFlags().Expand().Border(wxTOP)); + + sizer->Add(sizerMsgs, wxSizerFlags().Expand().Border()); +} + +void TestRichMessageDialog::AddAdditionalFlags(wxSizer *sizer) +{ + // add checkbox to set the initial state for the checkbox shown + // in the dialog. + m_initialValueCheckBox = + new wxCheckBox(this, wxID_ANY, "Checkbox initially checked"); + sizer->Add(m_initialValueCheckBox, wxSizerFlags().Border()); +} + +void TestRichMessageDialog::OnApply(wxCommandEvent& WXUNUSED(event)) +{ + wxRichMessageDialog dlg(this, GetMessage(), GetBoxTitle(), GetStyle()); + PrepareMessageDialog(dlg); + + dlg.ShowCheckBox(m_textCheckBox->GetValue(), + m_initialValueCheckBox->GetValue()); + dlg.ShowDetailedText(m_textDetailed->GetValue()); + dlg.SetFooterText(m_textFooter->GetValue()); + switch ( m_iconsFooter->GetSelection() ) + { + case 1: + dlg.SetFooterIcon(wxICON_INFORMATION); + break; + + case 2: + dlg.SetFooterIcon(wxICON_WARNING); + break; + + case 3: + dlg.SetFooterIcon(wxICON_ERROR); + break; + + case 4: + dlg.SetFooterIcon(wxICON_AUTH_NEEDED); + break; + } + + ShowResult(dlg.ShowModal()); +} + +#endif // wxUSE_RICHMSGDLG + +#if wxUSE_LOG + +// ---------------------------------------------------------------------------- +// custom log target +// ---------------------------------------------------------------------------- + +class MyLogGui : public wxLogGui +{ +private: + virtual void DoShowSingleLogMessage(const wxString& message, + const wxString& title, + int style) wxOVERRIDE + { + wxMessageDialog dlg(NULL, message, title, + wxOK | wxCANCEL | wxCANCEL_DEFAULT | style); + dlg.SetOKCancelLabels(wxID_COPY, wxID_OK); + dlg.SetExtendedMessage("Note that this is a custom log dialog."); + dlg.ShowModal(); + } +}; + +wxLog *MyAppTraits::CreateLogTarget() +{ + return new MyLogGui; +} + +#endif // wxUSE_LOG diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h new file mode 100644 index 0000000..963d93f --- /dev/null +++ b/samples/dialogs/dialogs.h @@ -0,0 +1,321 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dialogs.h +// Purpose: Common dialogs demo +// Author: Julian Smart, Vadim Zeitlin, ABX +// Created: 04/01/98 +// Copyright: (c) Julian Smart +// (c) 2004 ABX +// (c) Vadim Zeitlin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +/* +This sample shows how to use the common dialogs available from wxWidgets. +It also shows that generic implementations of common dialogs can be exchanged +with native dialogs and can coexist in one application. The need for generic +dialogs addition is recognized thanks to setup of below USE_*** setting. Their +combinations reflects conditions of makefiles and project files to avoid unresolved +references during linking. For now some generic dialogs are added in static builds +of MSW, MAC and OS2 +*/#pragma once +#ifndef __DIALOGSH__ +#define __DIALOGSH__ +#endif + +#ifdef __WXUNIVERSAL__ + #define USE_WXUNIVERSAL 1 +#else + #define USE_WXUNIVERSAL 0 +#endif + +#ifdef WXUSINGDLL + #define USE_DLL 1 +#else + #define USE_DLL 0 +#endif + +#if defined(__WXMSW__) + #define USE_WXMSW 1 +#else + #define USE_WXMSW 0 +#endif + +#ifdef __WXMAC__ + #define USE_WXMAC 1 +#else + #define USE_WXMAC 0 +#endif + +#if USE_NATIVE_FONT_DIALOG_FOR_MACOSX + #define USE_WXMACFONTDLG 1 +#else + #define USE_WXMACFONTDLG 0 +#endif + +#ifdef __WXGTK__ + #define USE_WXGTK 1 +#else + #define USE_WXGTK 0 +#endif + +#define USE_GENERIC_DIALOGS (!USE_WXUNIVERSAL && !USE_DLL) + +#define USE_COLOURDLG_GENERIC \ + ((USE_WXMSW || USE_WXMAC) && USE_GENERIC_DIALOGS && wxUSE_COLOURDLG) +#define USE_DIRDLG_GENERIC \ + ((USE_WXMSW || USE_WXMAC) && USE_GENERIC_DIALOGS && wxUSE_DIRDLG) +#define USE_FILEDLG_GENERIC \ + ((USE_WXMSW || USE_WXMAC) && USE_GENERIC_DIALOGS && wxUSE_FILEDLG) +#define USE_FONTDLG_GENERIC \ + ((USE_WXMSW || USE_WXMACFONTDLG) && USE_GENERIC_DIALOGS && wxUSE_FONTDLG) + +// Turn USE_MODAL_PRESENTATION to 0 if there is any reason for not presenting difference +// between modal and modeless dialogs (ie. not implemented it in your port yet) +#if !wxUSE_BOOKCTRL + #define USE_MODAL_PRESENTATION 0 +#else + #define USE_MODAL_PRESENTATION 1 +#endif + + +// Turn USE_SETTINGS_DIALOG to 0 if supported +#if wxUSE_BOOKCTRL + #define USE_SETTINGS_DIALOG 1 +#else + #define USE_SETTINGS_DIALOG 0 +#endif + +#if USE_MODAL_PRESENTATION + +// A custom modeless dialog +class MyModelessDialog : public wxDialog +{ +public: + MyModelessDialog(wxWindow *parent); + + void OnButton(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +private: + wxDECLARE_EVENT_TABLE(); +}; + +// A custom modal dialog +class MyModalDialog : public wxDialog +{ +public: + MyModalDialog(wxWindow *parent); + + void OnButton(wxCommandEvent& event); + +private: + wxButton *m_btnModal, + *m_btnModeless, + *m_btnDelete; + + wxDECLARE_EVENT_TABLE(); +}; + +#endif // USE_MODAL_PRESENTATION + +// A class demonstrating CreateStdDialogButtonSizer() +class StdButtonSizerDialog : public wxDialog +{ +public: + StdButtonSizerDialog(wxWindow *parent); + + void OnEvent(wxCommandEvent& event); + +private: + void EnableDisableControls(); + + wxCheckBox *m_chkboxAffirmativeButton; + wxRadioButton *m_radiobtnOk, + *m_radiobtnYes; + + wxCheckBox *m_chkboxDismissButton; + wxRadioButton *m_radiobtnClose, + *m_radiobtnCancel; + + wxCheckBox *m_chkboxApply, + *m_chkboxNo, + *m_chkboxHelp, + *m_chkboxNoDefault; + + wxSizer *m_buttonsSizer; + + wxDECLARE_EVENT_TABLE(); +}; + +// Test harness for wxMessageDialog. +class TestMessageBoxDialog : public wxDialog +{ +public: + TestMessageBoxDialog(wxWindow *parent); + + bool Create(); + +protected: + wxString GetBoxTitle() { return m_textTitle->GetValue(); } + wxString GetMessage() { return m_textMsg->GetValue(); } + long GetStyle(); + + void PrepareMessageDialog(wxMessageDialogBase &dlg); + + virtual void AddAdditionalTextOptions(wxSizer *WXUNUSED(sizer)) { } + virtual void AddAdditionalFlags(wxSizer *WXUNUSED(sizer)) { } + + void ShowResult(int res); + + void OnApply(wxCommandEvent& event); + void OnClose(wxCommandEvent& event); + void OnUpdateLabelUI(wxUpdateUIEvent& event); + void OnUpdateNoDefaultUI(wxUpdateUIEvent& event); + +private: + enum + { + Btn_Yes, + Btn_No, + Btn_Ok, + Btn_Cancel, + Btn_Help, + Btn_Max + }; + + struct BtnInfo + { + int flag; + const char *name; + }; + + static const BtnInfo ms_btnInfo[Btn_Max]; + + enum + { + MsgDlgIcon_No, + MsgDlgIcon_None, + MsgDlgIcon_Info, + MsgDlgIcon_Question, + MsgDlgIcon_Warning, + MsgDlgIcon_Error, + MsgDlgIcon_AuthNeeded, + MsgDlgIcon_Max + }; + + wxTextCtrl *m_textTitle, + *m_textMsg, + *m_textExtMsg; + + wxCheckBox *m_buttons[Btn_Max]; + wxTextCtrl *m_labels[Btn_Max]; + + wxRadioBox *m_icons; + + wxCheckBox *m_chkNoDefault, + *m_chkCentre; + + wxStaticText *m_labelResult; + + wxDECLARE_EVENT_TABLE(); + wxDECLARE_NO_COPY_CLASS(TestMessageBoxDialog); +}; + +#if wxUSE_RICHMSGDLG +class TestRichMessageDialog : public TestMessageBoxDialog +{ +public: + TestRichMessageDialog(wxWindow *parent); + +protected: + // overrides method in base class + virtual void AddAdditionalTextOptions(wxSizer *sizer) wxOVERRIDE; + virtual void AddAdditionalFlags(wxSizer *sizer) wxOVERRIDE; + + void OnApply(wxCommandEvent& event); + +private: + wxTextCtrl *m_textCheckBox; + wxCheckBox *m_initialValueCheckBox; + wxTextCtrl *m_textDetailed; + wxTextCtrl *m_textFooter; + wxChoice *m_iconsFooter; + + wxDECLARE_EVENT_TABLE(); +}; +#endif // wxUSE_RICHMSGDLG + +class TestDefaultActionDialog: public wxDialog +{ +public: + TestDefaultActionDialog( wxWindow *parent ); + + void OnListBoxDClick(wxCommandEvent& event); + void OnDisableOK(wxCommandEvent& event); + void OnDisableCancel(wxCommandEvent& event); + void OnCatchListBoxDClick(wxCommandEvent& event); + void OnTextEnter(wxCommandEvent& event); + +private: + bool m_catchListBoxDClick; + +private: + wxDECLARE_EVENT_TABLE(); +}; + + +#if USE_SETTINGS_DIALOG + +// Struct containing properties edited by SettingsDialog. +struct SettingsData +{ + SettingsData() : + m_loadLastOnStartup(false), + m_autoSaveInterval(1), + m_showToolTips(false), + m_applyTo(0), + m_bgStyle(0), + m_titleFontSize(10) + { + } + + bool m_loadLastOnStartup; + int m_autoSaveInterval; + bool m_showToolTips; + int m_applyTo; + int m_bgStyle; + int m_titleFontSize; +}; + +// Property sheet dialog +class SettingsDialog: public wxPropertySheetDialog +{ + wxDECLARE_CLASS(SettingsDialog); +public: + SettingsDialog(wxWindow* parent, SettingsData& settingsData, int dialogType); + ~SettingsDialog(); + + wxPanel* CreateGeneralSettingsPage(wxWindow* parent); + wxPanel* CreateAestheticSettingsPage(wxWindow* parent); + +protected: + + enum { + ID_SHOW_TOOLTIPS = 100, + ID_AUTO_SAVE, + ID_AUTO_SAVE_MINS, + ID_LOAD_LAST_PROJECT, + + ID_APPLY_SETTINGS_TO, + ID_BACKGROUND_STYLE, + ID_FONT_SIZE + }; + + wxImageList* m_imageList; + + SettingsData& m_settingsData; + + wxDECLARE_EVENT_TABLE(); +}; + +#endif // USE_SETTINGS_DIALOG diff --git a/samples/dialogs/dialogs.rc b/samples/dialogs/dialogs.rc new file mode 100644 index 0000000..20867a3 --- /dev/null +++ b/samples/dialogs/dialogs.rc @@ -0,0 +1,21 @@ +// This is wxWidgets style resource file. ;; +// The visual studio resource editor will screw it up. +#pragma code_page(65001) // UTF-8 +// this icon is used with wxFrame::SetIcon() +AAArho ICON "../../docs/rho.ico" + +// set this to 1 if you don't want to use manifest resource provided by wxWidgets. +// An aplication manifest is needed for the application UI to look properly and other +// things - see docs/msw/winxp.md for more information) +#define wxUSE_NO_MANIFEST 0 + +// to enable full High DPI suppport, we need to opt in into Per-Monitor (V2) DPI awareness, +// see section Issues/MSW in programming guide High DPI Support in wxWidgets +#ifndef wxUSE_DPI_AWARE_MANIFEST +#define wxUSE_DPI_AWARE_MANIFEST 2 +#endif + +// this file contains the standard icons, cursors etc. and also includes the application +// manifest mentioned above +#include "../../wxWidgets/include/wx/msw/wx.rc" + diff --git a/samples/dialogs/dialogs.sln b/samples/dialogs/dialogs.sln new file mode 100644 index 0000000..9f73eaa --- /dev/null +++ b/samples/dialogs/dialogs.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34031.279 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dialogs", "dialogs.vcxproj", "{8241F179-E1E6-5760-8B4F-5CE0D518BE5B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8241F179-E1E6-5760-8B4F-5CE0D518BE5B}.Debug|x64.ActiveCfg = Debug|x64 + {8241F179-E1E6-5760-8B4F-5CE0D518BE5B}.Debug|x64.Build.0 = Debug|x64 + {8241F179-E1E6-5760-8B4F-5CE0D518BE5B}.Release|x64.ActiveCfg = Release|x64 + {8241F179-E1E6-5760-8B4F-5CE0D518BE5B}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5B093A83-6CDF-4178-AE13-7F0D562446D0} + EndGlobalSection +EndGlobal diff --git a/samples/dialogs/dialogs.vcxproj b/samples/dialogs/dialogs.vcxproj new file mode 100644 index 0000000..9a592ae --- /dev/null +++ b/samples/dialogs/dialogs.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {8241F179-E1E6-5760-8B4F-5CE0D518BE5B} + 10.0 + + + + Application + v143 + false + Unicode + + + Application + v143 + false + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34031.279 + + + ..\..\build\$(Configuration)\ + ..\..\build\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\build\$(Configuration)\ + ..\..\build\$(Configuration)\$(ProjectName)\ + false + false + true + + + + WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + ../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + + + /MP /Zc:__cplusplus /utf-8 %(AdditionalOptions) + Disabled + ../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + Sync + EnableFastChecks + MultiThreadedDebugDLL + true + true + Level4 + true + ProgramDatabase + Use + stdcpp20 + stdc17 + + + _DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + 0x0409 + ../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + + + wxmsw32ud_core.lib;wxbase32ud.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;wxregexud.lib;wxexpatd.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;winspool.lib;winmm.lib;shell32.lib;shlwapi.lib;comctl32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;advapi32.lib;version.lib;ws2_32.lib;wininet.lib;%(AdditionalDependencies) + true + ../..\wxWidgets\lib\vc_x64_lib;%(AdditionalLibraryDirectories) + true + ../../build/Debug/dialogs.pdb + Windows + MachineX64 + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib %(AdditionalOptions) + + + true + + + + + WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + ../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + + + /MP /Zc:__cplusplus /utf-8 %(AdditionalOptions) + MaxSpeed + ../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + Sync + MultiThreadedDLL + true + Level4 + true + ProgramDatabase + stdcpp20 + stdc17 + Use + + + _CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions) + 0x0409 + ../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories) + + + wxmsw32u_core.lib;wxbase32u.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;winspool.lib;winmm.lib;shell32.lib;shlwapi.lib;comctl32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;advapi32.lib;version.lib;ws2_32.lib;wininet.lib;%(AdditionalDependencies) + true + ../..\wxWidgets\lib\vc_x64_lib;%(AdditionalLibraryDirectories) + true + ../../build/Release/dialogs.pdb + Windows + MachineX64 + true + true + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib %(AdditionalOptions) + + + true + + + + + Use + Use + + + Use + Use + + + Use + Use + + + Create + Create + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/dialogs/frame.cpp b/samples/dialogs/frame.cpp new file mode 100644 index 0000000..5492ae2 --- /dev/null +++ b/samples/dialogs/frame.cpp @@ -0,0 +1,3222 @@ +#include "stdafx.h" + +wxBEGIN_EVENT_TABLE(Frame, wxFrame) +#if wxUSE_MSGDLG +EVT_MENU(DIALOGS_MESSAGE_BOX, Frame::MessageBox) +EVT_MENU(DIALOGS_MESSAGE_DIALOG, Frame::MessageBoxDialog) +EVT_MENU(DIALOGS_MESSAGE_BOX_WXINFO, Frame::MessageBoxInfo) +#endif // wxUSE_MSGDLG +#if wxUSE_RICHMSGDLG +EVT_MENU(DIALOGS_RICH_MESSAGE_DIALOG, Frame::RichMessageDialog) +#endif // wxUSE_RICHMSGDLG +#if wxUSE_COLOURDLG +EVT_MENU(DIALOGS_CHOOSE_COLOUR, Frame::ChooseColour) +EVT_MENU(DIALOGS_CHOOSE_COLOUR_ALPHA, Frame::ChooseColour) +EVT_MENU(DIALOGS_GET_COLOUR, Frame::GetColour) +#endif // wxUSE_COLOURDLG + +#if wxUSE_FONTDLG +EVT_MENU(DIALOGS_CHOOSE_FONT, Frame::ChooseFont) +#endif // wxUSE_FONTDLG + +#if wxUSE_LOG_DIALOG +EVT_MENU(DIALOGS_LOG_DIALOG, Frame::LogDialog) +#endif // wxUSE_LOG_DIALOG +#if wxUSE_INFOBAR +EVT_MENU(DIALOGS_INFOBAR_SIMPLE, Frame::InfoBarSimple) +EVT_MENU(DIALOGS_INFOBAR_SIMPLE_WRAPPED, Frame::InfoBarSimpleWrapped) +EVT_MENU(DIALOGS_INFOBAR_ADVANCED, Frame::InfoBarAdvanced) +#endif // wxUSE_INFOBAR + +#if wxUSE_TEXTDLG +EVT_MENU(DIALOGS_LINE_ENTRY, Frame::LineEntry) +EVT_MENU(DIALOGS_TEXT_ENTRY, Frame::TextEntry) +EVT_MENU(DIALOGS_PASSWORD_ENTRY, Frame::PasswordEntry) +#endif // wxUSE_TEXTDLG + +#if wxUSE_CREDENTIALDLG +EVT_MENU(DIALOGS_CREDENTIAL_ENTRY, Frame::CredentialEntry) +#endif // wxUSE_CREDENTIALDLG + +#if wxUSE_NUMBERDLG +EVT_MENU(DIALOGS_NUM_ENTRY, Frame::NumericEntry) +#endif // wxUSE_NUMBERDLG + +#if wxUSE_CHOICEDLG +EVT_MENU(DIALOGS_SINGLE_CHOICE, Frame::SingleChoice) +EVT_MENU(DIALOGS_MULTI_CHOICE, Frame::MultiChoice) +#endif // wxUSE_CHOICEDLG + +#if wxUSE_REARRANGECTRL +EVT_MENU(DIALOGS_REARRANGE, Frame::Rearrange) +#endif // wxUSE_REARRANGECTRL + +#if wxUSE_ADDREMOVECTRL +EVT_MENU(DIALOGS_ADDREMOVE, Frame::AddRemove) +#endif // wxUSE_ADDREMOVECTRL + +#if wxUSE_FILEDLG +EVT_MENU(DIALOGS_FILE_OPEN, Frame::OnFileOpen) +EVT_MENU(DIALOGS_FILE_OPEN2, Frame::FileOpen2) +EVT_MENU(DIALOGS_FILES_OPEN, Frame::FilesOpen) +EVT_MENU(DIALOGS_FILE_SAVE, Frame::OnSaveNew) +EVT_MENU(DIALOGS_MAC_TOGGLE_ALWAYS_SHOW_TYPES, Frame::MacToggleAlwaysShowTypes) +#endif // wxUSE_FILEDLG + +#if wxUSE_DIRDLG +EVT_MENU(DIALOGS_DIR_CHOOSE, Frame::DirChoose) +EVT_MENU(DIALOGS_DIRNEW_CHOOSE, Frame::DirChooseNew) +EVT_MENU(DIALOGS_DIRMULTIPLE_CHOOSE, Frame::DirChooseMultiple) +#endif // wxUSE_DIRDLG + +#if USE_MODAL_PRESENTATION +EVT_MENU(DIALOGS_MODAL, Frame::ModalDlg) +#endif // USE_MODAL_PRESENTATION +EVT_MENU(DIALOGS_MODELESS, Frame::ModelessDlg) +EVT_MENU(DIALOGS_CENTRE_SCREEN, Frame::DlgCenteredScreen) +EVT_MENU(DIALOGS_CENTRE_PARENT, Frame::DlgCenteredParent) +#if wxUSE_MINIFRAME +EVT_MENU(DIALOGS_MINIFRAME, Frame::MiniFrame) +#endif // wxUSE_MINIFRAME +EVT_MENU(DIALOGS_ONTOP, Frame::DlgOnTop) + +#if wxUSE_STARTUP_TIPS +EVT_MENU(DIALOGS_TIP, Frame::ShowTip) +#endif // wxUSE_STARTUP_TIPS + +#if wxUSE_ABOUTDLG +EVT_MENU(DIALOGS_ABOUTDLG_SIMPLE, Frame::ShowSimpleAboutDialog) +EVT_MENU(DIALOGS_ABOUTDLG_FANCY, Frame::ShowFancyAboutDialog) +EVT_MENU(DIALOGS_ABOUTDLG_FULL, Frame::ShowFullAboutDialog) +EVT_MENU(DIALOGS_ABOUTDLG_CUSTOM, Frame::ShowCustomAboutDialog) +#endif // wxUSE_ABOUTDLG + +#if wxUSE_BUSYINFO +EVT_MENU(DIALOGS_BUSYINFO, Frame::ShowBusyInfo) +EVT_MENU(DIALOGS_BUSYINFO_RICH, Frame::ShowRichBusyInfo) +#endif // wxUSE_BUSYINFO + +#if wxUSE_FINDREPLDLG +EVT_MENU(DIALOGS_FIND, Frame::ShowFindDialog) +EVT_MENU(DIALOGS_REPLACE, Frame::ShowReplaceDialog) + +EVT_FIND(wxID_ANY, Frame::OnFindDialog) +EVT_FIND_NEXT(wxID_ANY, Frame::OnFindDialog) +EVT_FIND_REPLACE(wxID_ANY, Frame::OnFindDialog) +EVT_FIND_REPLACE_ALL(wxID_ANY, Frame::OnFindDialog) +EVT_FIND_CLOSE(wxID_ANY, Frame::OnFindDialog) +#endif // wxUSE_FINDREPLDLG + +#if USE_SETTINGS_DIALOG +EVT_MENU(DIALOGS_PROPERTY_SHEET, Frame::OnPropertySheet) +EVT_MENU(DIALOGS_PROPERTY_SHEET_TOOLBOOK, Frame::OnPropertySheet) +EVT_MENU(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, Frame::OnPropertySheet) +#endif // USE_SETTINGS_DIALOG + +EVT_MENU(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, Frame::OnStandardButtonsSizerDialog) +EVT_MENU(DIALOGS_TEST_DEFAULT_ACTION, Frame::OnTestDefaultActionDialog) +EVT_MENU(DIALOGS_MODAL_HOOK, Frame::OnModalHook) +EVT_MENU(DIALOGS_SIMULATE_UNSAVED, Frame::OnSimulatedUnsaved) + +EVT_MENU(DIALOGS_REQUEST, Frame::OnRequestUserAttention) +#if wxUSE_NOTIFICATION_MESSAGE +EVT_MENU(DIALOGS_NOTIFY_MSG, Frame::OnNotifMsg) +#endif // wxUSE_NOTIFICATION_MESSAGE + +#if wxUSE_TIPWINDOW +EVT_MENU(DIALOGS_SHOW_TIP, Frame::OnShowTip) +EVT_UPDATE_UI(DIALOGS_SHOW_TIP, Frame::OnUpdateShowTipUI) +#endif // wxUSE_TIPWINDOW +#if wxUSE_RICHTOOLTIP +EVT_MENU(DIALOGS_RICHTIP_DIALOG, Frame::OnRichTipDialog) +#endif // wxUSE_RICHTOOLTIP + +EVT_MENU(wxID_EXIT, Frame::OnExit) +EVT_CLOSE(Frame::OnClose) +wxEND_EVENT_TABLE() + +void Frame::RestorePositionFromConfig(const wxSize& bestSize) { + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig) { + // SetPath() understands ".." but you should probably never use it. + pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; + // restore frame position and size + int x = pConfig->ReadLong(wxT("x"), scr.x / 4); + int y = pConfig->ReadLong(wxT("y"), scr.y / 4); + int w = pConfig->ReadLong(wxT("w"), scr.x / 2); + int h = pConfig->ReadLong(wxT("h"), scr.y / 2); + w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9); + h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5); + x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12)); + y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10)); + this->Move(x, y); + this->Maximize(pConfig->ReadBool(wxT("Maximized"), false)); + this->SetSize(w, h); + pConfig->SetPath(wxT("/TipOfTheDay")); + m_showTipsAtStartup = pConfig->Read("show", true); + m_TipOfTheDayIndex = pConfig->Read("index", int(-1)); + pConfig->SetPath(wxT("/FileDialog")); + m_FileDialogFilterIndex = pConfig->Read("index", int(0)); + m_strLastUsedFile=pConfig->Read("LastUsed",wxEmptyString).utf8_str(); + pConfig->SetPath(wxT("/")); + } +} + +void Frame::StorePositionToConfig() { + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig) { + pConfig->SetPath(wxT("/MainFrame")); + if (this->IsMaximized()) { + pConfig->Write(wxT("Maximized"), true); + } + else { + // save the frame position + int x, y, w, h; + this->GetSize(&w, &h); + this->GetPosition(&x, &y); + pConfig->Write(wxT("x"), (long)x); + pConfig->Write(wxT("y"), (long)y); + pConfig->Write(wxT("w"), (long)w); + pConfig->Write(wxT("h"), (long)h); + pConfig->Write(wxT("Maximized"), false); + } + pConfig->SetPath(wxT("/")); + } +} + +// My frame constructor +Frame::Frame(const wxString& title) + : wxFrame(NULL, wxID_ANY, title), m_confirmExit(false) +{ + SetIcon(wxICON(sample)); + +#if USE_MODAL_PRESENTATION + m_dialog = (MyModelessDialog*)NULL; +#endif // USE_MODAL_PRESENTATION + +#if wxUSE_FINDREPLDLG + m_dlgFind = + m_dlgReplace = NULL; +#endif + +#if wxUSE_COLOURDLG + m_clrData.SetChooseFull(true); + for (int i = 0; i < wxColourData::NUM_CUSTOM; i++) + { + unsigned char n = i * 16; + m_clrData.SetCustomColour(i, wxColour(n, n, n)); + } +#endif // wxUSE_COLOURDLG + +#if wxUSE_STATUSBAR + CreateStatusBar(); +#endif // wxUSE_STATUSBAR + + m_canvas = new MyCanvas(this); + +#if wxUSE_INFOBAR + // an info bar can be created very simply and used without any extra effort + m_infoBarSimple = new wxInfoBar(this); + + // or it can also be customized by + m_infoBarAdvanced = new wxInfoBar(this); + + // ... adding extra buttons (but more than two will usually be too many) + m_infoBarAdvanced->AddButton(wxID_UNDO); + m_infoBarAdvanced->AddButton(wxID_REDO); + + m_infoBarAdvanced->Bind(wxEVT_BUTTON, &Frame::OnInfoBarRedo, this, + wxID_REDO); + + // adding and removing a button immediately doesn't make sense here, of + // course, it's done just to show that it is possible + m_infoBarAdvanced->AddButton(wxID_EXIT); + m_infoBarAdvanced->RemoveButton(wxID_EXIT); + + // ... changing the colours and/or fonts + m_infoBarAdvanced->SetOwnBackgroundColour(0xc8ffff); + m_infoBarAdvanced->SetForegroundColour(0x123312); + m_infoBarAdvanced->SetFont(GetFont().Bold().Larger()); + + // ... and changing the effect (only does anything under MSW currently) + m_infoBarAdvanced->SetShowHideEffects(wxSHOW_EFFECT_EXPAND, + wxSHOW_EFFECT_EXPAND); + m_infoBarAdvanced->SetEffectDuration(1500); + + + // to use the info bars we need to use sizer for the window layout + wxBoxSizer* const sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(m_infoBarSimple, wxSizerFlags().Expand()); + sizer->Add(m_canvas, wxSizerFlags(1).Expand()); + sizer->Add(m_infoBarAdvanced, wxSizerFlags().Expand()); + SetSizer(sizer); + + // final touch: under MSW the info bars are shown progressively and parts + // of the parent window can be seen during the process, so use the same + // background colour for our background as for the canvas window which + // covers our entire client area to avoid jarring colour jumps + SetOwnBackgroundColour(m_canvas->GetBackgroundColour()); + wxMenuBar* menuBar = new wxMenuBar; + + SetIcon(wxICON(AAArho)); //Does not appear to do anything. Maybe it does something in Unix. + //wxICON is a namestring on windows, and a symbol on Unix + wxMenu* menuFile = new wxMenu; + menuFile->Append(wxID_OPEN, "&Open file\tCtrl-O"); + menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN); + menuFile->Append(wxID_NEW, "Sa&ve file\tCtrl-S"); + menuFile->Bind(wxEVT_MENU, &Frame::OnSaveNew, this, wxID_NEW); + menuFile->Append(wxID_EXIT); + menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); + + menuBar->Append(menuFile, "&File"); + + // Make a menubar + wxMenu* menuDlg = new wxMenu; + + menuDlg->Append(DIALOGS_MESSAGE_BOX, "&Message box\tCtrl-M"); + menuDlg->Append(DIALOGS_MESSAGE_DIALOG, "Message dialog\tShift-Ctrl-M"); +#if wxUSE_RICHMSGDLG + menuDlg->Append(DIALOGS_RICH_MESSAGE_DIALOG, "Rich message dialog"); +#endif // wxUSE_RICHMSGDLG + + +#if wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG + + wxMenu* choices_menu = new wxMenu; + +#if wxUSE_COLOURDLG + wxMenu* choices_bg_colour = new wxMenu; + choices_bg_colour->Append(DIALOGS_CHOOSE_COLOUR, "&No opacity"); + choices_bg_colour->Append(DIALOGS_CHOOSE_COLOUR_ALPHA, "&With opacity"); + choices_menu->Append(wxID_ANY, "&Choose bg colour", choices_bg_colour); + choices_menu->Append(DIALOGS_GET_COLOUR, "&Choose fg colour"); +#endif // wxUSE_COLOURDLG + +#if wxUSE_FONTDLG + choices_menu->Append(DIALOGS_CHOOSE_FONT, "Choose &font\tShift-Ctrl-N"); +#endif // wxUSE_FONTDLG + +#if wxUSE_CHOICEDLG + choices_menu->Append(DIALOGS_SINGLE_CHOICE, "&Single choice\tCtrl-C"); + choices_menu->Append(DIALOGS_MULTI_CHOICE, "M&ultiple choice\tCtrl-U"); +#endif // wxUSE_CHOICEDLG + +#if wxUSE_REARRANGECTRL + choices_menu->Append(DIALOGS_REARRANGE, "&Rearrange dialog\tCtrl-R"); +#endif // wxUSE_REARRANGECTRL + +#if wxUSE_ADDREMOVECTRL + choices_menu->Append(DIALOGS_ADDREMOVE, "&Add/remove items control\tCtrl-A"); +#endif // wxUSE_ADDREMOVECTRL + + menuDlg->Append(wxID_ANY, "&Choices and selectors", choices_menu); +#endif // wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG + + +#if wxUSE_TEXTDLG || wxUSE_NUMBERDLG || wxUSE_CREDENTIALDLG + + wxMenu* entry_menu = new wxMenu; + +#if wxUSE_TEXTDLG + entry_menu->Append(DIALOGS_LINE_ENTRY, "Single line &entry\tCtrl-E"); + entry_menu->Append(DIALOGS_TEXT_ENTRY, "Multi line text &entry\tShift-Ctrl-E"); + entry_menu->Append(DIALOGS_PASSWORD_ENTRY, "&Password entry\tCtrl-P"); +#endif // wxUSE_TEXTDLG + +#if wxUSE_CREDENTIALDLG + entry_menu->Append(DIALOGS_CREDENTIAL_ENTRY, "&Credential entry\tShift-Ctrl-C"); +#endif // wxUSE_CREDENTIALDLG + +#if wxUSE_NUMBERDLG + entry_menu->Append(DIALOGS_NUM_ENTRY, "&Numeric entry\tCtrl-N"); +#endif // wxUSE_NUMBERDLG + + menuDlg->Append(wxID_ANY, "&Entry dialogs", entry_menu); + +#endif // wxUSE_TEXTDLG || wxUSE_NUMBERDLG + + +#if wxUSE_FILEDLG + + wxMenu* filedlg_menu = new wxMenu; + filedlg_menu->Append(DIALOGS_FILE_OPEN2, "&Second open file\tCtrl-2"); + filedlg_menu->Append(DIALOGS_FILES_OPEN, "Open &files\tShift-Ctrl-O"); + + filedlg_menu->AppendSeparator(); + filedlg_menu->AppendRadioItem( + DIALOGS_FILE_USE_CUSTOMIZER, + "Use new customization API", + "Use wxFileDialog::SetCustomizeHook() for file dialog customization" + ); + filedlg_menu->AppendRadioItem( + DIALOGS_FILE_USE_EXTRA_CONTROL_CREATOR, + "Use old customization API", + "Use wxFileDialog::SetExtraControlCreator() for file dialog customization" + ); +#ifdef __WXOSX_COCOA__ + filedlg_menu->AppendSeparator(); + filedlg_menu->AppendCheckItem(DIALOGS_MAC_TOGGLE_ALWAYS_SHOW_TYPES, + "macOS only: Toggle open file " + "\"Always show types\"\tRawCtrl+Ctrl+S"); +#endif + + menuDlg->Append(wxID_ANY, "&File operations", filedlg_menu); + +#endif // wxUSE_FILEDLG + +#if wxUSE_DIRDLG + wxMenu* dir_menu = new wxMenu; + + dir_menu->Append(DIALOGS_DIR_CHOOSE, "&Choose a directory\tCtrl-D"); + dir_menu->Append(DIALOGS_DIRNEW_CHOOSE, "Choose a directory (with \"Ne&w\" button)\tShift-Ctrl-D"); + dir_menu->Append(DIALOGS_DIRMULTIPLE_CHOOSE, "Choose multiple and hidden directories\tAlt-Ctrl-D"); + menuDlg->Append(wxID_ANY, "&Directory operations", dir_menu); + +#endif // wxUSE_DIRDLG + + +#if wxUSE_STARTUP_TIPS || \ + wxUSE_PROGRESSDLG || \ + wxUSE_BUSYINFO || \ + wxUSE_LOG_DIALOG || \ + wxUSE_MSGDLG + + wxMenu* info_menu = new wxMenu; + +#if wxUSE_STARTUP_TIPS + info_menu->Append(DIALOGS_TIP, "&Tip of the day\tCtrl-T"); +#endif // wxUSE_STARTUP_TIPS + +#if wxUSE_LOG_DIALOG + info_menu->Append(DIALOGS_LOG_DIALOG, "&Log dialog\tCtrl-L"); +#endif // wxUSE_LOG_DIALOG + +#if wxUSE_INFOBAR + info_menu->Append(DIALOGS_INFOBAR_SIMPLE, "Simple &info bar\tCtrl-I"); + info_menu->Append(DIALOGS_INFOBAR_SIMPLE_WRAPPED, "Simple info bar with wrapped text"); + info_menu->Append(DIALOGS_INFOBAR_ADVANCED, "&Advanced info bar\tShift-Ctrl-I"); +#endif // wxUSE_INFOBAR + +#if wxUSE_MSGDLG + info_menu->Append(DIALOGS_MESSAGE_BOX_WXINFO, + "&wxWidgets information\tCtrl-W"); +#endif // wxUSE_MSGDLG + + menuDlg->Append(wxID_ANY, "&Informative dialogs", info_menu); + +#endif // wxUSE_STARTUP_TIPS || wxUSE_PROGRESSDLG || wxUSE_BUSYINFO || wxUSE_LOG_DIALOG + + +#if wxUSE_FINDREPLDLG + wxMenu* find_menu = new wxMenu; + find_menu->AppendCheckItem(DIALOGS_FIND, "&Find dialog\tCtrl-F"); + find_menu->AppendCheckItem(DIALOGS_REPLACE, "Find and &replace dialog\tShift-Ctrl-F"); + menuDlg->Append(wxID_ANY, "&Searching", find_menu); +#endif // wxUSE_FINDREPLDLG + + wxMenu* dialogs_menu = new wxMenu; +#if USE_MODAL_PRESENTATION + dialogs_menu->Append(DIALOGS_MODAL, "&Modal dialog\tShift-Ctrl-W"); +#endif // USE_MODAL_PRESENTATION + dialogs_menu->AppendCheckItem(DIALOGS_MODELESS, "Mode&less dialog\tShift-Ctrl-Z"); + dialogs_menu->Append(DIALOGS_CENTRE_SCREEN, "Centered on &screen\tShift-Ctrl-1"); + dialogs_menu->Append(DIALOGS_CENTRE_PARENT, "Centered on &parent\tShift-Ctrl-2"); +#if wxUSE_MINIFRAME + dialogs_menu->Append(DIALOGS_MINIFRAME, "&Mini frame"); +#endif // wxUSE_MINIFRAME + dialogs_menu->Append(DIALOGS_ONTOP, "Dialog staying on &top"); + menuDlg->Append(wxID_ANY, "&Generic dialogs", dialogs_menu); + +#if USE_SETTINGS_DIALOG + wxMenu* sheet_menu = new wxMenu; + sheet_menu->Append(DIALOGS_PROPERTY_SHEET, "&Standard property sheet\tShift-Ctrl-P"); + sheet_menu->Append(DIALOGS_PROPERTY_SHEET_TOOLBOOK, "&Toolbook sheet\tShift-Ctrl-T"); + + if (wxPlatformIs(wxPORT_MAC)) + sheet_menu->Append(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, "Button &Toolbook sheet\tShift-Ctrl-U"); + /* + #ifdef __WXMAC__ + sheet_menu->Append(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, "Button &Toolbook sheet\tShift-Ctrl-U"); + #endif + */ + menuDlg->Append(wxID_ANY, "&Property sheets", sheet_menu); +#endif // USE_SETTINGS_DIALOG + + wxMenu* menuNotif = new wxMenu; + menuNotif->Append(DIALOGS_REQUEST, "&Request user attention\tCtrl-Shift-R"); +#if wxUSE_NOTIFICATION_MESSAGE + menuNotif->AppendSeparator(); + menuNotif->Append(DIALOGS_NOTIFY_MSG, "User &Notification\tCtrl-Shift-N"); +#endif // wxUSE_NOTIFICATION_MESSAGE + menuDlg->AppendSubMenu(menuNotif, "&User notifications"); + +#if wxUSE_TIPWINDOW + menuDlg->AppendCheckItem(DIALOGS_SHOW_TIP, "Show &tip window\tShift-Ctrl-H"); +#endif // wxUSE_TIPWINDOW + +#if wxUSE_RICHTOOLTIP + menuDlg->Append(DIALOGS_RICHTIP_DIALOG, "Rich &tooltip dialog...\tCtrl-H"); + menuDlg->AppendSeparator(); +#endif // wxUSE_RICHTOOLTIP + + menuDlg->Append(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, "&Standard Buttons Sizer Dialog"); + menuDlg->Append(DIALOGS_TEST_DEFAULT_ACTION, "&Test dialog default action"); + menuDlg->AppendCheckItem(DIALOGS_MODAL_HOOK, "Enable modal dialog hook"); + menuDlg->AppendCheckItem(DIALOGS_SIMULATE_UNSAVED, "Simulate an unsaved document at exit"); + + menuDlg->AppendSeparator(); + menuDlg->Append(wxID_EXIT, "E&xit\tAlt-X"); + +#if wxUSE_ABOUTDLG + wxMenu* menuHelp = new wxMenu; + menuHelp->Append(DIALOGS_ABOUTDLG_SIMPLE, "&About (simple)...\tF1"); + menuHelp->Append(DIALOGS_ABOUTDLG_FANCY, "About (&fancy)...\tShift-F1"); + menuHelp->Append(DIALOGS_ABOUTDLG_FULL, "About (f&ull)...\tCtrl-F1"); + menuHelp->Append(DIALOGS_ABOUTDLG_CUSTOM, "About (&custom)...\tCtrl-Shift-F1"); +#endif // wxUSE_ABOUTDLG + + wxMenu* editMenu = new wxMenu; + editMenu->Append(wxID_UNDO, "&Undo\tCtrl+Z"); + editMenu->Append(wxID_REDO, "&Redo\tCtrl+Y"); + editMenu->AppendSeparator(); + editMenu->Append(wxID_CUT, "Cu&t\tCtrl+X"); + editMenu->Append(wxID_COPY, "&Copy\tCtrl+C"); + editMenu->Append(wxID_PASTE, "&Paste\tCtrl+V"); + editMenu->Append(wxID_CLEAR, "&Delete"); + + editMenu->AppendSeparator(); + editMenu->Append(wxID_SELECTALL, "Select All\tCtrl+A"); + + //wxMenuBar* menubar = frame->GetMenuBar(); + menuBar->Append(menuDlg, "&Dialogs"); + + menuBar->Append(editMenu, "&Edit"); + +#if wxUSE_ABOUTDLG + menuBar->Append(menuHelp, "&Help"); +#endif // wxUSE_ABOUTDLG + + SetMenuBar(menuBar); + this->SetMenuBar(menuBar); +#endif // wxUSE_INFOBAR + +#if wxUSE_TIPWINDOW + m_tipWindow = NULL; +#endif // wxUSE_TIPWINDOW + +#ifdef __WXMSW__ + // Test MSW-specific function allowing to access the "system" menu. + wxMenu* const menu = MSWGetSystemMenu(); + if (menu) + { + menu->AppendSeparator(); + + // The ids of the menu commands in MSW system menu must be multiple of + // 16 so we can't use DIALOGS_ABOUTDLG_SIMPLE here because it might not + // satisfy this condition and need to define and connect a separate id. + static const int DIALOGS_SYSTEM_ABOUT = 0x4010; + + menu->Append(DIALOGS_SYSTEM_ABOUT, "&About"); + Bind(wxEVT_MENU, &Frame::ShowSimpleAboutDialog, this, + DIALOGS_SYSTEM_ABOUT); + + } + this->RestorePositionFromConfig(ClientToWindowSize(m_canvas->GetBestSize())); + SetClientSize(GetClientSize()); +#endif // __WXMSW__ +} + +#if wxUSE_COLOURDLG + +void Frame::DoApplyColour(const wxColour& colour) +{ + if (colour == m_canvas->GetBackgroundColour()) + return; + + m_canvas->SetBackgroundColour(colour); + m_canvas->ClearBackground(); + m_canvas->Refresh(); +} + +void Frame::OnColourChanged(wxColourDialogEvent& event) +{ + DoApplyColour(event.GetColour()); +} + +void Frame::ChooseColour(wxCommandEvent& event) +{ + m_clrData.SetColour(m_canvas->GetBackgroundColour()); + m_clrData.SetChooseAlpha(event.GetId() == DIALOGS_CHOOSE_COLOUR_ALPHA); + + wxColourDialog dialog(this, &m_clrData); + dialog.Bind(wxEVT_COLOUR_CHANGED, &Frame::OnColourChanged, this); + dialog.SetTitle("Please choose the background colour"); + if (dialog.ShowModal() == wxID_OK) + { + m_clrData = dialog.GetColourData(); + } + + DoApplyColour(m_clrData.GetColour()); +} + +void Frame::GetColour(wxCommandEvent& WXUNUSED(event)) +{ + wxColour clr = wxGetColourFromUser + ( + this, + m_canvas->GetForegroundColour(), + "Please choose the foreground colour" + ); + if (clr.IsOk()) + { + m_canvas->SetForegroundColour(clr); + m_canvas->Refresh(); + } + //else: dialog cancelled by user +} + +#endif // wxUSE_COLOURDLG + +#if wxUSE_FONTDLG +void Frame::ChooseFont(wxCommandEvent& WXUNUSED(event)) +{ + wxFontData data; + data.SetInitialFont(m_canvas->GetFont()); + data.SetColour(m_canvas->GetForegroundColour()); + + // you might also do this: + // + // wxFontDialog dialog; + // if ( !dialog.Create(this, data) { ... error ... } + // + wxFontDialog dialog(this, data); + + if (dialog.ShowModal() == wxID_OK) + { + wxFontData retData = dialog.GetFontData(); + m_canvas->SetFont(retData.GetChosenFont()); + m_canvas->SetForegroundColour(retData.GetColour()); + m_canvas->Refresh(); + } + //else: cancelled by the user, don't change the font +} +#endif // wxUSE_FONTDLG + +#if wxUSE_LOG_DIALOG +void Frame::LogDialog(wxCommandEvent& WXUNUSED(event)) +{ + // calling wxYield() (as ~wxBusyCursor does) shouldn't result in messages + // being flushed -- test it + { + wxBusyCursor bc; + wxLogMessage("This is some message - everything is ok so far."); + wxLogMessage("Another message...\n... this one is on multiple lines"); + wxLogWarning("And then something went wrong!"); + + // and if ~wxBusyCursor doesn't do it, then call it manually + wxYield(); + } + + wxLogError("Intermediary error handler decided to abort."); + wxLogError("The top level caller detected an unrecoverable error."); + + wxLog::FlushActive(); + + wxLogMessage("And this is the same dialog but with only one message."); +} +#endif // wxUSE_LOG_DIALOG + +#if wxUSE_INFOBAR + +void Frame::InfoBarSimple(wxCommandEvent& WXUNUSED(event)) +{ + static int s_count = 0; + m_infoBarSimple->ShowMessage + ( + wxString::Format("Message #%d in the info bar.", ++s_count) + ); +} + +void Frame::InfoBarSimpleWrapped(wxCommandEvent& WXUNUSED(event)) +{ + m_infoBarSimple->ShowMessage("This is very very long message to try the label wrapping on the info bar"); +} + +void Frame::InfoBarAdvanced(wxCommandEvent& WXUNUSED(event)) +{ + m_infoBarAdvanced->ShowMessage("Sorry, it didn't work out.", wxICON_WARNING); +} + +void Frame::OnInfoBarRedo(wxCommandEvent& WXUNUSED(event)) +{ + m_infoBarAdvanced->ShowMessage("Still no, sorry again.", wxICON_ERROR); +} + +#endif // wxUSE_INFOBAR + + +#if wxUSE_MSGDLG +void Frame::MessageBox(wxCommandEvent& WXUNUSED(event)) +{ + wxMessageDialog dialog(this, + "This is a message box\n" + "This is a long, long string to test out if the message box " + "is laid out properly.", + "Message box text", + wxCENTER | + wxNO_DEFAULT | wxYES_NO | wxCANCEL | + wxICON_INFORMATION); + + wxString extmsg; + if (dialog.SetYesNoCancelLabels + ( + "Answer &Yes", + "Answer &No", + "Refuse to answer" + )) + { + extmsg = "This platform supports custom button labels,\n" + "so you should see the descriptive labels below."; + } + else + { + extmsg = "Custom button labels are not supported on this platform,\n" + "so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used."; + } + dialog.SetExtendedMessage(extmsg); + + switch (dialog.ShowModal()) + { + case wxID_YES: + wxLogStatus("You pressed \"Yes\""); + break; + + case wxID_NO: + wxLogStatus("You pressed \"No\""); + break; + + case wxID_CANCEL: + wxLogStatus("You pressed \"Cancel\""); + break; + + default: + wxLogError("Unexpected wxMessageDialog return code!"); + } +} + +void Frame::MessageBoxWindowModal(wxCommandEvent& WXUNUSED(event)) +{ + wxMessageDialog* dialog = new wxMessageDialog(this, + "This is a message box\n" + "This is a long, long string to test out if the message box " + "is laid out properly.", + "Message box text", + wxCENTER | + wxNO_DEFAULT | wxYES_NO | wxCANCEL | + wxICON_INFORMATION); + + wxString extmsg; + if (dialog->SetYesNoCancelLabels + ( + "Answer &Yes", + "Answer &No", + "Refuse to answer" + )) + { + extmsg = "This platform supports custom button labels,\n" + "so you should see the descriptive labels below."; + } + else + { + extmsg = "Custom button labels are not supported on this platform,\n" + "so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used."; + } + dialog->SetExtendedMessage(extmsg); + dialog->Bind(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, + &Frame::MessageBoxWindowModalClosed, this); + dialog->ShowWindowModal(); +} + +void Frame::MessageBoxWindowModalClosed(wxWindowModalDialogEvent& event) +{ + wxDialog* dialog = event.GetDialog(); + switch (dialog->GetReturnCode()) + { + case wxID_YES: + wxLogStatus("You pressed \"Yes\""); + break; + + case wxID_NO: + wxLogStatus("You pressed \"No\""); + break; + + case wxID_CANCEL: + wxLogStatus("You pressed \"Cancel\""); + break; + + default: + wxLogError("Unexpected wxMessageDialog return code!"); + } + delete dialog; +} + +void Frame::MessageBoxDialog(wxCommandEvent& WXUNUSED(event)) +{ + TestMessageBoxDialog dlg(this); + dlg.Create(); + dlg.ShowModal(); +} + +void Frame::MessageBoxDialogWindowModal(wxCommandEvent& WXUNUSED(event)) +{ + TestMessageBoxDialog* dlg = new TestMessageBoxDialog(this); + dlg->Create(); + dlg->ShowWindowModal(); +} + +void Frame::MessageBoxDialogWindowModalClosed(wxWindowModalDialogEvent& event) +{ + TestMessageBoxDialog* dialog = dynamic_cast(event.GetDialog()); + delete dialog; +} + + +void Frame::MessageBoxInfo(wxCommandEvent& WXUNUSED(event)) +{ + ::wxInfoMessageBox(this); +} +#endif // wxUSE_MSGDLG + +#if wxUSE_RICHMSGDLG +void Frame::RichMessageDialog(wxCommandEvent& WXUNUSED(event)) +{ + TestRichMessageDialog dlg(this); + dlg.Create(); + dlg.ShowModal(); +} +#endif // wxUSE_RICHMSGDLG + +#if wxUSE_NUMBERDLG +void Frame::NumericEntry(wxCommandEvent& WXUNUSED(event)) +{ + long res = wxGetNumberFromUser("This is some text, actually a lot of text.\n" + "Even two rows of text.", + "Enter a number:", "Numeric input test", + 50, 0, 100, this); + + wxString msg; + int icon; + if (res == -1) + { + msg = "Invalid number entered or dialog cancelled."; + icon = wxICON_HAND; + } + else + { + msg.Printf("You've entered %lu", res); + icon = wxICON_INFORMATION; + } + + wxMessageBox(msg, "Numeric test result", wxOK | icon, this); +} +#endif // wxUSE_NUMBERDLG + +#if wxUSE_TEXTDLG +void Frame::PasswordEntry(wxCommandEvent& WXUNUSED(event)) +{ + wxString pwd = wxGetPasswordFromUser("Enter password:", + "Password entry dialog", + wxEmptyString, + this); + if (!pwd.empty()) + { + wxMessageBox(wxString::Format("Your password is '%s'", pwd), + "Got password", wxOK | wxICON_INFORMATION, this); + } +} + +void Frame::LineEntry(wxCommandEvent& WXUNUSED(event)) +{ + wxTextEntryDialog dialog(this, + "This is a small sample\n" + "A long, long string to test out the text entrybox", + "Please enter a string", + "Default value", + wxOK | wxCANCEL); + + if (dialog.ShowModal() == wxID_OK) + { + wxMessageBox(dialog.GetValue(), "Got string", wxOK | wxICON_INFORMATION, this); + } +} + +void Frame::TextEntry(wxCommandEvent& WXUNUSED(event)) +{ + wxTextEntryDialog dialog(this, "You can enter a multiline string here.", + "Please enter some text", + "First line\nSecond one\nAnd another one too", + wxOK | wxCANCEL | wxTE_MULTILINE); + + if (dialog.ShowModal() == wxID_OK) + { + wxMessageBox(dialog.GetValue(), "Got text", wxOK | wxICON_INFORMATION, this); + } +} +#endif // wxUSE_TEXTDLG + +#if wxUSE_CREDENTIALDLG +void Frame::CredentialEntry(wxCommandEvent& WXUNUSED(event)) +{ + wxCredentialEntryDialog dialog(this, "A login is required", "Credentials"); + if (dialog.ShowModal() == wxID_OK) + { + const wxWebCredentials credentials = dialog.GetCredentials(); + const wxString& password = wxSecretString(credentials.GetPassword()); + wxMessageBox + ( + wxString::Format + ( + "User: %s Password: %s", + credentials.GetUser(), + password + ), + "Credentials", + wxOK | wxICON_INFORMATION, + this + ); + } +} +#endif // wxUSE_CREDENTIALDLG + +#if wxUSE_CHOICEDLG +void Frame::SingleChoice(wxCommandEvent& WXUNUSED(event)) +{ + const wxString choices[] = { "One", "Two", "Three", "Four", "Five" }; + + wxSingleChoiceDialog dialog(this, + "This is a small sample\n" + "A single-choice convenience dialog", + "Please select a value", + WXSIZEOF(choices), choices); + + dialog.SetSelection(2); + + if (dialog.ShowModal() == wxID_OK) + { + wxMessageDialog dialog2(this, dialog.GetStringSelection(), "Got string"); + dialog2.ShowModal(); + } +} + +void Frame::MultiChoice(wxCommandEvent& WXUNUSED(event)) +{ + const wxString choices[] = + { + "One", "Two", "Three", "Four", "Five", + "Six", "Seven", "Eight", "Nine", "Ten", + "Eleven", "Twelve", "Seventeen", + }; + + wxArrayInt selections; + const int count = wxGetSelectedChoices(selections, + "This is a small sample\n" + "A multi-choice convenience dialog", + "Please select a value", + WXSIZEOF(choices), choices, + this); + if (count >= 0) + { + wxString msg; + if (count == 0) + { + msg = "You did not select any items"; + } + else + { + msg.Printf("You selected %u items:\n", (unsigned)count); + for (int n = 0; n < count; n++) + { + msg += wxString::Format("\t%u: %u (%s)\n", + (unsigned)n, (unsigned)selections[n], + choices[selections[n]]); + } + } + wxLogMessage(msg); + } + //else: cancelled +} +#endif // wxUSE_CHOICEDLG + +#if wxUSE_REARRANGECTRL +// custom rearrange dialog: it adds the possibility to rename an item to the +// base class functionality +class MyRearrangeDialog : public wxRearrangeDialog +{ +public: + MyRearrangeDialog(wxWindow* parent, + wxArrayInt& order, + wxArrayString& labels, + wxArrayString& labelsOrig) + : wxRearrangeDialog + ( + parent, + "Configure the columns shown:", + "wxRearrangeDialog example", + order, + labels + ), + m_order(order), + m_labels(labels), + m_labelsOrig(labelsOrig) + { + m_sel = wxNOT_FOUND; + + wxPanel* const panel = new wxPanel(this); + wxSizer* const sizer = new wxBoxSizer(wxHORIZONTAL); + + m_labelOrig = new wxStaticText(panel, wxID_ANY, ""); + sizer->Add(m_labelOrig, wxSizerFlags().Centre().Border(wxRIGHT)); + + m_text = new wxTextCtrl(panel, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, + wxTE_PROCESS_ENTER); + sizer->Add(m_text, wxSizerFlags().Centre().Border(wxRIGHT)); + + sizer->Add(new wxButton(panel, wxID_APPLY, "&Rename"), + wxSizerFlags().Centre()); + + panel->SetSizer(sizer); + + // call this first to ensure that the controls have a reasonable best + // size before they're added + DoUpdateExtraControls(GetList()->GetSelection()); + + AddExtraControls(panel); + + + // another customization not directly supported by the dialog: add a + // custom button + wxWindow* const btnOk = FindWindow(wxID_OK); + wxCHECK_RET(btnOk, "no Ok button?"); + + wxSizer* const sizerBtns = btnOk->GetContainingSizer(); + wxCHECK_RET(sizerBtns, "no buttons sizer?"); + + sizerBtns->Add(new wxButton(this, wxID_RESET, "&Reset all"), + wxSizerFlags().Border(wxLEFT)); + } + + // call this instead of ShowModal() to update order and labels array in + // case the dialog was not cancelled + bool Rearrange() + { + switch (ShowModal()) + { + case wxID_CANCEL: + return false; + + case wxID_OK: + m_order = GetOrder(); + break; + + case wxID_RESET: + // order already reset + break; + } + + return true; + } + +private: + void OnSelChange(wxCommandEvent& event) + { + DoUpdateExtraControls(event.GetInt()); + } + + void OnUpdateUIRename(wxUpdateUIEvent& event) + { + event.Enable(CanRename()); + } + + void OnRename(wxCommandEvent& WXUNUSED(event)) + { + if (!CanRename()) + return; + + m_labels[m_sel] = m_text->GetValue(); + GetList()->SetString(m_sel, m_labels[m_sel]); + } + + void OnReset(wxCommandEvent& WXUNUSED(event)) + { + // in a real program we should probably ask if the user really wants to + // do this but here we just go ahead and reset all columns labels and + // their order without confirmation + const unsigned count = m_order.size(); + for (unsigned n = 0; n < count; n++) + { + m_order[n] = n; + m_labels[n] = m_labelsOrig[n]; + } + + EndModal(wxID_RESET); + } + + bool CanRename() const + { + // only allow renaming if the user modified the currently selected item + // text (which presupposes that we do have a current item) + return m_sel != wxNOT_FOUND && m_text->GetValue() != m_labels[m_sel]; + } + + void DoUpdateExtraControls(int sel) + { + m_sel = sel; + + if (m_sel == wxNOT_FOUND) + { + m_labelOrig->SetLabel(""); + m_text->Clear(); + m_text->Disable(); + } + else // have valid item + { + m_labelOrig->SetLabelText(m_labelsOrig[m_sel]); + m_text->Enable(); + m_text->SetValue(m_labels[m_sel]); + } + } + + wxArrayInt& m_order; + wxArrayString& m_labels, + m_labelsOrig; + + int m_sel; + wxStaticText* m_labelOrig; + wxTextCtrl* m_text; + + wxDECLARE_EVENT_TABLE(); + wxDECLARE_NO_COPY_CLASS(MyRearrangeDialog); +}; + +wxBEGIN_EVENT_TABLE(MyRearrangeDialog, wxRearrangeDialog) +EVT_LISTBOX(wxID_ANY, MyRearrangeDialog::OnSelChange) + +EVT_UPDATE_UI(wxID_APPLY, MyRearrangeDialog::OnUpdateUIRename) + +EVT_TEXT_ENTER(wxID_ANY, MyRearrangeDialog::OnRename) +EVT_BUTTON(wxID_APPLY, MyRearrangeDialog::OnRename) +EVT_BUTTON(wxID_RESET, MyRearrangeDialog::OnReset) +wxEND_EVENT_TABLE() + +void Frame::Rearrange(wxCommandEvent& WXUNUSED(event)) +{ + // the arrays are static so that we preserve the items order between calls + // to this function + static wxArrayInt s_order; + static wxArrayString s_labels, + s_labelsOrig; + + // initialize them on the first call + if (s_labelsOrig.empty()) + { + static const struct ItemInfo + { + const char* label; + const char* labelOrig; + int order; + } items[] = + { + { "File name", "Name", 0 }, + { "File type", "Ext", 1 }, + { "Size", "Size", 2 }, + { "Creation time", "Ctime", ~3 }, // negated so hidden + { "Last accessed", "Atime", ~4 }, + { "Last modified", "Mtime", 5 }, + }; + + s_order.reserve(WXSIZEOF(items)); + s_labels.reserve(WXSIZEOF(items)); + s_labelsOrig.reserve(WXSIZEOF(items)); + for (unsigned n = 0; n < WXSIZEOF(items); n++) + { + const ItemInfo& item = items[n]; + s_order.push_back(item.order); + s_labels.push_back(item.label); + s_labelsOrig.push_back(item.labelOrig); + } + } + + MyRearrangeDialog dlg(this, s_order, s_labels, s_labelsOrig); + if (!dlg.Rearrange()) + return; + + wxString columns; + for (unsigned n = 0; n < s_order.size(); n++) + { + columns += wxString::Format("\n %u: ", n); + int idx = s_order[n]; + if (idx < 0) + { + columns += "[hidden] "; + idx = ~idx; + } + + columns += s_labels[idx]; + if (s_labels[idx] != s_labelsOrig[idx]) + { + columns += wxString::Format(" (original label: \"%s\")", + s_labelsOrig[idx]); + } + } + + wxLogMessage("The columns order now is:%s", columns); +} +#endif // wxUSE_REARRANGECTRL + +#if wxUSE_ADDREMOVECTRL + +void Frame::AddRemove(wxCommandEvent& WXUNUSED(event)) +{ + wxDialog dlg(this, wxID_ANY, "wxAddRemoveCtrl test", + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + wxAddRemoveCtrl* const ctrl = new wxAddRemoveCtrl(&dlg); + ctrl->SetInitialSize(wxSize(-1, 12 * GetCharHeight())); + + const wxString items[] = + { + "some", "items", "for", "testing", "wxAddRemoveCtrl", + }; + wxListBox* const lbox = new wxListBox(ctrl, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(items), items); + + // Test adaptor class connecting wxAddRemoveCtrl with wxListBox we use + // inside it. + class ListBoxAdaptor : public wxAddRemoveAdaptor + { + public: + explicit ListBoxAdaptor(wxListBox* lbox) + : m_lbox(lbox) + { + } + + wxWindow* GetItemsCtrl() const wxOVERRIDE + { + return m_lbox; + } + + bool CanAdd() const wxOVERRIDE + { + // Restrict the maximal number of items to 10 just for testing. + return m_lbox->GetCount() <= 10; + } + + bool CanRemove() const wxOVERRIDE + { + // We must have a selected item in order to be able to delete it. + return m_lbox->GetSelection() != wxNOT_FOUND; + } + + void OnAdd() wxOVERRIDE + { + // A real program would use a wxDataViewCtrl or wxListCtrl and + // allow editing the newly edited item in place, here we just use a + // hardcoded item value instead. + static int s_item = 0; + m_lbox->Append(wxString::Format("new item #%d", ++s_item)); + } + + void OnRemove() wxOVERRIDE + { + // Notice that we don't need to check if we have a valid selection, + // we can be only called if CanRemove(), which already checks for + // this, had returned true. + const unsigned pos = m_lbox->GetSelection(); + + m_lbox->Delete(pos); + m_lbox->SetSelection(pos == m_lbox->GetCount() ? pos - 1 : pos); + } + + private: + wxListBox* const m_lbox; + }; + + ctrl->SetAdaptor(new ListBoxAdaptor(lbox)); + + ctrl->SetButtonsToolTips("Add up to 10 items", "Remove current item"); + + wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL); + sizerTop->Add(ctrl, wxSizerFlags(1).Expand().Border()); + sizerTop->Add(dlg.CreateStdDialogButtonSizer(wxOK | wxCANCEL), + wxSizerFlags().Expand().Border()); + dlg.SetSizerAndFit(sizerTop); + + dlg.ShowModal(); +} + +#endif // wxUSE_ADDREMOVECTRL + +#if wxUSE_FILEDLG + +// Simple function showing the current wxFileDialog state. +wxString GetFileDialogStateDescription(wxFileDialogBase* dialog) +{ + const wxString fn = dialog->GetCurrentlySelectedFilename(); + + wxString msg; + if (fn.empty()) + msg = "Nothing"; + else if (wxFileName::FileExists(fn)) + msg = "File"; + else if (wxFileName::DirExists(fn)) + msg = "Directory"; + else + msg = "Something else"; + + msg += " selected"; + + const int filter = dialog->GetCurrentlySelectedFilterIndex(); + if (filter != wxNOT_FOUND) + msg += wxString::Format(" (filter=%d)", filter); + + return msg; +} + +// Another helper translating demo combobox selection. +wxString GetFileDialogPaperSize(int selection) +{ + switch (selection) + { + case -1: return ""; + case 0: return "A4"; + case 1: return "Letter"; + default: return "INVALID"; + } +} + +// panel with custom controls for file dialog +class MyExtraPanel : public wxPanel +{ +public: + MyExtraPanel(wxWindow* parent); + wxString GetInfo() const + { + return wxString::Format("paper=%s (%s), enabled=%d, text=\"%s\"", + m_paperSize, m_paperOrient, m_checked, m_str); + } + +private: + void OnCheckBox(wxCommandEvent& event) + { + m_checked = event.IsChecked(); + m_btn->Enable(m_checked); + } + + void OnRadioButton(wxCommandEvent& event) + { + if (event.GetEventObject() == m_radioPortrait) + m_paperOrient = "portrait"; + else if (event.GetEventObject() == m_radioLandscape) + m_paperOrient = "landscape"; + else + m_paperOrient = "unknown"; + } + + void OnChoice(wxCommandEvent& event) + { + m_paperSize = GetFileDialogPaperSize(event.GetSelection()); + } + + void OnText(wxCommandEvent& event) + { + m_str = event.GetString(); + } + + void OnUpdateLabelUI(wxUpdateUIEvent& event) + { + // In this sample, the dialog may be either wxFileDialog itself, or + // wxGenericFileDialog, so we need to cast to the base class. In a + // typical application, we would cast to just wxFileDialog instead. + wxFileDialogBase* const dialog = wxStaticCast(GetParent(), wxFileDialogBase); + + event.SetText(GetFileDialogStateDescription(dialog)); + } + + wxString m_str; + bool m_checked; + wxString m_paperSize; + wxString m_paperOrient; + + wxButton* m_btn; + wxCheckBox* m_cb; + wxRadioButton* m_radioPortrait; + wxRadioButton* m_radioLandscape; + wxStaticText* m_label; + wxTextCtrl* m_text; +}; + +MyExtraPanel::MyExtraPanel(wxWindow* parent) + : wxPanel(parent), + m_str("extra text"), + m_checked(false) +{ + m_btn = new wxButton(this, -1, "Custom Button"); + m_btn->Enable(false); + m_cb = new wxCheckBox(this, -1, "Enable Custom Button"); + m_cb->Bind(wxEVT_CHECKBOX, &MyExtraPanel::OnCheckBox, this); + wxChoice* choiceSize = new wxChoice(this, wxID_ANY); + choiceSize->Append("A4"); + choiceSize->Append("Letter"); + choiceSize->Bind(wxEVT_CHOICE, &MyExtraPanel::OnChoice, this); + m_radioPortrait = new wxRadioButton(this, wxID_ANY, "&Portrait", + wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + m_radioPortrait->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this); + m_radioLandscape = new wxRadioButton(this, wxID_ANY, "&Landscape"); + m_radioLandscape->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this); + m_label = new wxStaticText(this, wxID_ANY, "Nothing selected"); + m_label->Bind(wxEVT_UPDATE_UI, &MyExtraPanel::OnUpdateLabelUI, this); + + m_text = new wxTextCtrl(this, -1, m_str, + wxDefaultPosition, wxSize(40 * GetCharWidth(), -1)); + m_text->Bind(wxEVT_TEXT, &MyExtraPanel::OnText, this); + + wxBoxSizer* sizerTop = new wxBoxSizer(wxHORIZONTAL); + sizerTop->Add(new wxStaticText(this, wxID_ANY, "Just some extra text:"), + wxSizerFlags().Centre().Border()); + sizerTop->Add(m_text, wxSizerFlags(1).Centre().Border()); + sizerTop->AddSpacer(10); + sizerTop->Add(choiceSize, wxSizerFlags().Centre().Border(wxRIGHT)); + sizerTop->Add(m_radioPortrait, wxSizerFlags().Centre().Border()); + sizerTop->Add(m_radioLandscape, wxSizerFlags().Centre().Border()); + sizerTop->Add(m_cb, wxSizerFlags().Centre().Border()); + sizerTop->AddSpacer(5); + sizerTop->Add(m_btn, wxSizerFlags().Centre().Border()); + sizerTop->AddSpacer(5); + sizerTop->Add(m_label, wxSizerFlags(1).Centre().Border()); + + SetSizerAndFit(sizerTop); +} + +// a static method can be used instead of a function with most of compilers +static wxWindow* createMyExtraPanel(wxWindow* parent) +{ + return new MyExtraPanel(parent); +} + +// This class does the same thing as MyExtraPanel above, but uses newer API for +// wxFileDialog customization. +class MyCustomizeHook : public wxFileDialogCustomizeHook +{ +public: + // Normally we would just use wxFileDialog, but this sample allows using + // both the real wxFileDialog and wxGenericFileDialog, so allow passing + // either of them here. + explicit MyCustomizeHook(wxFileDialogBase& dialog) + : m_dialog(&dialog) + { + } + + // Override pure virtual base class method to add our custom controls. + virtual void AddCustomControls(wxFileDialogCustomize& customizer) wxOVERRIDE + { + // Note: all the pointers created here cease to be valid once + // ShowModal() returns, TransferDataFromCustomControls() is the latest + // moment when they can still be used. + m_text = customizer.AddTextCtrl("Just some extra text:"); + const wxString sizes[] = { "A4", "Letter" }; + m_choiceSize = customizer.AddChoice(WXSIZEOF(sizes), sizes); + m_radioPortrait = customizer.AddRadioButton("&Portrait"); + m_radioLandscape = customizer.AddRadioButton("&Landscape"); + m_cb = customizer.AddCheckBox("Enable Custom Button"); + m_cb->Bind(wxEVT_CHECKBOX, &MyCustomizeHook::OnCheckBox, this); + m_btn = customizer.AddButton("Custom Button"); + m_btn->Bind(wxEVT_BUTTON, &MyCustomizeHook::OnButton, this); + m_label = customizer.AddStaticText("Nothing selected"); + } + + // Override another method called whenever something changes in the dialog. + virtual void UpdateCustomControls() wxOVERRIDE + { + // Enable the button if and only if the checkbox is checked. + m_btn->Enable(m_cb->GetValue()); + + // Enable radio buttons only if a file is selected. + bool hasFile = wxFileName::FileExists( + m_dialog->GetCurrentlySelectedFilename() + ); + m_radioPortrait->Enable(hasFile); + m_radioLandscape->Enable(hasFile); + + // Also show the current dialog state. + m_label->SetLabelText(GetFileDialogStateDescription(m_dialog)); + } + + // And another one called when the dialog is accepted. + virtual void TransferDataFromCustomControls() wxOVERRIDE + { + m_info.Printf("paper=%s (%s), enabled=%d, text=\"%s\"", + GetFileDialogPaperSize(m_choiceSize->GetSelection()), + m_radioPortrait->GetValue() ? "portrait" : "landscape", + m_cb->GetValue(), m_text->GetValue()); + } + + + // This is just a helper function allowing to show the values of the custom + // controls. + wxString GetInfo() const { return m_info; } + +private: + void OnCheckBox(wxCommandEvent& event) + { + m_btn->Enable(event.IsChecked()); + } + + void OnButton(wxCommandEvent& WXUNUSED(event)) + { + wxMessageBox("Custom button pressed", "wxWidgets dialogs sample", + wxOK | wxICON_INFORMATION, m_dialog); + } + + wxFileDialogBase* const m_dialog; + + wxFileDialogButton* m_btn; + wxFileDialogCheckBox* m_cb; + wxFileDialogChoice* m_choiceSize; + wxFileDialogRadioButton* m_radioPortrait; + wxFileDialogRadioButton* m_radioLandscape; + wxFileDialogTextCtrl* m_text; + wxFileDialogStaticText* m_label; + + wxString m_info; + + wxDECLARE_NO_COPY_CLASS(MyCustomizeHook); +}; + +void Frame::OnFileOpen(wxCommandEvent& WXUNUSED(event)) +{ wxFileName fnLastUsed(wxString::FromUTF8(m_strLastUsedFile)); + wxFileDialog dialog + ( + this, + "Testing open file dialog", + fnLastUsed.GetPath(), + fnLastUsed.GetFullName(), + wxString::Format + ( "Html (*.htm;*.html)|*.htm;*.html|Text files (*.txt)|*.txt|" + "Document files (*.doc;*.ods)|*.doc;*.ods|Markdown (*.md)|*.md|" + "All (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ) + ); + dialog.SetFilterIndex(m_FileDialogFilterIndex); + + + // For demonstration purposes, add wxWidgets directories to the sidebar. + wxString wxdir; + if (wxGetEnv("WXWIN", &wxdir)) + { + dialog.AddShortcut(wxdir + "/src"); + + // By default shortcuts are added at the bottom, but we can override + // this in the ports that support it (currently only wxMSW) and add a + // shortcut added later at the top instead. + dialog.AddShortcut(wxdir + "/include", wxFD_SHORTCUT_TOP); + } + + // Note: this object must remain alive until ShowModal() returns. + MyCustomizeHook myCustomizer(dialog); + + // Normal programs would use either SetCustomizeHook() (preferred) or + // SetExtraControlCreator() (if its extra flexibility is really required), + // but, for demonstration purposes, this sample allows either one or the + // other. + const bool useExtra = + GetMenuBar()->IsChecked(DIALOGS_FILE_USE_EXTRA_CONTROL_CREATOR); + const bool hasExtra = + useExtra ? dialog.SetExtraControlCreator(&createMyExtraPanel) + : dialog.SetCustomizeHook(myCustomizer); + + dialog.CentreOnParent(); + if (dialog.ShowModal() == wxID_OK) + { + wxString extraInfo; + if (hasExtra) + { + if (useExtra) + { + wxWindow* const extra = dialog.GetExtraControl(); + extraInfo = static_cast(extra)->GetInfo(); + } + else + { + extraInfo = myCustomizer.GetInfo(); + } + } + else + { + extraInfo = ""; + } + m_FileDialogFilterIndex = dialog.GetFilterIndex(); + m_strLastUsedFile = dialog.GetPath().ToUTF8(); + wxString info; + info.Printf("Full file name: %s\n" + "Path: %s\n" + "Name: %s\n" + "Custom window: %s", + dialog.GetPath(), + dialog.GetDirectory(), + dialog.GetFilename(), + extraInfo); + wxMessageDialog dialog2(this, info, "Selected file"); + dialog2.ShowModal(); + } +} + +// this shows how to take advantage of specifying a default extension in the +// call to wxFileSelector: it is remembered after each new call and the next +// one will use it by default +void Frame::FileOpen2(wxCommandEvent& WXUNUSED(event)) +{ + static wxString s_extDef; + wxString path = wxFileSelector( + "Select the file to load", + wxEmptyString, wxEmptyString, + s_extDef, + wxString::Format + ( + "Waveform (*.wav)|*.wav|Plain text (*.txt)|*.txt|All files (%s)|%s", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_OPEN | wxFD_CHANGE_DIR | wxFD_PREVIEW | wxFD_NO_FOLLOW | wxFD_SHOW_HIDDEN, + this + ); + + if (!path) + return; + + // it is just a sample, would use wxSplitPath in real program + s_extDef = path.AfterLast('.'); + + wxLogMessage("You selected the file '%s', remembered extension '%s'", + path, s_extDef); +} + +void Frame::FilesOpen(wxCommandEvent& WXUNUSED(event)) +{ + wxString wildcards = +#ifdef __WXMOTIF__ + "C++ files (*.cpp)|*.cpp"; +#else + wxString::Format + ( + "All files (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ); +#endif + wxFileDialog dialog(this, "Testing open multiple file dialog", + wxEmptyString, wxEmptyString, wildcards, + wxFD_OPEN | wxFD_MULTIPLE); + + dialog.Centre(wxCENTER_ON_SCREEN); + + if (dialog.ShowModal() == wxID_OK) + { + wxArrayString paths, filenames; + + dialog.GetPaths(paths); + dialog.GetFilenames(filenames); + + wxString msg, s; + size_t count = paths.GetCount(); + for (size_t n = 0; n < count; n++) + { + s.Printf("File %d: %s (%s)\n", + (int)n, paths[n], filenames[n]); + + msg += s; + } + s.Printf("Filter index: %d", dialog.GetFilterIndex()); + msg += s; + + wxMessageDialog dialog2(this, msg, "Selected files"); + dialog2.ShowModal(); + } +} + +void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) +{ + wxFileName fnLastUsed(wxString::FromUTF8(m_strLastUsedFile)); + wxFileDialog dialog(this, + "Testing save file dialog", + fnLastUsed.GetPath(), + fnLastUsed.GetFullName(), + wxString::Format + ( "Html (*.htm;*.html)|*.htm;*.html|Text files (*.txt)|*.txt|" + "Document files (*.doc;*.ods)|*.doc;*.ods|Markdown (*.md)|*.md|" + "All (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + dialog.SetFilterIndex(m_FileDialogFilterIndex); + + // This tests the (even more simplified) example from the docs. + class EncryptHook : public wxFileDialogCustomizeHook + { + public: + EncryptHook() + : m_encrypt(false) + { + } + + void AddCustomControls(wxFileDialogCustomize& customizer) wxOVERRIDE + { + m_checkbox = customizer.AddCheckBox("Encrypt"); + } + + void TransferDataFromCustomControls() wxOVERRIDE + { + m_encrypt = m_checkbox->GetValue(); + } + + bool Encrypt() const { return m_encrypt; } + + private: + wxFileDialogCheckBox* m_checkbox; + + bool m_encrypt; + }; + + EncryptHook customHook; + dialog.SetCustomizeHook(customHook); + + if (dialog.ShowModal() == wxID_OK) + { + m_FileDialogFilterIndex = dialog.GetFilterIndex(); + m_strLastUsedFile = dialog.GetPath().ToUTF8(); + wxLogMessage("%s,\n filter %d%s", + dialog.GetPath(), + m_FileDialogFilterIndex, + customHook.Encrypt() ? ", encrypt" : ""); + } +} + +#endif // wxUSE_FILEDLG + +void Frame::MacToggleAlwaysShowTypes(wxCommandEvent& event) +{ +#ifdef wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES + wxSystemOptions::SetOption(wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, + event.IsChecked()); +#else + wxUnusedVar(event); +#endif +} + +#if wxUSE_DIRDLG +void Frame::DoDirChoose(int style) +{ + // pass some initial dir to wxDirDialog + wxString dirHome; + wxGetHomeDir(&dirHome); + + wxDirDialog dialog(this, "Testing directory picker", dirHome, style); + + if (dialog.ShowModal() == wxID_OK) + { + wxLogMessage("Selected path: %s", dialog.GetPath()); + } +} + +void Frame::DirChoose(wxCommandEvent& WXUNUSED(event)) +{ + DoDirChoose(wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); +} + +void Frame::DirChooseNew(wxCommandEvent& WXUNUSED(event)) +{ + DoDirChoose(wxDD_DEFAULT_STYLE & ~wxDD_DIR_MUST_EXIST); +} + +void Frame::DirChooseMultiple(wxCommandEvent& WXUNUSED(event)) +{ + // pass some initial dir and the style to wxDirDialog + int style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST | wxDD_MULTIPLE | wxDD_SHOW_HIDDEN; + wxString dirHome; + wxGetHomeDir(&dirHome); + + wxDirDialog dialog(this, "Testing multiple directory picker", dirHome, style); + + if (dialog.ShowModal() == wxID_OK) + { + wxArrayString paths; + + dialog.GetPaths(paths); + + wxString msg, s; + size_t count = paths.GetCount(); + for (size_t n = 0; n < count; n++) + { + s.Printf("Directory %d: %s\n", + (int)n, paths[n]); + + msg += s; + } + + wxMessageDialog dialog2(this, msg, "Selected directories"); + dialog2.ShowModal(); + } +} + +void Frame::DirChooseWindowModal(wxCommandEvent& WXUNUSED(event)) +{ + // pass some initial dir to wxDirDialog + wxString dirHome; + wxGetHomeDir(&dirHome); + + wxDirDialog* dialog = new wxDirDialog(this, "Testing directory picker", dirHome, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + + dialog->Bind(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, + &Frame::DirChooseWindowModalClosed, this); + + dialog->ShowWindowModal(); +} + +void Frame::DirChooseWindowModalClosed(wxWindowModalDialogEvent& event) +{ + wxDirDialog* dialog = dynamic_cast(event.GetDialog()); + if (dialog->GetReturnCode() == wxID_OK) + { + wxLogMessage("Selected path: %s", dialog->GetPath()); + } + delete dialog; +} +#endif // wxUSE_DIRDLG + +#if USE_MODAL_PRESENTATION +void Frame::ModalDlg(wxCommandEvent& WXUNUSED(event)) +{ + MyModalDialog dlg(this); + dlg.ShowModal(); +} +#endif // USE_MODAL_PRESENTATION + +void Frame::ModelessDlg(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_dialog) + { + m_dialog = new MyModelessDialog(this); + } + + m_dialog->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + + wxASSERT(m_dialog != NULL); + if (m_dialog) + m_dialog->Hide(); + } +} + +void Frame::DlgCenteredScreen(wxCommandEvent& WXUNUSED(event)) +{ + wxDialog dlg(this, wxID_ANY, "Dialog centered on screen", + wxDefaultPosition, wxSize(200, 100)); + (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); + dlg.CentreOnScreen(); + dlg.ShowModal(); +} + +void Frame::DlgCenteredParent(wxCommandEvent& WXUNUSED(event)) +{ + wxDialog dlg(this, wxID_ANY, "Dialog centered on parent", + wxDefaultPosition, wxSize(200, 100)); + (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); + dlg.CentreOnParent(); + dlg.ShowModal(); +} + +#if wxUSE_MINIFRAME +void Frame::MiniFrame(wxCommandEvent& WXUNUSED(event)) +{ + wxFrame* frame = new wxMiniFrame(this, wxID_ANY, "Mini frame", + wxDefaultPosition, wxSize(300, 100), + wxCAPTION | wxCLOSE_BOX); + new wxStaticText(frame, + wxID_ANY, + "Mini frames have slightly different appearance", + wxPoint(5, 5)); + new wxStaticText(frame, + wxID_ANY, + "from the normal frames but that's the only difference.", + wxPoint(5, 25)); + + frame->CentreOnParent(); + frame->Show(); +} +#endif // wxUSE_MINIFRAME + +void Frame::DlgOnTop(wxCommandEvent& WXUNUSED(event)) +{ + wxDialog dlg(this, wxID_ANY, "Dialog staying on top of other windows", + wxDefaultPosition, wxSize(300, 100), + wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP); + (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); + dlg.ShowModal(); +} + +#if wxUSE_STARTUP_TIPS +void Frame::ShowTip(wxCommandEvent& WXUNUSED(event)) +{ + wxFileName fnResources; + wxStandardPaths::Get().DontIgnoreAppSubDir(); + fnResources.AssignDir(wxStandardPaths::Get().GetResourcesDir()); + fnResources.SetFullName("tips.txt"); + wxTipProvider* tipProvider = wxCreateFileTipProvider(fnResources.GetFullPath(), m_TipOfTheDayIndex); + m_showTipsAtStartup = wxShowTip(this, tipProvider, m_showTipsAtStartup); + m_TipOfTheDayIndex = tipProvider->GetCurrentTip(); + delete tipProvider; +} +#endif // wxUSE_STARTUP_TIPS + +#if USE_SETTINGS_DIALOG +void Frame::OnPropertySheet(wxCommandEvent& event) +{ + SettingsDialog dialog(this, m_settingsData, event.GetId()); + dialog.ShowModal(); +} +#endif // USE_SETTINGS_DIALOG + +void Frame::OnRequestUserAttention(wxCommandEvent& WXUNUSED(event)) +{ + wxLogStatus("Sleeping for 3 seconds to allow you to switch to another window"); + + wxSleep(3); + + RequestUserAttention(wxUSER_ATTENTION_ERROR); +} + +#if wxUSE_RICHTOOLTIP || wxUSE_NOTIFICATION_MESSAGE +#include "tip.xpm" +#endif + +#if wxUSE_NOTIFICATION_MESSAGE + +// ---------------------------------------------------------------------------- +// TestNotificationMessageDialog +// ---------------------------------------------------------------------------- + +class TestNotificationMessageWindow : public wxFrame +{ +public: + TestNotificationMessageWindow(wxWindow* parent) : + wxFrame(parent, wxID_ANY, "User Notification Test Dialog") + { +#ifdef __WXMSW__ + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); +#endif + wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL); + + wxSizer* sizerText = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Texts"); + + sizerText->Add(new wxStaticText(this, wxID_ANY, "&Title:"), + wxSizerFlags()); + m_textTitle = new wxTextCtrl(this, wxID_ANY, "Notification Title"); + sizerText->Add(m_textTitle, wxSizerFlags().Expand()); + + sizerText->Add(new wxStaticText(this, wxID_ANY, "&Message:"), + wxSizerFlags()); + m_textMessage = new wxTextCtrl(this, wxID_ANY, "A message within the notification", + wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textMessage->SetMinSize(wxSize(300, -1)); + sizerText->Add(m_textMessage, wxSizerFlags().Expand()); + + sizerTop->Add(sizerText, wxSizerFlags().Expand().Border()); + + const wxString icons[] = + { + "De&fault", + "None", + "&Information", + "&Warning", + "&Error", + "&Custom" + }; + wxCOMPILE_TIME_ASSERT(WXSIZEOF(icons) == Icon_Max, IconMismatch); + m_icons = new wxRadioBox(this, wxID_ANY, "Ic&on in notification", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(icons), icons, + 1, wxRA_SPECIFY_ROWS); + m_icons->SetSelection(Icon_Default); + sizerTop->Add(m_icons, wxSizerFlags().Expand().Border()); + + const wxString timeouts[] = + { + "&Automatic", + "&Never", + "&5 sec", + "&15 sec" + }; + m_showTimeout = new wxRadioBox(this, wxID_ANY, "&Timeout for notification", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(timeouts), timeouts, + 1, wxRA_SPECIFY_ROWS); + m_showTimeout->SetSelection(0); + sizerTop->Add(m_showTimeout, wxSizerFlags().Expand().Border()); + + wxSizer* sizerActions = new wxStaticBoxSizer(wxVERTICAL, this, "Additional Actions"); + + m_actionList = new wxListBox(this, wxID_ANY); + sizerActions->Add(m_actionList, wxSizerFlags().Expand()); + + wxSizer* sizerActionMod = new wxBoxSizer(wxHORIZONTAL); + sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "ID:"), wxSizerFlags().Center()); + const wxString actionIds[] = + { + "wxID_DELETE", + "wxID_CLOSE", + "wxID_OK", + "wxID_CANCEL" + }; + m_actionChoice = new wxChoice(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(actionIds), actionIds + ); + m_actionChoice->SetSelection(0); + sizerActionMod->Add(m_actionChoice); + sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "Custom label:"), wxSizerFlags().Center()); + m_actionCaption = new wxTextCtrl(this, wxID_ANY); + sizerActionMod->Add(m_actionCaption); + wxButton* actionAddBtn = new wxButton(this, wxID_ADD); + actionAddBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionAddClicked, this); + sizerActionMod->Add(actionAddBtn); + wxButton* actionRemoveBtn = new wxButton(this, wxID_REMOVE); + actionRemoveBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionRemoveClicked, this); + sizerActionMod->Add(actionRemoveBtn); + + sizerActions->Add(sizerActionMod, wxSizerFlags().Border()); + + sizerTop->Add(sizerActions, wxSizerFlags().Expand().Border()); + + wxSizer* sizerSettings = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Settings"); + +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + m_useGeneric = new wxCheckBox(this, wxID_ANY, "Use &generic notifications"); + sizerSettings->Add(m_useGeneric); +#endif + + m_delayShow = new wxCheckBox(this, wxID_ANY, "&Delay show"); +#if defined(__WXOSX__) + m_delayShow->SetValue(true); +#endif + sizerSettings->Add(m_delayShow); + + m_handleEvents = new wxCheckBox(this, wxID_ANY, "&Handle events"); + m_handleEvents->SetValue(true); + sizerSettings->Add(m_handleEvents); + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + m_taskbarIcon = NULL; + m_useTaskbar = new wxCheckBox(this, wxID_ANY, "Use persistent &taskbar icon"); + m_useTaskbar->SetValue(false); + sizerSettings->Add(m_useTaskbar); +#endif + + sizerTop->Add(sizerSettings, wxSizerFlags().Expand().Border()); + + m_textStatus = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, + wxST_NO_AUTORESIZE | wxALIGN_CENTRE_HORIZONTAL); + m_textStatus->SetForegroundColour(*wxBLUE); + sizerTop->Add(m_textStatus, wxSizerFlags().Expand().Border()); + + wxSizer* sizerButtons = new wxBoxSizer(wxHORIZONTAL); + sizerButtons->Add(new wxButton(this, wxID_NEW, "&Show")); + m_closeButton = new wxButton(this, wxID_CLOSE, "&Close"); + m_closeButton->Disable(); + sizerButtons->Add(m_closeButton); + sizerTop->Add(sizerButtons, wxSizerFlags().Center()); + + SetSizerAndFit(sizerTop); + + Center(); + + Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnShowClicked, this, wxID_NEW); + Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnCloseClicked, this, wxID_CLOSE); + } + +private: + enum + { + Icon_Default, + Icon_None, + Icon_Info, + Icon_Warning, + Icon_Error, + Icon_Custom, + Icon_Max + }; + + class ActionInfo : public wxClientData + { + public: + ActionInfo(wxWindowID actionId, const wxString& actionCaption) : + id(actionId), + customCaption(actionCaption) + { + + } + + wxWindowID id; + wxString customCaption; + }; + + wxTextCtrl* m_textTitle; + wxTextCtrl* m_textMessage; + wxRadioBox* m_icons; + wxRadioBox* m_showTimeout; + wxListBox* m_actionList; + wxChoice* m_actionChoice; + wxTextCtrl* m_actionCaption; +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + wxCheckBox* m_useGeneric; +#endif + wxCheckBox* m_delayShow; + wxCheckBox* m_handleEvents; + wxStaticText* m_textStatus; + wxButton* m_closeButton; + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + wxCheckBox* m_useTaskbar; + wxTaskBarIcon* m_taskbarIcon; +#endif + + wxSharedPtr< wxNotificationMessageBase> m_notif; + + void DoShowNotification() + { + if (m_delayShow->GetValue()) + { + ShowStatus("Sleeping for 3 seconds to allow you to switch to another window"); + wxYield(); + wxSleep(3); + } + + m_closeButton->Enable(); + ShowStatus("Showing notification..."); +#ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE + if (m_useGeneric->GetValue()) + m_notif = new wxGenericNotificationMessage( + m_textTitle->GetValue(), + m_textMessage->GetValue(), + this); + else +#endif + { + m_notif = new wxNotificationMessage( + m_textTitle->GetValue(), + m_textMessage->GetValue(), + this); + +#if defined(__WXMSW__) && wxUSE_TASKBARICON + if (m_useTaskbar->GetValue()) + { + if (!m_taskbarIcon) + { + m_taskbarIcon = new wxTaskBarIcon(); + m_taskbarIcon->SetIcon(reinterpret_cast(GetParent())->GetIcon(), + "Dialogs Sample (Persistent)"); + } + wxNotificationMessage::UseTaskBarIcon(m_taskbarIcon); + } + else + if (m_taskbarIcon) + { + wxNotificationMessage::UseTaskBarIcon(NULL); + delete m_taskbarIcon; + m_taskbarIcon = NULL; + } +#endif + } + + switch (m_icons->GetSelection()) + { + case Icon_Default: + // Don't call SetFlags or SetIcon to see the implementations default + break; + case Icon_None: + m_notif->SetFlags(0); + break; + case Icon_Info: + m_notif->SetFlags(wxICON_INFORMATION); + break; + case Icon_Warning: + m_notif->SetFlags(wxICON_WARNING); + break; + case Icon_Error: + m_notif->SetFlags(wxICON_ERROR); + break; + case Icon_Custom: + m_notif->SetIcon(tip_xpm); + break; + } + + int timeout; + switch (m_showTimeout->GetSelection()) + { + case 1: + timeout = wxNotificationMessage::Timeout_Never; + break; + case 2: + timeout = 5; + break; + case 3: + timeout = 10; + break; + default: + timeout = wxNotificationMessage::Timeout_Auto; + break; + } + + for (unsigned int i = 0; i < m_actionList->GetCount(); i++) + { + ActionInfo* ai = reinterpret_cast(m_actionList->GetClientObject(i)); + if (!m_notif->AddAction(ai->id, ai->customCaption)) + wxLogWarning("Could not add action: %s", m_actionList->GetString(i)); + } + + if (m_handleEvents->GetValue()) + { + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_ACTION, &TestNotificationMessageWindow::OnNotificationAction, this); + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_CLICK, &TestNotificationMessageWindow::OnNotificationClicked, this); + m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_DISMISSED, &TestNotificationMessageWindow::OnNotificationDismissed, this); + } + + m_notif->Show(timeout); + + // Free the notification if we don't handle it's events + if (!m_handleEvents->GetValue()) + { + // Notice that the notification remains shown even after the + // wxNotificationMessage object itself is destroyed so we can show simple + // notifications using temporary objects. + m_notif.reset(); + ShowStatus("Showing notification, deleted object"); + } + } + + void OnShowClicked(wxCommandEvent& WXUNUSED(event)) + { + DoShowNotification(); + } + + void OnCloseClicked(wxCommandEvent& WXUNUSED(event)) + { + if (m_notif) + m_notif->Close(); + } + + void OnActionAddClicked(wxCommandEvent& WXUNUSED(event)) + { + wxWindowID actionId; + switch (m_actionChoice->GetSelection()) + { + case 1: + actionId = wxID_CLOSE; + break; + case 2: + actionId = wxID_OK; + break; + case 3: + actionId = wxID_CANCEL; + break; + default: + actionId = wxID_DELETE; + break; + } + + wxString actionCaption = m_actionCaption->GetValue(); + wxString desc = m_actionChoice->GetStringSelection(); + if (!actionCaption.empty()) + desc += " (" + actionCaption + ")"; + m_actionList->SetSelection(m_actionList->Append(desc, new ActionInfo(actionId, actionCaption))); + } + + void OnActionRemoveClicked(wxCommandEvent& WXUNUSED(event)) + { + int pos = m_actionList->GetSelection(); + if (pos != wxNOT_FOUND) + { + m_actionList->Delete(pos); + if (pos > 0 && m_actionList->GetCount() > 0) + m_actionList->SetSelection(pos - 1); + } + else + wxLogError("No action selected"); + } + + void OnNotificationClicked(wxCommandEvent& event) + { + ShowStatus("Notification was clicked"); + + Raise(); + + event.Skip(); + } + + void OnNotificationDismissed(wxCommandEvent& event) + { + ShowStatus("Notification was dismissed"); + + Raise(); + + event.Skip(); + } + + void OnNotificationAction(wxCommandEvent& event) + { + ShowStatus(wxString::Format("Selected %s action in notification", wxGetStockLabel(event.GetId(), 0))); + + event.Skip(); + } + + void ShowStatus(const wxString& text) + { + m_textStatus->SetLabelText(text); + } + +}; + +void Frame::OnNotifMsg(wxCommandEvent& WXUNUSED(event)) +{ +#ifdef __WXMSW__ + // Try to enable toast notifications (available since Win8) + if (!wxNotificationMessage::MSWUseToasts()) + { + wxLogDebug("Toast notifications not available."); + } +#endif + + TestNotificationMessageWindow* dlg = new TestNotificationMessageWindow(this); + dlg->Show(); +} + +#endif // wxUSE_NOTIFICATION_MESSAGE + +#if wxUSE_TIPWINDOW + +void Frame::OnShowTip(wxCommandEvent& WXUNUSED(event)) +{ + if (m_tipWindow) + { + m_tipWindow->Close(); + } + else + { + m_tipWindow = new wxTipWindow + ( + this, + "This is just some text to be shown in the tip " + "window, broken into multiple lines, each less " + "than 60 logical pixels wide.", + FromDIP(60), + &m_tipWindow + ); + } +} + +void Frame::OnUpdateShowTipUI(wxUpdateUIEvent& event) +{ + event.Check(m_tipWindow != NULL); +} + +#endif // wxUSE_TIPWINDOW + +#if wxUSE_RICHTOOLTIP + +#include "wx/richtooltip.h" + +class RichTipDialog : public wxDialog +{ +public: + RichTipDialog(wxWindow* parent) + : wxDialog(parent, wxID_ANY, "wxRichToolTip Test", + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + { + // Create the controls. + m_textTitle = new wxTextCtrl(this, wxID_ANY, "Tooltip title"); + m_textBody = new wxTextCtrl(this, wxID_ANY, "Main tooltip text\n" + "possibly on several\n" + "lines.", + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + wxButton* btnShowText = new wxButton(this, wxID_ANY, "Show for &text"); + wxButton* btnShowBtn = new wxButton(this, wxID_ANY, "Show for &button"); + + const wxString icons[] = + { + "&None", + "&Information", + "&Warning", + "&Error", + "&Custom" + }; + wxCOMPILE_TIME_ASSERT(WXSIZEOF(icons) == Icon_Max, IconMismatch); + m_icons = new wxRadioBox(this, wxID_ANY, "&Icon choice:", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(icons), icons, + 1, wxRA_SPECIFY_ROWS); + m_icons->SetSelection(Icon_Info); + + const wxString tipKinds[] = + { + "&None", "Top left", "Top", "Top right", + "Bottom left", "Bottom", "Bottom right", "&Auto" + }; + m_tipKinds = new wxRadioBox(this, wxID_ANY, "Tip &kind:", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(tipKinds), tipKinds, + 4, wxRA_SPECIFY_COLS); + m_tipKinds->SetSelection(wxTipKind_Auto); + + const wxString bgStyles[] = + { + "&Default", "&Solid", "&Gradient", + }; + wxCOMPILE_TIME_ASSERT(WXSIZEOF(bgStyles) == Bg_Max, BgMismatch); + m_bgStyles = new wxRadioBox(this, wxID_ANY, "Background style:", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(bgStyles), bgStyles, + 1, wxRA_SPECIFY_ROWS); + + const wxString timeouts[] = { "&None", "&Default (no delay)", "&3 seconds" }; + wxCOMPILE_TIME_ASSERT(WXSIZEOF(timeouts) == Timeout_Max, TmMismatch); + m_timeouts = new wxRadioBox(this, wxID_ANY, "Timeout:", + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(timeouts), timeouts, + 1, wxRA_SPECIFY_ROWS); + m_timeouts->SetSelection(Timeout_Default); + m_timeDelay = new wxCheckBox(this, wxID_ANY, "Delay show"); + + // Lay them out. + m_textBody->SetMinSize(wxSize(300, 200)); + + wxBoxSizer* const sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(m_textTitle, wxSizerFlags().Expand().Border()); + sizer->Add(m_textBody, wxSizerFlags(1).Expand().Border()); + sizer->Add(m_icons, wxSizerFlags().Expand().Border()); + sizer->Add(m_tipKinds, wxSizerFlags().Centre().Border()); + sizer->Add(m_bgStyles, wxSizerFlags().Centre().Border()); + sizer->Add(m_timeouts, wxSizerFlags().Centre().Border()); + sizer->Add(m_timeDelay, wxSizerFlags().Centre().Border()); + wxBoxSizer* const sizerBtns = new wxBoxSizer(wxHORIZONTAL); + sizerBtns->Add(btnShowText, wxSizerFlags().Border(wxRIGHT)); + sizerBtns->Add(btnShowBtn, wxSizerFlags().Border(wxLEFT)); + sizer->Add(sizerBtns, wxSizerFlags().Centre().Border()); + sizer->Add(CreateStdDialogButtonSizer(wxOK), + wxSizerFlags().Expand().Border()); + SetSizerAndFit(sizer); + + + // And connect the event handlers. + btnShowText->Bind(wxEVT_BUTTON, &RichTipDialog::OnShowTipForText, this); + btnShowBtn->Bind(wxEVT_BUTTON, &RichTipDialog::OnShowTipForBtn, this); + } + +private: + enum + { + Icon_None, + Icon_Info, + Icon_Warning, + Icon_Error, + Icon_Custom, + Icon_Max + }; + + enum + { + Bg_Default, + Bg_Solid, + Bg_Gradient, + Bg_Max + }; + + enum + { + Timeout_None, + Timeout_Default, + Timeout_3sec, + Timeout_Max + }; + + + void OnShowTipForText(wxCommandEvent& WXUNUSED(event)) + { + DoShowTip(m_textTitle); + } + + void OnShowTipForBtn(wxCommandEvent& WXUNUSED(event)) + { + DoShowTip(FindWindow(wxID_OK)); + } + + void DoShowTip(wxWindow* win) + { + wxRichToolTip tip(m_textTitle->GetValue(), m_textBody->GetValue()); + const int iconSel = m_icons->GetSelection(); + if (iconSel == Icon_Custom) + { + tip.SetIcon(tip_xpm); + } + else // Use a standard icon. + { + static const int stdIcons[] = + { + wxICON_NONE, + wxICON_INFORMATION, + wxICON_WARNING, + wxICON_ERROR, + }; + + tip.SetIcon(stdIcons[iconSel]); + } + + switch (m_bgStyles->GetSelection()) + { + case Bg_Default: + break; + + case Bg_Solid: + tip.SetBackgroundColour(*wxLIGHT_GREY); + break; + + case Bg_Gradient: + tip.SetBackgroundColour(*wxWHITE, wxColour(0xe4, 0xe5, 0xf0)); + break; + } + + int delay = m_timeDelay->IsChecked() ? 500 : 0; + + switch (m_timeouts->GetSelection()) + { + case Timeout_None: + // Don't call SetTimeout unnecessarily + // or msw will show generic impl + if (delay) + tip.SetTimeout(0, delay); + break; + + case Timeout_Default: + break; + + case Timeout_3sec: + tip.SetTimeout(3000, delay); + break; + } + + tip.SetTipKind(static_cast(m_tipKinds->GetSelection())); + + tip.ShowFor(win); + } + + wxTextCtrl* m_textTitle; + wxTextCtrl* m_textBody; + wxRadioBox* m_icons; + wxRadioBox* m_tipKinds; + wxRadioBox* m_bgStyles; + wxRadioBox* m_timeouts; + wxCheckBox* m_timeDelay; +}; + +void Frame::OnRichTipDialog(wxCommandEvent& WXUNUSED(event)) +{ + RichTipDialog dialog(this); + dialog.ShowModal(); +} + +#endif // wxUSE_RICHTOOLTIP + +void Frame::OnStandardButtonsSizerDialog(wxCommandEvent& WXUNUSED(event)) +{ + StdButtonSizerDialog dialog(this); + dialog.ShowModal(); +} + +// TestDefaultAction + +#define ID_CATCH_LISTBOX_DCLICK 100 +#define ID_LISTBOX 101 +#define ID_DISABLE_OK 102 +#define ID_DISABLE_CANCEL 103 + +wxBEGIN_EVENT_TABLE(TestDefaultActionDialog, wxDialog) +EVT_CHECKBOX(ID_CATCH_LISTBOX_DCLICK, TestDefaultActionDialog::OnCatchListBoxDClick) +EVT_CHECKBOX(ID_DISABLE_OK, TestDefaultActionDialog::OnDisableOK) +EVT_CHECKBOX(ID_DISABLE_CANCEL, TestDefaultActionDialog::OnDisableCancel) +EVT_LISTBOX_DCLICK(ID_LISTBOX, TestDefaultActionDialog::OnListBoxDClick) +EVT_TEXT_ENTER(wxID_ANY, TestDefaultActionDialog::OnTextEnter) +wxEND_EVENT_TABLE() + +// TODO-C++11: We can't declare this class inside TestDefaultActionDialog +// itself when using C++98, so we have to do it here instead. +namespace +{ + + // We have to define a new class in order to actually handle pressing + // Enter, if we didn't do it, pressing it would still close the dialog. + class EnterHandlingTextCtrl : public wxTextCtrl + { + public: + EnterHandlingTextCtrl(wxWindow* parent, int id, const wxString& value) + : wxTextCtrl(parent, id, value, + wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER) + { + Bind(wxEVT_TEXT_ENTER, &EnterHandlingTextCtrl::OnEnter, this); + + SetInitialSize(GetSizeFromTextSize(GetTextExtent(value).x)); + } + + private: + void OnEnter(wxCommandEvent& WXUNUSED(event)) + { + wxLogMessage("Enter pressed"); + } + }; + +} // anonymous namespace + +TestDefaultActionDialog::TestDefaultActionDialog(wxWindow* parent) : + wxDialog(parent, -1, "Test default action") +{ + m_catchListBoxDClick = false; + + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + + const int border = wxSizerFlags::GetDefaultBorder(); + wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(2, wxSize(border, border)); + +#if wxUSE_LISTBOX + wxListBox* listbox = new wxListBox(this, ID_LISTBOX); + listbox->Append("String 1"); + listbox->Append("String 2"); + listbox->Append("String 3"); + listbox->Append("String 4"); + grid_sizer->Add(listbox); +#endif // wxUSE_LISTBOX + + grid_sizer->Add(new wxCheckBox(this, ID_CATCH_LISTBOX_DCLICK, "Catch DoubleClick from wxListBox"), + wxSizerFlags().CentreVertical()); + + grid_sizer->Add(new wxTextCtrl(this, wxID_ANY, "Enter here closes the dialog"), + wxSizerFlags().Expand().CentreVertical()); + grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl without wxTE_PROCESS_ENTER"), + wxSizerFlags().CentreVertical()); + + grid_sizer->Add(new EnterHandlingTextCtrl(this, wxID_ANY, "Enter here is handled by the application"), + wxSizerFlags().CentreVertical()); + grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl with wxTE_PROCESS_ENTER"), + wxSizerFlags().CentreVertical()); + + grid_sizer->Add(new wxTextCtrl(this, wxID_ANY, + "Enter here adds another line,\n" + "while Ctrl-Enter closes the dialog", + wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), + wxSizerFlags().Expand()); + grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl without wxTE_PROCESS_ENTER"), + wxSizerFlags().CentreVertical()); + + grid_sizer->Add(new wxCheckBox(this, ID_DISABLE_OK, "Disable \"OK\""), + wxSizerFlags().CentreVertical()); + grid_sizer->Add(new wxCheckBox(this, ID_DISABLE_CANCEL, "Disable \"Cancel\""), + wxSizerFlags().CentreVertical()); + + main_sizer->Add(grid_sizer, wxSizerFlags().DoubleBorder()); + + wxSizer* button_sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL); + if (button_sizer) + main_sizer->Add(button_sizer, wxSizerFlags().Expand().Border()); + + SetSizerAndFit(main_sizer); +} + +void TestDefaultActionDialog::OnDisableOK(wxCommandEvent& event) +{ + FindWindow(wxID_OK)->Enable(!event.IsChecked()); +} + +void TestDefaultActionDialog::OnDisableCancel(wxCommandEvent& event) +{ + FindWindow(wxID_CANCEL)->Enable(!event.IsChecked()); +} + +void TestDefaultActionDialog::OnListBoxDClick(wxCommandEvent& event) +{ + event.Skip(!m_catchListBoxDClick); +} + +void TestDefaultActionDialog::OnCatchListBoxDClick(wxCommandEvent& WXUNUSED(event)) +{ + m_catchListBoxDClick = !m_catchListBoxDClick; +} + +void TestDefaultActionDialog::OnTextEnter(wxCommandEvent& event) +{ + const wxString& text = event.GetString(); + if (text.empty()) + { + event.Skip(); + return; + } + + wxLogMessage("Text \"%s\" entered.", text); +} + +void Frame::OnTestDefaultActionDialog(wxCommandEvent& WXUNUSED(event)) +{ + TestDefaultActionDialog dialog(this); + dialog.ShowModal(); +} + +void Frame::OnModalHook(wxCommandEvent& event) +{ + class TestModalHook : public wxModalDialogHook + { + protected: + virtual int Enter(wxDialog* dialog) wxOVERRIDE + { + wxLogStatus("Showing %s modal dialog", + dialog->GetClassInfo()->GetClassName()); + return wxID_NONE; + } + + virtual void Exit(wxDialog* dialog) wxOVERRIDE + { + wxLogStatus("Leaving %s modal dialog", + dialog->GetClassInfo()->GetClassName()); + } + }; + + static TestModalHook s_hook; + if (event.IsChecked()) + s_hook.Register(); + else + s_hook.Unregister(); +} + +void Frame::OnSimulatedUnsaved(wxCommandEvent& event) +{ + m_confirmExit = event.IsChecked(); +} + +void Frame::OnExit(wxCommandEvent& WXUNUSED(event)) +{ + Close(true); +} + +void Frame::OnClose(wxCloseEvent& event) +{ + if (m_confirmExit && event.CanVeto()) + { + wxMessageDialog dialog(this, + "You have an unsaved file; save before closing?", + "OnClose", + wxCENTER | + wxYES_NO | wxCANCEL | + wxICON_QUESTION); + + dialog.SetYesNoLabels( + "&Save", + "&Discard changes" + ); + switch (dialog.ShowModal()) + { + case wxID_CANCEL: + event.Veto(); + wxLogStatus("You cancelled closing the application."); + // Return without calling event.Skip() to prevent closing the frame. + // The application should resume operation as if closing it had not + // been attempted. + return; + case wxID_YES: + wxMessageBox("You chose to save your file.", "OnClose", wxOK); + // In a real application, do something to save the + // file(s), possibly asking for a file name and location + // using wxFileDialog. + break; + default: + wxLogError("Unexpected wxMessageDialog return code!"); + wxFALLTHROUGH; + case wxID_NO: + // Don't save anything, and simply continue with closing the frame. + break; + } + } + + // Continue with closing the frame. + event.Skip(); +} + +#if wxUSE_PROGRESSDLG + +static const int max_ = 100; + +void Frame::ShowProgress(wxCommandEvent& WXUNUSED(event)) +{ + wxProgressDialog dialog("Progress dialog example", + // "Reserve" enough space for the multiline + // messages below, we'll change it anyhow + // immediately in the loop below + wxString(' ', 100) + "\n\n\n\n", + max_, // range + this, // parent + wxPD_CAN_ABORT | + wxPD_CAN_SKIP | + wxPD_APP_MODAL | + //wxPD_AUTO_HIDE | // -- try this as well + wxPD_ELAPSED_TIME | + wxPD_ESTIMATED_TIME | + wxPD_REMAINING_TIME | + wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small + ); + + DoShowProgress(dialog); +} + +#ifdef wxHAS_NATIVE_PROGRESSDIALOG +void Frame::ShowProgressGeneric(wxCommandEvent& WXUNUSED(event)) +{ + wxGenericProgressDialog dialog("Generic progress dialog example", + wxString(' ', 100) + "\n\n\n\n", + max_, + this, + wxPD_CAN_ABORT | + wxPD_CAN_SKIP | + wxPD_APP_MODAL | + wxPD_ELAPSED_TIME | + wxPD_ESTIMATED_TIME | + wxPD_REMAINING_TIME | + wxPD_SMOOTH); + + DoShowProgress(dialog); +} +#endif // wxHAS_NATIVE_PROGRESSDIALOG + +void Frame::DoShowProgress(wxGenericProgressDialog& dialog) +{ + bool cont = true; + for (int i = 0; i <= max_; i++) + { + wxString msg; + + // test both modes of wxProgressDialog behaviour: start in + // indeterminate mode but switch to the determinate one later + const bool determinate = i > max_ / 2; + + if (i == max_) + { + msg = "That's all, folks!\n" + "\n" + "Nothing to see here any more."; + } + else if (!determinate) + { + msg = "Testing indeterminate mode\n" + "\n" + "This mode allows you to show to the user\n" + "that something is going on even if you don't know\n" + "when exactly will you finish."; + } + else if (determinate) + { + msg = "Now in standard determinate mode\n" + "\n" + "This is the standard usage mode in which you\n" + "update the dialog after performing each new step of work.\n" + "It requires knowing the total number of steps in advance."; + } + + // will be set to true if "Skip" button was pressed + bool skip = false; + if (determinate) + { + cont = dialog.Update(i, msg, &skip); + } + else + { + cont = dialog.Pulse(msg, &skip); + } + + // each skip will move progress about quarter forward + if (skip) + { + i += max_ / 4; + + if (i >= max_) + i = max_ - 1; + } + + if (!cont) + { + if (wxMessageBox("Do you really want to cancel?", + "Progress dialog question", // caption + wxYES_NO | wxICON_QUESTION) == wxYES) + break; + + cont = true; + dialog.Resume(); + } + + wxMilliSleep(100); + } + + if (!cont) + { + wxLogStatus("Progress dialog aborted!"); + } + else + { + wxLogStatus("Countdown from %d finished", max_); + } +} + +#endif // wxUSE_PROGRESSDLG + +void Frame::ShowAppProgress(wxCommandEvent& WXUNUSED(event)) +{ + wxAppProgressIndicator progress(this); + if (!progress.IsAvailable()) + { + wxLogStatus("Progress indicator not available under this platform."); + return; + } + + wxLogStatus("Using application progress indicator..."); + + const int range = 10; + progress.SetRange(range); + for (int i = 0; i < range; i++) + { + progress.SetValue(i); + + wxMilliSleep(200); + } + + wxLogStatus("Progress finished"); +} + + +#if USE_MODAL_PRESENTATION + +wxBEGIN_EVENT_TABLE(MyModalDialog, wxDialog) +EVT_BUTTON(wxID_ANY, MyModalDialog::OnButton) +wxEND_EVENT_TABLE() + +wxBEGIN_EVENT_TABLE(MyModelessDialog, wxDialog) +EVT_BUTTON(DIALOGS_MODELESS_BTN, MyModelessDialog::OnButton) +EVT_CLOSE(MyModelessDialog::OnClose) +wxEND_EVENT_TABLE() + +#endif // USE_MODAL_PRESENTATION + +wxBEGIN_EVENT_TABLE(StdButtonSizerDialog, wxDialog) +EVT_CHECKBOX(wxID_ANY, StdButtonSizerDialog::OnEvent) +EVT_RADIOBUTTON(wxID_ANY, StdButtonSizerDialog::OnEvent) +wxEND_EVENT_TABLE() +#if wxUSE_ABOUTDLG + +static void InitAboutInfoMinimal(wxAboutDialogInfo& info) +{ + info.SetName("Dialogs Sample"); + info.SetVersion(wxVERSION_NUM_DOT_STRING, + wxString::Format + ( + "%s version %s", + wxMINOR_VERSION % 2 ? "Development" : "Stable", + wxVERSION_NUM_DOT_STRING + )); + info.SetDescription("This sample shows different wxWidgets dialogs"); + info.SetCopyright("(C) 1998-2006 wxWidgets dev team"); + info.AddDeveloper("Vadim Zeitlin"); +} + +static void InitAboutInfoWebsite(wxAboutDialogInfo& info) +{ + InitAboutInfoMinimal(info); + + info.SetWebSite("http://www.wxwidgets.org/", "wxWidgets web site"); +} + +static void InitAboutInfoAll(wxAboutDialogInfo& info) +{ + InitAboutInfoWebsite(info); + + // we can add a second developer + info.AddDeveloper("A.N. Other"); + + // or we can add several persons at once like this + wxArrayString docwriters; + docwriters.Add("First D. Writer"); + docwriters.Add("Second One"); + + info.SetDocWriters(docwriters); + info.SetLicence(wxString::FromAscii( + " wxWindows Library Licence, Version 3.1\n" + " ======================================\n" + "\n" + " Copyright (c) 1998-2018 Julian Smart, Robert Roebling et al\n" + "\n" + " Everyone is permitted to copy and distribute verbatim copies\n" + " of this licence document, but changing it is not allowed.\n" + "\n" + " WXWINDOWS LIBRARY LICENCE\n" + " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" + "\n" + " ...and so on and so forth...\n" + )); + + info.AddTranslator("Wun Ngo Wen (Martian)"); +} + +void Frame::ShowSimpleAboutDialog(wxCommandEvent& WXUNUSED(event)) +{ + wxAboutDialogInfo info; + InitAboutInfoMinimal(info); + + wxAboutBox(info, this); +} + +void Frame::ShowFancyAboutDialog(wxCommandEvent& WXUNUSED(event)) +{ + wxAboutDialogInfo info; + InitAboutInfoWebsite(info); + + wxAboutBox(info, this); +} + +void Frame::ShowFullAboutDialog(wxCommandEvent& WXUNUSED(event)) +{ + wxAboutDialogInfo info; + InitAboutInfoAll(info); + + wxAboutBox(info, this); +} + +// a trivial example of a custom dialog class +class MyAboutDialog : public wxGenericAboutDialog +{ +public: + MyAboutDialog(const wxAboutDialogInfo& info, wxWindow* parent) + { + Create(info, parent); + } + + // add some custom controls + virtual void DoAddCustomControls() wxOVERRIDE + { + AddControl(new wxStaticLine(this), wxSizerFlags().Expand()); + AddText("Some custom text"); + AddControl(new wxStaticLine(this), wxSizerFlags().Expand()); + } +}; + +void Frame::ShowCustomAboutDialog(wxCommandEvent& WXUNUSED(event)) +{ + wxAboutDialogInfo info; + InitAboutInfoAll(info); + + MyAboutDialog dlg(info, this); + dlg.ShowModal(); +} + +#endif // wxUSE_ABOUTDLG + +#if wxUSE_BUSYINFO + +void Frame::ShowBusyInfo(wxCommandEvent& WXUNUSED(event)) +{ + wxWindowDisabler disableAll; + + wxBusyInfo info("Working, please wait...", this); + + for (int i = 0; i < 18; i++) + { + wxMilliSleep(100); + wxTheApp->Yield(); + } + + wxSleep(2); +} + +void Frame::ShowRichBusyInfo(wxCommandEvent& WXUNUSED(event)) +{ + wxWindowDisabler disableAll; + + // This is just an example and not an encouragement for printing + // synchronously from the main thread. + wxBusyInfo info + ( + wxBusyInfoFlags() + .Parent(this) + .Icon(wxArtProvider::GetIcon(wxART_PRINT, + wxART_OTHER, wxSize(128, 128))) + .Title("Printing your document") + .Text("Please wait...") + .Foreground(*wxWHITE) + .Background(*wxBLACK) + .Transparency(4 * wxALPHA_OPAQUE / 5) + ); + + wxSleep(5); +} + +#endif // wxUSE_BUSYINFO + +#if wxUSE_FINDREPLDLG + +void Frame::ShowReplaceDialog(wxCommandEvent& WXUNUSED(event)) +{ + if (m_dlgReplace) + { + m_dlgReplace->Destroy(); + + m_dlgReplace = NULL; + } + else + { + m_dlgReplace = new wxFindReplaceDialog + ( + this, + &m_findData, + "Find and replace dialog", + wxFR_REPLACEDIALOG + ); + + m_dlgReplace->Show(true); + } +} + +void Frame::ShowFindDialog(wxCommandEvent& WXUNUSED(event)) +{ + if (m_dlgFind) + { + m_dlgFind->Destroy(); + + m_dlgFind = NULL; + } + else + { + m_dlgFind = new wxFindReplaceDialog + ( + this, + &m_findData, + "Find dialog", + // just for testing + wxFR_NOWHOLEWORD + ); + + m_dlgFind->Show(true); + } +} + +static wxString DecodeFindDialogEventFlags(int flags) +{ + wxString str; + str << (flags & wxFR_DOWN ? "down" : "up") << ", " + << (flags & wxFR_WHOLEWORD ? "whole words only, " : "") + << (flags & wxFR_MATCHCASE ? "" : "not ") + << "case sensitive"; + + return str; +} + +void Frame::OnFindDialog(wxFindDialogEvent& event) +{ + wxEventType type = event.GetEventType(); + + if (type == wxEVT_FIND || type == wxEVT_FIND_NEXT) + { + wxLogMessage("Find %s'%s' (flags: %s)", + type == wxEVT_FIND_NEXT ? "next " : "", + event.GetFindString(), + DecodeFindDialogEventFlags(event.GetFlags())); + } + else if (type == wxEVT_FIND_REPLACE || + type == wxEVT_FIND_REPLACE_ALL) + { + wxLogMessage("Replace %s'%s' with '%s' (flags: %s)", + type == wxEVT_FIND_REPLACE_ALL ? "all " : "", + event.GetFindString(), + event.GetReplaceString(), + DecodeFindDialogEventFlags(event.GetFlags())); + } + else if (type == wxEVT_FIND_CLOSE) + { + wxFindReplaceDialog* dlg = event.GetDialog(); + + int idMenu; + wxString txt; + if (dlg == m_dlgFind) + { + txt = "Find"; + idMenu = DIALOGS_FIND; + m_dlgFind = NULL; + } + else if (dlg == m_dlgReplace) + { + txt = "Replace"; + idMenu = DIALOGS_REPLACE; + m_dlgReplace = NULL; + } + else + { + txt = "Unknown"; + idMenu = wxID_ANY; + + wxFAIL_MSG("unexpected event"); + } + + wxLogMessage("%s dialog is being closed.", txt); + + if (idMenu != wxID_ANY) + { + GetMenuBar()->Check(idMenu, false); + } + + dlg->Destroy(); + } + else + { + wxLogError("Unknown find dialog event!"); + } +} +#endif // wxUSE_FINDREPLDLG + +Frame::~Frame() +{ + wxConfigBase* pConfig = wxConfigBase::Get(); + if (pConfig == NULL) + return; + StorePositionToConfig(); + pConfig->SetPath(wxT("/TipOfTheDay")); + pConfig->Write("show", (int)m_showTipsAtStartup); + pConfig->Write("index", (int)m_TipOfTheDayIndex); + pConfig->SetPath(wxT("/FileDialog")); + pConfig->Write("index", (int)m_FileDialogFilterIndex); + pConfig->Write("LastUsed", wxString::FromUTF8(m_strLastUsedFile)); + pConfig->SetPath(wxT("/")); +} diff --git a/samples/dialogs/frame.h b/samples/dialogs/frame.h new file mode 100644 index 0000000..4211c88 --- /dev/null +++ b/samples/dialogs/frame.h @@ -0,0 +1,298 @@ +#pragma once +// Define a new frame type +class Frame : public wxFrame +{ + int m_TipOfTheDayIndex; + int m_FileDialogFilterIndex; + std::string m_strLastUsedFile; +public: + bool m_showTipsAtStartup; + Frame(const wxString& title); + virtual ~Frame(); + void StorePositionToConfig(void); + void RestorePositionFromConfig(const wxSize&); + +#if wxUSE_MSGDLG + void MessageBox(wxCommandEvent& event); + void MessageBoxDialog(wxCommandEvent& event); + void MessageBoxDialogWindowModal(wxCommandEvent& event); + void MessageBoxDialogWindowModalClosed(wxWindowModalDialogEvent& event); + void MessageBoxInfo(wxCommandEvent& event); + void MessageBoxWindowModal(wxCommandEvent& event); + void MessageBoxWindowModalClosed(wxWindowModalDialogEvent& event); +#endif // wxUSE_MSGDLG +#if wxUSE_RICHMSGDLG + void RichMessageDialog(wxCommandEvent& event); +#endif // wxUSE_RICHMSGDLG + +#if wxUSE_COLOURDLG + void ChooseColour(wxCommandEvent& event); + void GetColour(wxCommandEvent& event); +#endif // wxUSE_COLOURDLG + +#if wxUSE_FONTDLG + void ChooseFont(wxCommandEvent& event); +#endif // wxUSE_FONTDLG + +#if wxUSE_LOG_DIALOG + void LogDialog(wxCommandEvent& event); +#endif // wxUSE_LOG_DIALOG + +#if wxUSE_INFOBAR + void InfoBarSimple(wxCommandEvent& event); + void InfoBarSimpleWrapped(wxCommandEvent& event); + void InfoBarAdvanced(wxCommandEvent& event); +#endif // wxUSE_INFOBAR + +#if wxUSE_CHOICEDLG + void SingleChoice(wxCommandEvent& event); + void MultiChoice(wxCommandEvent& event); +#endif // wxUSE_CHOICEDLG + +#if wxUSE_REARRANGECTRL + void Rearrange(wxCommandEvent& event); +#endif // wxUSE_REARRANGECTRL + +#if wxUSE_ADDREMOVECTRL + void AddRemove(wxCommandEvent& event); +#endif // wxUSE_ADDREMOVECTRL + +#if wxUSE_TEXTDLG + void LineEntry(wxCommandEvent& event); + void TextEntry(wxCommandEvent& event); + void PasswordEntry(wxCommandEvent& event); +#endif // wxUSE_TEXTDLG + +#ifdef wxUSE_CREDENTIALDLG + void CredentialEntry(wxCommandEvent& event); +#endif // wxUSE_CREDENTIALDLG + +#if wxUSE_NUMBERDLG + void NumericEntry(wxCommandEvent& event); +#endif // wxUSE_NUMBERDLG + +#if wxUSE_FILEDLG + void OnFileOpen(wxCommandEvent& event); + void FileOpen2(wxCommandEvent& event); + void FilesOpen(wxCommandEvent& event); + void FilesOpenWindowModal(wxCommandEvent& event); + void FilesOpenWindowModalClosed(wxWindowModalDialogEvent& event); + void OnSaveNew(wxCommandEvent& event); + void FileSaveWindowModal(wxCommandEvent& event); + void FileSaveWindowModalClosed(wxWindowModalDialogEvent& event); + void MacToggleAlwaysShowTypes(wxCommandEvent& event); +#endif // wxUSE_FILEDLG + +#if USE_FILEDLG_GENERIC + void FileOpenGeneric(wxCommandEvent& event); + void FilesOpenGeneric(wxCommandEvent& event); + void FileSaveGeneric(wxCommandEvent& event); +#endif // USE_FILEDLG_GENERIC + +#if wxUSE_DIRDLG + void DirChoose(wxCommandEvent& event); + void DirChooseWindowModal(wxCommandEvent& event); + void DirChooseWindowModalClosed(wxWindowModalDialogEvent& event); + void DirChooseNew(wxCommandEvent& event); + void DirChooseMultiple(wxCommandEvent& event); +#endif // wxUSE_DIRDLG + +#if USE_DIRDLG_GENERIC + void GenericDirChoose(wxCommandEvent& event); +#endif // USE_DIRDLG_GENERIC + +#if wxUSE_STARTUP_TIPS + void ShowTip(wxCommandEvent& event); +#endif // wxUSE_STARTUP_TIPS + +#if USE_MODAL_PRESENTATION + void ModalDlg(wxCommandEvent& event); +#endif // USE_MODAL_PRESENTATION + void ModelessDlg(wxCommandEvent& event); + void DlgCenteredScreen(wxCommandEvent& event); + void DlgCenteredParent(wxCommandEvent& event); + void MiniFrame(wxCommandEvent& event); + void DlgOnTop(wxCommandEvent& event); + +#if wxUSE_PROGRESSDLG + void ShowProgress(wxCommandEvent& event); +#ifdef wxHAS_NATIVE_PROGRESSDIALOG + void ShowProgressGeneric(wxCommandEvent& event); +#endif // wxHAS_NATIVE_PROGRESSDIALOG + void DoShowProgress(wxGenericProgressDialog& dialog); +#endif // wxUSE_PROGRESSDLG + void ShowAppProgress(wxCommandEvent& event); + +#if wxUSE_ABOUTDLG + void ShowSimpleAboutDialog(wxCommandEvent& event); + void ShowFancyAboutDialog(wxCommandEvent& event); + void ShowFullAboutDialog(wxCommandEvent& event); + void ShowCustomAboutDialog(wxCommandEvent& event); +#endif // wxUSE_ABOUTDLG + +#if wxUSE_BUSYINFO + void ShowBusyInfo(wxCommandEvent& event); + void ShowRichBusyInfo(wxCommandEvent& event); +#endif // wxUSE_BUSYINFO + +#if wxUSE_FINDREPLDLG + void ShowFindDialog(wxCommandEvent& event); + void ShowReplaceDialog(wxCommandEvent& event); + void OnFindDialog(wxFindDialogEvent& event); +#endif // wxUSE_FINDREPLDLG + +#if USE_COLOURDLG_GENERIC + void ChooseColourGeneric(wxCommandEvent& event); +#endif // USE_COLOURDLG_GENERIC + +#if USE_FONTDLG_GENERIC + void ChooseFontGeneric(wxCommandEvent& event); +#endif // USE_FONTDLG_GENERIC + + void OnPropertySheet(wxCommandEvent& event); + + void OnRequestUserAttention(wxCommandEvent& event); +#if wxUSE_NOTIFICATION_MESSAGE + void OnNotifMsg(wxCommandEvent& event); +#endif // wxUSE_NOTIFICATION_MESSAGE + +#if wxUSE_RICHTOOLTIP + void OnRichTipDialog(wxCommandEvent& event); +#endif // wxUSE_RICHTOOLTIP + + void OnStandardButtonsSizerDialog(wxCommandEvent& event); + + void OnTestDefaultActionDialog(wxCommandEvent& event); + void OnModalHook(wxCommandEvent& event); + void OnSimulatedUnsaved(wxCommandEvent& event); + + void OnExit(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +private: +#if wxUSE_COLOURDLG + void OnColourChanged(wxColourDialogEvent& event); + void DoApplyColour(const wxColour& colour); +#endif // wxUSE_COLOURDLG + +#if wxUSE_DIRDLG + void DoDirChoose(int style); +#endif // wxUSE_DIRDLG + +#if USE_MODAL_PRESENTATION + MyModelessDialog* m_dialog; +#endif // USE_MODAL_PRESENTATION + +#if wxUSE_FINDREPLDLG + wxFindReplaceData m_findData; + + wxFindReplaceDialog* m_dlgFind, + * m_dlgReplace; +#endif // wxUSE_FINDREPLDLG + + wxColourData m_clrData; + + // just a window which we use to show the effect of font/colours selection + wxWindow* m_canvas; + +#if wxUSE_INFOBAR + void OnInfoBarRedo(wxCommandEvent& event); + + wxInfoBar* m_infoBarSimple, + * m_infoBarAdvanced; +#endif // wxUSE_INFOBAR + +#if USE_SETTINGS_DIALOG + SettingsData m_settingsData; +#endif // USE_SETTINGS_DIALOG + +#if wxUSE_TIPWINDOW + void OnShowTip(wxCommandEvent& event); + void OnUpdateShowTipUI(wxUpdateUIEvent& event); + + wxTipWindow* m_tipWindow; +#endif // wxUSE_TIPWINDOW + + bool m_confirmExit; + wxDECLARE_EVENT_TABLE(); +}; + +class MyCanvas : public wxScrolledWindow +{ +public: + MyCanvas(wxWindow* parent) : wxScrolledWindow(parent, wxID_ANY) + { + SetForegroundColour(*wxBLACK); + SetBackgroundColour(*wxWHITE); + SetFont(*wxNORMAL_FONT); + } + +private: + void OnPaint(wxPaintEvent& event); + + wxDECLARE_EVENT_TABLE(); +}; + + +// Menu IDs +enum +{ + DIALOGS_CHOOSE_COLOUR = wxID_HIGHEST, + DIALOGS_CHOOSE_COLOUR_ALPHA, + DIALOGS_GET_COLOUR, + DIALOGS_CHOOSE_FONT, + DIALOGS_MESSAGE_BOX, + DIALOGS_MESSAGE_DIALOG, + DIALOGS_MESSAGE_BOX_WXINFO, + DIALOGS_RICH_MESSAGE_DIALOG, + DIALOGS_SINGLE_CHOICE, + DIALOGS_MULTI_CHOICE, + DIALOGS_REARRANGE, + DIALOGS_ADDREMOVE, + DIALOGS_LINE_ENTRY, + DIALOGS_TEXT_ENTRY, + DIALOGS_PASSWORD_ENTRY, + DIALOGS_CREDENTIAL_ENTRY, + DIALOGS_FILE_OPEN, + DIALOGS_FILE_OPEN2, + DIALOGS_FILES_OPEN, + DIALOGS_FILE_SAVE, + DIALOGS_FILE_USE_CUSTOMIZER, + DIALOGS_FILE_USE_EXTRA_CONTROL_CREATOR, + DIALOGS_MAC_TOGGLE_ALWAYS_SHOW_TYPES, + DIALOGS_DIR_CHOOSE, + DIALOGS_DIRNEW_CHOOSE, + DIALOGS_DIRMULTIPLE_CHOOSE, + DIALOGS_TIP, + DIALOGS_NUM_ENTRY, + DIALOGS_LOG_DIALOG, + DIALOGS_INFOBAR_SIMPLE, + DIALOGS_INFOBAR_SIMPLE_WRAPPED, + DIALOGS_INFOBAR_ADVANCED, + DIALOGS_MODAL, + DIALOGS_MODELESS, + DIALOGS_CENTRE_SCREEN, + DIALOGS_CENTRE_PARENT, + DIALOGS_MINIFRAME, + DIALOGS_ONTOP, + DIALOGS_MODELESS_BTN, + DIALOGS_ABOUTDLG_SIMPLE, + DIALOGS_ABOUTDLG_FANCY, + DIALOGS_ABOUTDLG_FULL, + DIALOGS_ABOUTDLG_CUSTOM, + DIALOGS_BUSYINFO, + DIALOGS_BUSYINFO_RICH, + DIALOGS_FIND, + DIALOGS_REPLACE, + DIALOGS_REQUEST, + DIALOGS_NOTIFY_MSG, + DIALOGS_SHOW_TIP, + DIALOGS_RICHTIP_DIALOG, + DIALOGS_PROPERTY_SHEET, + DIALOGS_PROPERTY_SHEET_TOOLBOOK, + DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, + DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, + DIALOGS_TEST_DEFAULT_ACTION, + DIALOGS_MODAL_HOOK, + DIALOGS_SIMULATE_UNSAVED +}; diff --git a/samples/dialogs/stdafx.cpp b/samples/dialogs/stdafx.cpp new file mode 100644 index 0000000..d1303f3 --- /dev/null +++ b/samples/dialogs/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/samples/dialogs/stdafx.h b/samples/dialogs/stdafx.h new file mode 100644 index 0000000..904e9b2 --- /dev/null +++ b/samples/dialogs/stdafx.h @@ -0,0 +1,133 @@ +#pragma once +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "../../src/rho.xpm" + +#include "wx/config.h" +#include "wx/apptrait.h" +#include "wx/datetime.h" +#include "wx/filename.h" +#include "wx/image.h" +#include "wx/bookctrl.h" +#include "wx/artprov.h" +#include "wx/imaglist.h" +#include "wx/minifram.h" +#include "wx/sysopt.h" +#include "wx/notifmsg.h" +#include "wx/generic/notifmsg.h" +#include "wx/modalhook.h" +#include + +#if defined(__WXMSW__) && wxUSE_TASKBARICON +#include "wx/taskbar.h" +#endif + +#if wxUSE_RICHMSGDLG + #include "wx/richmsgdlg.h" +#endif // wxUSE_RICHMSGDLG + +#if wxUSE_COLOURDLG + #include "wx/colordlg.h" +#endif // wxUSE_COLOURDLG + +#if wxUSE_CHOICEDLG + #include "wx/choicdlg.h" +#endif // wxUSE_CHOICEDLG + +#include "wx/rearrangectrl.h" +#include "wx/addremovectrl.h" + +#if wxUSE_STARTUP_TIPS +#include "wx/tipdlg.h" +#endif // wxUSE_STARTUP_TIPS + +#if wxUSE_TIPWINDOW +#include "wx/tipwin.h" +#endif // wxUSE_TIPWINDOW + +#if wxUSE_PROGRESSDLG +#if wxUSE_STOPWATCH && wxUSE_LONGLONG + #include "wx/datetime.h" // wxDateTime +#endif + + #include "wx/progdlg.h" +#endif // wxUSE_PROGRESSDLG + +#include "wx/appprogress.h" + +#if wxUSE_ABOUTDLG +#include "wx/aboutdlg.h" + + // these headers are only needed for custom about dialog + #include "wx/statline.h" + #include "wx/generic/aboutdlgg.h" +#endif // wxUSE_ABOUTDLG + +#if wxUSE_BUSYINFO + #include "wx/busyinfo.h" +#endif // wxUSE_BUSYINFO + +#if wxUSE_NUMBERDLG + #include "wx/numdlg.h" +#endif // wxUSE_NUMBERDLG + +#if wxUSE_FILEDLG +#include "wx/filedlg.h" +#include "wx/filedlgcustomize.h" +#endif // wxUSE_FILEDLG + +#if wxUSE_DIRDLG +#include "wx/dirdlg.h" +#endif // wxUSE_DIRDLG + +#if wxUSE_FONTDLG + #include "wx/fontdlg.h" +#endif // wxUSE_FONTDLG + +#if wxUSE_FINDREPLDLG + #include "wx/fdrepdlg.h" +#endif // wxUSE_FINDREPLDLG + +#if wxUSE_INFOBAR +#include "wx/infobar.h" +#endif // wxUSE_INFOBAR + +#include "wx/spinctrl.h" +#include "wx/propdlg.h" +#include "wx/valgen.h" + +#if wxUSE_CREDENTIALDLG + #include "wx/creddlg.h" +#endif + +#if USE_COLOURDLG_GENERIC + #include "wx/generic/colrdlgg.h" +#endif // USE_COLOURDLG_GENERIC + +#if USE_DIRDLG_GENERIC + #include "wx/generic/dirdlgg.h" +#endif // USE_DIRDLG_GENERIC + +#if USE_FILEDLG_GENERIC + #include "wx/generic/filedlgg.h" +#endif // USE_FILEDLG_GENERIC + +#if USE_FONTDLG_GENERIC + #include "wx/generic/fontdlgg.h" +#endif // USE_FONTDLG_GENERIC + +#if wxUSE_CMDLINE_PARSER +#include "wx/cmdline.h" +#endif // wxUSE_CMDLINE_PARSER + + +#include "dialogs.h" +#include "frame.h" +#include "app.h" + diff --git a/samples/dialogs/tip.xpm b/samples/dialogs/tip.xpm new file mode 100644 index 0000000..28ea755 --- /dev/null +++ b/samples/dialogs/tip.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static const char *const tip_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 119 2", +" c #141414", +". c #1B1B1B", +"X c #1F2527", +"o c #242525", +"O c #242728", +"+ c #262A2B", +"@ c #2B2B2B", +"# c #2A2E30", +"$ c #2C3233", +"% c #2C3639", +"& c #2F3A3D", +"* c #313131", +"= c #303C3F", +"- c #2D3E42", +"; c #323F42", +": c #33454A", +"> c #34494F", +", c #324A50", +"< c #3B4E52", +"1 c #2F5058", +"2 c #325157", +"3 c #3D545A", +"4 c #3A5A62", +"5 c #34606A", +"6 c #3F616A", +"7 c #464646", +"8 c #4B4B4B", +"9 c #41585E", +"0 c gray33", +"q c #5D5D5D", +"w c #425B62", +"e c #456067", +"r c #46646B", +"t c #456972", +"y c #4B6972", +"u c #416F7A", +"i c #646464", +"p c gray42", +"a c #696F71", +"s c #767676", +"d c #787777", +"f c gray49", +"g c #3E7582", +"h c #3E7D8A", +"j c #417A86", +"k c #417F8E", +"l c #3E8494", +"z c #418595", +"x c #4D8995", +"c c #468D9E", +"v c #6B848A", +"b c #4795A7", +"n c #4F92A1", +"m c #4D9AAA", +"M c #5695A4", +"N c #55A2B3", +"B c #5FAABA", +"V c #7BA6AF", +"C c #4FAFC5", +"Z c #5DB7CA", +"A c #52BAD1", +"S c #58BDD4", +"D c #62C2D5", +"F c #64C3DA", +"G c #73C8DA", +"H c #7ECBDD", +"J c #868686", +"K c gray55", +"L c #9FA0A0", +"P c #98A8AB", +"I c #ADADAC", +"U c #AAB1B2", +"Y c #A8B9BD", +"T c gray70", +"R c #90C3CF", +"E c #87C8D7", +"W c #82CADA", +"Q c #91C8D4", +"! c #93CFDC", +"~ c #98CEDB", +"^ c #93D1DF", +"/ c #9AD1DC", +"( c #A4CCD7", +") c #A3CFDA", +"_ c #A1D0DB", +"` c #ACD1DA", +"' c #B2D6DE", +"] c #BCD7DD", +"[ c #89D2E2", +"{ c #9BD5E1", +"} c #A9DEE9", +"| c #BFE1E7", +" . c #BDE3EB", +".. c #C5C5C5", +"X. c #CACACA", +"o. c #C2D5D9", +"O. c #C2D8DD", +"+. c #CCD9DD", +"@. c #D4DBDD", +"#. c #DBDDDE", +"$. c #E0DFDF", +"%. c #CCDDE1", +"&. c #D2DFE1", +"*. c #CCE5EB", +"=. c #D6E2E4", +"-. c #DCE3E5", +";. c #D4E6E9", +":. c #DBE6E8", +">. c #E2E4E4", +",. c #E6E9E9", +"<. c #ECECEC", +"1. c #F1EFEF", +"2. c #E1EDF0", +"3. c #E9EFF0", +"4. c #EEF3F3", +"5. c #F5F5F4", +"6. c #F8F7F7", +"7. c #FBFBFA", +"8. c None", +/* pixels */ +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.o o o o @ @ o o o o 8.8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.o o @ * * q q f J i q 7 * @ o o 8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.o O @ 7 K X.7.7.7.7.7.7.7.7.>.I i * @ o 8.8.8.8.8.8.", +"8.8.8.8.8.o @ 8 T 6.7.7.7.7.7.7.7.7.7.7.7.7.7.#.s @ o o 8.8.8.8.", +"8.8.8.o O * K 5.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7...8 O o 8.8.8.", +"8.8.o O * I 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.>.0 O o 8.8.", +"8.8.o @ I 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.<.7 O 8.8.", +"8.o @ d 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.X.@ o 8.", +"8.O @ $.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.6.a O 8.", +"o @ p 6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.Y @ o ", +"o @ L 6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.*.$ o ", +"o O U 6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.5. .; o ", +"O $ P 5.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.4.} % o ", +"o < v 3.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.2.W O o ", +"o w < *.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.| x # o ", +"8.$ < V :.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.;.[ , ; ", +"8.o y : ( -.<.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.<.=.{ j 3 o 8.", +"8.8.+ w 4 ` =.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.%.^ m > % . 8.", +"8.8.o & 3 2 Q O.-.<.<.<.<.<.<.<.<.<.<.<.<.<.,.=.' H z : : . 8.8.", +"8.8.8.o % w - M / ] &.-.,.,.<.<.<.<.<.<.<.>.O.! Z 5 < ; . 8.8.8.", +"8.8.8.8.o O e : 1 n W ~ ` ] O.%.%.+.@.>.,.+.! z : w @ . 8.8.8.8.", +"8.8.8.8.8.8.o % r 3 > 5 h N B G G R o.#.>.` D : ; . 8.8.8.8.8.", +"8.8.8.8.8.8.8.8.o + : w y w 3 3 - X ` @.%.W l w . 8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.. o o o o O + - ( +._ S 6 O 8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.o 4 ( ) F g = . 8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.O u E F z < . 8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.o 3 C A k > . 8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.9 c b t + . 8.8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.: % o . 8.8.8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.. 8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.", +"8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8." +}; diff --git a/samples/dialogs/tips.txt b/samples/dialogs/tips.txt new file mode 100644 index 0000000..fe8a12e --- /dev/null +++ b/samples/dialogs/tips.txt @@ -0,0 +1,18 @@ +Startup tips are documented in the "Startup tips overview" section of wxWindows documentation. +These tips are being read from the tips.txt text file in this directory. Each line of the file contains a single tip. +If you close and open this tips dialog, you will notice that the tip numbers start at the point you were at when you closed the dialog last time. This allows easy cycling through the entire list of tips, instead of always showing the initial tips over and over. +Often you will want to save to the application's wxConfig, the last tip that the user saw, as well as whether they want to see tips on startup. +Comments in the tips file have a # as the first character. Comments are automatically skipped over. See the tips.txt file in this directory for the example. +# This line is a comment since it started with a #, and is skipped. +Blank lines in the tip file are also automatically skipped over. Lines with only spaces are also considered empty. +The next line in this tip file is empty, so it will be automatically skipped. + +The next line in this tip file is just empty spaces, so it is considered empty too, and is also automatically skipped. + +You can easily add translations to your startup tips via the usual gettext methods by wrapping a string in a gettext macro, which is _(""). See next tip for example. +_("This tip is marked as a translatable string by wrapping it inside the usual gettext macro, so it can be collected by gettext and added to a translation catalog. Your application can then use this catalog and serve out a translated version of the tip.") +Translatable strings must strictly begin with _(", not _( " or wxGetTranslation(" or something else. +If you are using gettext translatable strings, don't forget to escape to replace any " characters within the tip with a \" instead +_("This is a translatable tip with the quoted words \"Escape me\" properly escaped.") +If you have very specialized needs, you can derive your own wxTipProvider and use that instead. +If you want to modify the tip content at runtime for purposes other than translation (for example, variable expansion), one easy option is to use a custom tip provider derived from wxFileTipProvider. Your custom tip provider would contain a single virtual function to override: PreprocessTip(). diff --git a/src/app.cpp b/src/app.cpp index 224c8e1..5c12081 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -2,11 +2,11 @@ wxIMPLEMENT_APP(App); -App::App() +App::App() : m_Config("wallet", "rho") { assert (singletonApp == nullptr); singletonApp = this; - + wxConfigBase::DontCreateOnDemand(); } App::~App() @@ -18,41 +18,40 @@ App::~App() } bool App::OnInit() -{ if (wxApp::OnInit()) { - pConfig = std::unique_ptr(new wxConfig("wallet", "rho")); - /* This causes the non volatile config data to be stored under rho\wallet - We will generally place data in the database, and if additional executables need their own data - in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */ - pConfig->SetRecordDefaults(false); - /* pConfig corresponds to the Windows Registry entry - Computer\HKEY_CURRENT_USER\Software\rho\wallet +{ + if (wxApp::OnInit()) { + wxConfigBase* pConfig = &m_Config; + /* This causes the non volatile config data to be stored under rho\wallet + We will generally place data in the database, and if additional executables need their own data + in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */ + /* pConfig corresponds to the Windows Registry entry + Computer\HKEY_CURRENT_USER\Software\rho\wallet - Contrary to wxWidgets documentation, the config data on windows is by default stored in - HKCU, HKEY_CURRENT_USER, not in HKLM, HKEY_LOCAL_MACHINE. + Contrary to wxWidgets documentation, the config data on windows is by default stored in + HKCU, HKEY_CURRENT_USER, not in HKLM, HKEY_LOCAL_MACHINE. - We probably should have placed per user data in an sqlite3 file in - wxStandardPaths::GetUserDataDir() + We probably should have placed per user data in an sqlite3 file in + wxStandardPaths::GetUserDataDir() - Data global to all users has to go in an sqlite3 file in wxStandardPaths::GetAppDocumentsDir() - or wxStandardPaths::GetLocalDataDir() + Data global to all users has to go in an sqlite3 file in wxStandardPaths::GetAppDocumentsDir() + or wxStandardPaths::GetLocalDataDir() - User local database will record the derivation of all secrets, and what wallets along the path - are logged in. The local machine database will hold the global consensus blockchain, which contains - no privacy sensitive information, and will also hold data global to all users on a particular - machine. + User local database will record the derivation of all secrets, and what wallets along the path + are logged in. The local machine database will hold the global consensus blockchain, which contains + no privacy sensitive information, and will also hold data global to all users on a particular + machine. - A wallet's secret can be stored in a file - we will eventually provide passwords for files, - but passwords provide a false sense of security, because if someone gets a copy of that file, - a sophisticated attacker can perform an offline brute force attack, thus a human memorable - password only provides protection against casual and opportunistic attackers. - If the file is insecure, password needs to impossible to remember, and stored somewhere secure..*/ - - Frame* frame = new Frame(pConfig->GetAppName()); - frame->Show(true); //Frame, being top level unowned window, is owned by the one and only message pump - if (m_display_in_front && singletonFrame != nullptr && singletonFrame->m_pLogWindow != nullptr) singletonFrame->m_pLogWindow->GetFrame()->Raise(); - return true; -} -else return false; + A wallet's secret can be stored in a file - we will eventually provide passwords for files, + but passwords provide a false sense of security, because if someone gets a copy of that file, + a sophisticated attacker can perform an offline brute force attack, thus a human memorable + password only provides protection against casual and opportunistic attackers. + If the file is insecure, password needs to impossible to remember, and stored somewhere secure..*/ + Frame* frame = new Frame(pConfig->GetAppName()); + frame->Show(true); //Frame, being top level unowned window, is owned by the one and only message pump + if (m_display_in_front && singletonFrame != nullptr && singletonFrame->m_pLogWindow != nullptr) singletonFrame->m_pLogWindow->GetFrame()->Raise(); + return true; + } + else return false; } int App::OnRun() @@ -196,8 +195,7 @@ void App::OnError(wxCommandEvent& event) } int App::OnExit() -{ - assert(pConfig.get()); - if (errorCode)wxLogDebug("%s", szError); +{ if (errorCode)wxLogDebug("%s", szError); + m_Config.Flush(); return 0; } diff --git a/src/app.h b/src/app.h index 3ccc13f..ab8f91e 100644 --- a/src/app.h +++ b/src/app.h @@ -3,10 +3,6 @@ class App : public wxApp { public: - std::unique_ptrpConfig; - // pConfig corresponds to the Windows Registry entry Computer\HKEY_CURRENT_USER\Software\ro\wallet - // Don't use the registry for stuff better served by wxStandardPaths and sqlit3 files located - // in locations specified by wxStandardPaths App(); virtual ~App(); virtual bool OnInit() wxOVERRIDE; @@ -22,6 +18,10 @@ public: bool m_log_focus_events{ false }; bool m_quick_unit_test{ false }; bool m_complete_unit_test{ false }; + wxConfig m_Config; + // m_Config corresponds to the Windows Registry entry Computer\HKEY_CURRENT_USER\Software\ro\wallet + // Don't use the registry for stuff better served by wxStandardPaths and sqlit3 files located + // in locations specified by wxStandardPaths wxVector m_params; }; diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 74502fc..bc2b98b 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -71,7 +71,7 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : } Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this); this->SetSize(this->GetParent()->GetClientSize()); - singletonFrame->m_LastUsedSqlite.Assign(walletfile); + singletonFrame->m_LastUsedWallet.Assign(walletfile); wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) }; singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu. diff --git a/src/frame.cpp b/src/frame.cpp index a2096a3..5addfcb 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -7,21 +7,22 @@ Frame* singletonFrame{nullptr}; void Frame::RestorePositionFromConfig(const wxSize& bestSize) { + wxConfigBase* pConfig = &singletonApp->m_Config; // SetPath() understands ".." but you should probably never use it. - singletonApp->pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; + pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; // restore frame position and size - int x = singletonApp->pConfig->ReadLong(wxT("x"), scr.x / 4); - int y = singletonApp->pConfig->ReadLong(wxT("y"), scr.y / 4); - int w = singletonApp->pConfig->ReadLong(wxT("w"), scr.x / 2); - int h = singletonApp->pConfig->ReadLong(wxT("h"), scr.y / 2); + int x = pConfig->ReadLong(wxT("x"), scr.x / 4); + int y = pConfig->ReadLong(wxT("y"), scr.y / 4); + int w = pConfig->ReadLong(wxT("w"), scr.x / 2); + int h = pConfig->ReadLong(wxT("h"), scr.y / 2); w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9); h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5); x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12)); y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10)); this->Move(x, y); - this->Maximize(singletonApp->pConfig->ReadBool(wxT("Maximized"), false)); + this->Maximize(pConfig->ReadBool(wxT("Maximized"), false)); + pConfig->SetPath(wxT("/")); this->SetSize(w, h); - singletonApp->pConfig->SetPath(wxT("/")); if (singletonApp->m_display || m_pLogWindow != nullptr) { m_pLogWindow->GetFrame()->SetSize(w, h); if (singletonApp->m_display_in_front) { @@ -39,31 +40,32 @@ void Frame::RestorePositionFromConfig(const wxSize& bestSize) { } void Frame::StorePositionToConfig() { - if (singletonApp->pConfig) { - singletonApp->pConfig->SetPath(wxT("/MainFrame")); + wxConfigBase* pConfig = &singletonApp->m_Config; + if (pConfig) { + pConfig->SetPath(wxT("/MainFrame")); if (this->IsMaximized()) { - singletonApp->pConfig->Write(wxT("Maximized"), true); + pConfig->Write(wxT("Maximized"), true); } else { // save the frame position int x, y, w, h; this->GetSize(&w, &h); this->GetPosition(&x, &y); - singletonApp->pConfig->Write(wxT("x"), (long)x); - singletonApp->pConfig->Write(wxT("y"), (long)y); - singletonApp->pConfig->Write(wxT("w"), (long)w); - singletonApp->pConfig->Write(wxT("h"), (long)h); - singletonApp->pConfig->Write(wxT("Maximized"), false); + pConfig->Write(wxT("x"), (long)x); + pConfig->Write(wxT("y"), (long)y); + pConfig->Write(wxT("w"), (long)w); + pConfig->Write(wxT("h"), (long)h); + pConfig->Write(wxT("Maximized"), false); } - singletonApp->pConfig->SetPath(wxT("/")); + pConfig->SetPath(wxT("/")); } } // main frame ctor -Frame::Frame(wxString wxs) +Frame::Frame(const wxString& wxs) : wxFrame(nullptr, myID_MAINFRAME, wxs, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, wxs), m_panel(), - m_LastUsedSqlite() + m_LastUsedWallet() { try { assert(singletonFrame == nullptr); @@ -129,11 +131,11 @@ Frame::Frame(wxString wxs) menuFile->Append(wxID_OPEN, menu_strings[0].tail[2][0], menu_strings[0].tail[2][1]); menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN); { auto _ = new wxMenuItem(menuFile, wxID_CLOSE); - _->SetHelp(menu_strings[0].tail[3][1] + m_LastUsedSqlite.GetFullPath()); + _->SetHelp(menu_strings[0].tail[3][1] + m_LastUsedWallet.GetFullPath()); menuFile->Append(_); menuFile->Bind(wxEVT_MENU, &Frame::OnMyCloseMPanel, this, wxID_CLOSE); } - menuFile->Append(myID_DELETECONFIG, menu_strings[0].tail[4][0], menu_strings[0].tail[4][1] + m_LastUsedSqlite.GetFullPath()); + menuFile->Append(myID_DELETECONFIG, menu_strings[0].tail[4][0], menu_strings[0].tail[4][1] + m_LastUsedWallet.GetFullPath()); menuFile->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG); menuFile->Append(wxID_EXIT); menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); @@ -149,16 +151,34 @@ Frame::Frame(wxString wxs) CreateStatusBar(); menuBar->EnableTop(1, false); //disable edit menu. // child controls - m_LastUsedSqlite.Assign(singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT(""))); wxPanel* panel{ nullptr }; + m_panel = panel; + wxConfigBase& Config = singletonApp->m_Config; + Config.SetPath(wxT("/TipOfTheDay")); + m_showTipsAtStartup = Config.Read("show", true); + m_TipOfTheDayIndex = Config.Read("index", int(-1)); + wxStandardPaths& StandardPaths(wxStandardPaths::Get()); + StandardPaths.UseAppInfo(0); + StandardPaths.DontIgnoreAppSubDir(); + m_DefaultWalletLocation.AssignDir(StandardPaths.GetUserLocalDataDir()); + m_DefaultWalletLocation.AppendDir("wallet"); + m_DefaultWalletLocation.SetFullName("default.wallet"); + Config.SetPath(wxT("/FileDialog")); + m_FileDialogFilterIndex = Config.Read("index", int(0)); + m_LastUsedWallet = Config.Read("LastUsed", m_DefaultWalletLocation.GetFullPath()); + Config.SetPath(wxT("/")); + if (!m_LastUsedWallet.IsOk() || !m_LastUsedWallet.HasName()) { + m_LastUsedWallet = m_DefaultWalletLocation; + } try { - if (m_LastUsedSqlite.IsOk()) + if (m_LastUsedWallet.IsOk()) { //Try to load an existing file. - panel = new display_wallet(this, m_LastUsedSqlite); + panel = new display_wallet(this, m_LastUsedWallet); } else { panel = new welcome_to_rhocoin(this); } + } catch (const std::exception& e) { // if the attempt to load an existing wallet file fails, @@ -167,12 +187,12 @@ Frame::Frame(wxString wxs) queue_error_message(e.what()); panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame. } + m_panel = panel; // m_panel is a non owning pointer in the derived class that duplicates the // owning pointer in the base class. This looks like a violation of DIY. // but I have the concept of the primary child of the frame window, while // wxWidgets lacks that concept. // m_panel signifies the child window of the frame that currently matters. - m_panel = panel; this->RestorePositionFromConfig(ClientToWindowSize(m_panel->GetBestSize())); SetClientSize(GetClientSize()); } @@ -211,14 +231,13 @@ void Frame::OnAbout(wxCommandEvent& event) void Frame::OnDeleteConfiguration(wxCommandEvent&) { - std::unique_ptrpConfig{ wxConfigBase::Set(nullptr) }; + wxConfigBase* pConfig = &singletonApp->m_Config; if (pConfig) { if (pConfig->DeleteAll()) { wxLogMessage(wxT("Config file/registry key successfully deleted.")); wxConfigBase::DontCreateOnDemand(); - pConfig.release(); } else { @@ -270,7 +289,9 @@ CREATE TABLE "Misc"( "ROWID" INTEGER PRIMARY KEY, "m" ANY ) STRICT; +COMMIT; +BEGIN IMMEDIATE TRANSACTION; CREATE VIEW UserZookoIDs AS SELECT "Names".name AS name, @@ -279,7 +300,9 @@ FROM "Names" INNER JOIN "Keys" ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1 ORDER BY LOWER("name"), "name" COLLATE BINARY; +COMMIT; +BEGIN IMMEDIATE TRANSACTION; CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN INSERT OR FAIL INTO "Names" VALUES( NULL, @@ -291,15 +314,14 @@ CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW last_insert_rowid(), 1 ); -END +END; CREATE TRIGGER DeleteUserZookoID INSTEAD OF DELETE ON UserZookoIDs FOR EACH ROW BEGIN DELETE FROM "Keys" WHERE "Keys"."pubkey" = OLD."pubkey"; DELETE FROM "Names" WHERE "Names"."name" = OLD."name"; -END - - -COMMIT;)|"); +END; +COMMIT; +)|"); wxLogMessage("\t\tConstructing default wallet %s", filename.GetFullPath()); // We now have a working wallet file with no valid data. Attempting to create a strong random secret, a name, and public and private keys for that name. wxLogMessage("\t\tGenerating random 128 bit wallet secret"); @@ -322,62 +344,83 @@ COMMIT;)|"); } } -class hide_panel { - wxPanel* oldpanel; -public: - hide_panel(wxPanel* v): oldpanel(v){ - v->Hide(); - } - ~hide_panel() { - if (oldpanel == singletonFrame->m_panel) oldpanel->Show(); - } -}; - void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) { + wxString wxstrWalletPath; + wxString wxstrWalletName(wxEmptyString); + if (m_LastUsedWallet.IsOk())wxstrWalletPath = m_LastUsedWallet.GetPath(); + else wxstrWalletPath = m_DefaultWalletLocation.GetPath(); + if (!m_LastUsedWallet.FileExists()) wxstrWalletName = m_LastUsedWallet.GetFullName(); wxFileDialog dialog(this, sz_new_wallet_new_secret, - wxStandardPaths::Get().GetUserLocalDataDir(), - sz_default_wallet_name, - sz_wallet_files_title, - wxFD_SAVE | wxFD_OVERWRITE_PROMPT); - dialog.SetFilterIndex(1); + wxstrWalletPath, + wxstrWalletName, + wxString::Format + ("wallet (*.wallet)|*.wallet|All (%s)|%s", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT + ); + dialog.SetFilterIndex(m_FileDialogFilterIndex); if (dialog.ShowModal() == wxID_OK) { wxLogMessage("%s, filter %d", - dialog.GetPath(), dialog.GetFilterIndex()); - hide_panel hid(m_panel); - wxString wxStrWallet{ dialog.GetDirectory() + "/" + dialog.GetFilename() }; - wxFileName wxFileWallet(wxStrWallet); - ristretto255::hash<256> WalletSecret{ wxStrWallet.ToUTF8() }; + dialog.GetPath(), + dialog.GetFilterIndex() + ); + wxFileName wxFileWallet(dialog.GetPath()); + ristretto255::hash<256> WalletSecret( wxFileWallet.GetFullPath().ToUTF8()); NewWallet(wxFileWallet, WalletSecret); - wxLogMessage("new wallet created: %s", wxStrWallet); - if (m_panel)m_panel->Destroy(); - m_panel = new display_wallet(this, wxFileWallet); - m_panel->Show(); + wxLogMessage("new wallet created: %s", wxFileWallet.GetFullPath()); + if (m_panel)m_panel->Close(true); + m_panel = nullptr; + auto panel = new display_wallet(this, wxFileWallet); + m_panel = panel; + m_FileDialogFilterIndex = dialog.GetFilterIndex(); + m_LastUsedWallet = wxFileWallet; //We do this last, so that if an exception occurs the filename is forgotten. } } void Frame::OnFileOpen(wxCommandEvent&) { - wxString directory{ wxT("") }; - wxString file{ wxT("") }; - if (m_LastUsedSqlite.IsOk()) { - directory = m_LastUsedSqlite.GetPath(); - file = m_LastUsedSqlite.GetFullName(); + wxString directory(wxEmptyString); + wxString file(wxEmptyString); + if (m_LastUsedWallet.IsOk()) { + directory = m_LastUsedWallet.GetPath(); + if (m_LastUsedWallet.FileExists()) { + file = m_LastUsedWallet.GetFullName(); + } } - - wxFileDialog - dialog(this, sz_open_wallet_file, directory, file, - sz_wallet_files_title, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR); + else { + m_LastUsedWallet = m_DefaultWalletLocation; + directory = m_LastUsedWallet.GetPath(); + if (m_LastUsedWallet.FileExists()) { + file = m_LastUsedWallet.GetFullName(); + } + } + wxFileDialog dialog(this, + sz_open_wallet_file, + m_LastUsedWallet.GetPath(), + m_LastUsedWallet.GetFullName(), + wxString::Format + ("wallet (*.wallet)|*.wallet|All (%s)|%s", + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR); + dialog.SetFilterIndex(m_FileDialogFilterIndex); if (dialog.ShowModal() == wxID_CANCEL) return; // the user changed idea... wxLogMessage("Opening %s", dialog.GetPath()); wxFileName walletfile(dialog.GetPath()); - if (m_panel)m_panel->Destroy(); //Destroy somehow manages to execute + if (m_panel)m_panel->Close(); //Destroy somehow manages to execute // the correct derived destructor regardless of what kind of object it is. + m_panel = nullptr; display_wallet* panel = new display_wallet(this, walletfile); m_panel = panel; - m_panel->Show(); + //m_panel->Show(); + m_FileDialogFilterIndex = dialog.GetFilterIndex(); + m_LastUsedWallet = walletfile; //We do this last, so that if an exception occurs the filename is forgotten. } void Frame::RecreateWalletFromExistingSecret(wxCommandEvent&) { @@ -403,13 +446,6 @@ void Frame::OnMyCloseMPanel(wxCommandEvent& event) { if (m_panel) { if (!m_panel->Close(false)) throw MyException("Close cancelled"); } - assert(m_panel == nullptr); - singletonApp->pConfig->SetPath(wxT("/Wallet")); - if (singletonApp->pConfig->Read(wxT("LastUsed"), wxT("")) == m_LastUsedSqlite.GetFullPath()) { - singletonApp->pConfig->DeleteEntry(wxT("LastUsed")); - m_LastUsedSqlite.Clear(); - } - assert(m_panel == nullptr); } void Frame::OnMenuOpen(wxMenuEvent& evt) { @@ -423,10 +459,14 @@ void Frame::OnMenuOpen(wxMenuEvent& evt) { Frame::~Frame() { assert(singletonFrame == this); singletonFrame = nullptr; - wxConfigBase* pConfig = wxConfigBase::Get(); - if (pConfig == nullptr)return; + wxConfigBase& Config = singletonApp->m_Config; StorePositionToConfig(); - if (singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")) != m_LastUsedSqlite.GetFullPath()) { - pConfig->Write(wxT("/Wallet/LastUsed"), m_LastUsedSqlite.GetFullPath()); - } + Config.SetPath(wxT("/TipOfTheDay")); + Config.Write("show", (int)m_showTipsAtStartup); + Config.Write("index", (int)m_TipOfTheDayIndex); + Config.SetPath(wxT("/FileDialog")); + Config.Write("index", (int)m_FileDialogFilterIndex); + Config.Write(wxT("LastUsed"), m_LastUsedWallet.GetFullPath()); + Config.SetPath(wxT("/")); + Config.Flush(); } diff --git a/src/frame.h b/src/frame.h index 302a3a3..056872c 100644 --- a/src/frame.h +++ b/src/frame.h @@ -57,13 +57,16 @@ public: }; class Frame : public wxFrame -{ +{ int m_TipOfTheDayIndex; + int m_FileDialogFilterIndex; public: + bool m_showTipsAtStartup; + wxFileName m_LastUsedWallet; + wxFileName m_DefaultWalletLocation; + Frame(const wxString& title); + virtual ~Frame(); wxLogWindow*m_pLogWindow{ nullptr }; std::unique_ptrm_pLogNull{ nullptr }; - Frame(wxString); - ~Frame(); - wxFileName m_LastUsedSqlite; wxPanel* m_panel{nullptr}; //The once current child panel. private: typedef MenuLink MenuLink; diff --git a/src/rho.xpm b/src/rho.xpm index 808791c..7e196e0 100644 --- a/src/rho.xpm +++ b/src/rho.xpm @@ -1,151 +1,1664 @@ /* XPM */ -static const char *const rho[] = { -"32 32 115 2 0 0", -" c #60FF60", -"! c #62FF62", -"# c #64FF64", -"$ c #63FF63", -"% c #61FF61", -"& c #5CE55C", -"' c #347A34", -"( c #1E3A1E", -") c #0E1C0E", -"* c #182818", -"+ c #2A5B2A", -", c #4CB44C", -"- c #61FA61", -". c #2E642E", -"/ c #000000", -"0 c #121E12", -"1 c #0D0D0D", -"2 c #1A311A", -"3 c #5EEB5E", -"4 c #5CEF5C", -"5 c #132713", -"6 c #203E20", -"7 c #65FF65", -"8 c #58D458", -"9 c #1E3F1E", -": c #0F1E0F", -"; c #62F262", -"< c #60FE60", -"= c #204220", -"> c #010301", -"? c #52CA52", -"@ c #386F38", -"A c #255225", -"B c #4DB84D", -"C c #060A06", -"D c #60FC60", -"E c #254E25", -"F c #040904", -"G c #5AD65A", -"H c #5FFC5F", -"I c #295C29", -"J c #111A11", -"K c #5BE35B", -"L c #020102", -"M c #030603", -"N c #378437", -"O c #5EFB5E", -"P c #121F12", -"Q c #0A1C0A", -"R c #5EF85E", -"S c #275527", -"T c #020302", -"U c #295329", -"V c #60F960", -"W c #070507", -"X c #5FFB5F", -"Y c #439D43", -"Z c #010201", -"[ c #193819", -"] c #5DF65D", -"^ c #60FD60", -"_ c #4FC14F", -"` c #010101", -"a c #173517", -"b c #59D359", -"c c #254C25", -"d c #59D159", -"e c #020502", -"f c #5FFD5F", -"g c #4ABA4A", -"h c #4FBD4F", -"i c #121912", -"j c #5FFA5F", -"k c #3A873A", -"l c #132813", -"m c #63F163", -"n c #152815", -"o c #010401", -"p c #48AD48", -"q c #409340", -"r c #429542", -"s c #2C5B2C", -"t c #050805", -"u c #51C151", -"v c #5FFF5F", -"w c #46A146", -"x c #234723", -"y c #0A150A", -"z c #316A31", -"{ c #1D391D", -"| c #367736", -"} c #346F34", -"~ c #152715", -" ! c #397C39", -"!! c #5DE25D", -"#! c #397E39", -"$! c #245424", -"%! c #295B29", -"&! c #3E903E", -"'! c #61EF61", -"(! c #0B1C0B", -")! c #63F563", -"*! c #0D1E0D", -"+! c #65ED65", -",! c #000100", -"-! c #152615", -".! c #59DE59", -"/! c #183218", -"0! c #52C452", -"1! c #214521", -"2! c #43A343", -"3! c #2F652F", -"4! c #2E672E", -"5! c #3B8B3B", -"6! c None", -"6!6!6!6!6!6!6!6!6!6!6!6! 6!6!6!6!6!6!6!6!6!6!6!6!", -"6!6!6!6!6!6!6!6!6! 6!6!6!6!6!6!6!6!6!", -"6!6!6!6!6!6!6! ! # $ % 6!6!6!6!6!6!6!", -"6!6!6!6!6!6! % & ' ( ) * + , # 6!6!6!6!6!6!", -"6!6!6!6!6! - . / 0 1 / / / / 2 3 6!6!6!6!6!", -"6!6!6!6! 4 5 6 7 $ # 8 9 / / / : ; 6!6!6!6!", -"6!6!6! < = > ? % @ / / > A # 6!6!6!", -"6!6! < B / C 7 D E / / F G 6!6!", -"6!6! H I / J ! K L / M N ! 6!6!", -"6! O P / Q ! R S / T U ! 6!", -"6! V W / Q ! X Y / Z [ $ 6!", -"6! ] / / Q ! ^ _ / ` a $ 6!", -" ] / / Q ! < b / T c ! ", -" ] / / Q ! < d / e ' ! ", -" ] / / Q ! f g / F h % ", -" ] / / i $ j k / l # ", -" ] / / M m R n o p % ", -" ] / / T q % H r / s # ", -" ] / / / t u $ v $ w / x 7 ", -" ] / / y z / { | } ~ / !# ", -"6! ] / / Q $ !!#!$!%!&!'!% 6!", -"6! ] / / (!! % % 6!", -"6! )!/ / *!! 6!", -"6!6! +!/ ,!-!! 6!6!", -"6!6! .!/ ,!/!! 6!6!", -"6!6!6! < 0!/ ` 1!% 6!6!6!", -"6!6!6!6! < 2!/ Z 3!% 6!6!6!6!", -"6!6!6!6!6! f 4!/ / 5!% 6!6!6!6!6!", -"6!6!6!6!6!6! f < < % 6!6!6!6!6!6!", -"6!6!6!6!6!6!6! 6!6!6!6!6!6!6!", -"6!6!6!6!6!6!6!6!6! 6!6!6!6!6!6!6!6!6!", -"6!6!6!6!6!6!6!6!6!6!6!6! 6!6!6!6!6!6!6!6!6!6!6!6!" -}; +static const char * rho_xpm[] = { +"256 256 1405 2", +" c None", +". c #60FF60", +"+ c #62FF62", +"@ c #63FF63", +"# c #62FE62", +"$ c #61FD61", +"% c #60FC60", +"& c #5FFD5F", +"* c #5FFC5F", +"= c #5FFB5F", +"- c #5EFB5E", +"; c #60FD60", +"> c #61FF61", +", c #62FD62", +"' c #5AFC5A", +") c #83F183", +"! c #AFCCAF", +"~ c #909E90", +"{ c #667666", +"] c #4D5E4D", +"^ c #415141", +"/ c #334333", +"( c #263626", +"_ c #172817", +": c #0E1E0E", +"< c #132513", +"[ c #233323", +"} c #304030", +"| c #3D4D3D", +"1 c #495B49", +"2 c #5A6A5A", +"3 c #798979", +"4 c #AAB2AA", +"5 c #ACE2AC", +"6 c #74FB74", +"7 c #5DFB5D", +"8 c #61FC61", +"9 c #63FE63", +"0 c #67F767", +"a c #5FEE5F", +"b c #65E365", +"c c #8BBC8B", +"d c #7E7B7E", +"e c #3D403D", +"f c #151915", +"g c #090F09", +"h c #0C0D0C", +"i c #0A090A", +"j c #070607", +"k c #050505", +"l c #040404", +"m c #030303", +"n c #020202", +"o c #010101", +"p c #000000", +"q c #010001", +"r c #020102", +"s c #030203", +"t c #040304", +"u c #060506", +"v c #080808", +"w c #0B0B0B", +"x c #0C0E0C", +"y c #0C100C", +"z c #282C28", +"A c #535653", +"B c #9E989E", +"C c #87D487", +"D c #5DEA5D", +"E c #68F468", +"F c #68FC68", +"G c #5FFF5F", +"H c #5FFE5F", +"I c #6FF26F", +"J c #6DCD6D", +"K c #549D54", +"L c #5F715F", +"M c #454545", +"N c #141714", +"O c #0A0C0A", +"P c #090709", +"Q c #040204", +"R c #050405", +"S c #0B090B", +"T c #090E09", +"U c #2A2D2A", +"V c #656365", +"W c #648C64", +"X c #5EB55E", +"Y c #83E883", +"Z c #73FD73", +"` c #76DA76", +" . c #5D835D", +".. c #2A472A", +"+. c #262526", +"@. c #090A09", +"#. c #060606", +"$. c #070507", +"%. c #070907", +"&. c #141514", +"*. c #333433", +"=. c #496A49", +"-. c #A3C6A3", +";. c #88F888", +">. c #5EFE5E", +",. c #5DFF5D", +"'. c #83F683", +"). c #92AD92", +"!. c #343834", +"~. c #070807", +"{. c #020302", +"]. c #050605", +"^. c #0D0E0D", +"/. c #7F987F", +"(. c #78ED78", +"_. c #5EFF5E", +":. c #64F864", +"<. c #62E362", +"[. c #63A963", +"}. c #433E43", +"|. c #0C0C0C", +"1. c #0A0A0A", +"2. c #3E393E", +"3. c #5EA65E", +"4. c #68E668", +"5. c #66FB66", +"6. c #66FF66", +"7. c #5ED65E", +"8. c #4C7B4C", +"9. c #302E30", +"0. c #080C08", +"a. c #070C07", +"b. c #3E3A3E", +"c. c #598F59", +"d. c #6AE36A", +"e. c #6BFF6B", +"f. c #74DF74", +"g. c #607460", +"h. c #0D1C0D", +"i. c #030103", +"j. c #1E2C1E", +"k. c #9AAC9A", +"l. c #88F988", +"m. c #74F374", +"n. c #709A70", +"o. c #212021", +"p. c #0E0D0E", +"q. c #5D615D", +"r. c #71E071", +"s. c #61F461", +"t. c #72BB72", +"u. c #555155", +"v. c #020002", +"w. c #3C3B3C", +"x. c #75A975", +"y. c #6AF26A", +"z. c #6EFF6E", +"A. c #74DC74", +"B. c #477147", +"C. c #1D1A1D", +"D. c #1A161A", +"E. c #476E47", +"F. c #5EDF5E", +"G. c #5DBA5D", +"H. c #332C33", +"I. c #060806", +"J. c #384138", +"K. c #8DD18D", +"L. c #75FF75", +"M. c #81E981", +"N. c #7C797C", +"O. c #091009", +"P. c #040104", +"Q. c #010201", +"R. c #050305", +"S. c #433C43", +"T. c #73C273", +"U. c #67FE67", +"V. c #64FF64", +"W. c #5EC85E", +"X. c #3B443B", +"Y. c #0D090D", +"Z. c #0C0F0C", +"`. c #242724", +" + c #363A36", +".+ c #464946", +"++ c #535553", +"@+ c #405E40", +"#+ c #206120", +"$+ c #205F20", +"%+ c #3B5F3B", +"&+ c #545554", +"*+ c #494D49", +"=+ c #424642", +"-+ c #323632", +";+ c #1B1F1B", +">+ c #060306", +",+ c #050205", +"'+ c #342F34", +")+ c #63AB63", +"!+ c #65F765", +"~+ c #82F982", +"{+ c #81A881", +"]+ c #102710", +"^+ c #111311", +"/+ c #474C47", +"(+ c #6C8D6C", +"_+ c #55B055", +":+ c #5ECA5E", +"<+ c #71DB71", +"[+ c #80E980", +"}+ c #8EEF8E", +"|+ c #7AF17A", +"1+ c #5AF15A", +"2+ c #5BF15B", +"3+ c #74F174", +"4+ c #84ED84", +"5+ c #7CE67C", +"6+ c #6ED76E", +"7+ c #50C350", +"8+ c #63AA63", +"9+ c #838F83", +"0+ c #5F655F", +"a+ c #212621", +"b+ c #050105", +"c+ c #619C61", +"d+ c #69F669", +"e+ c #79ED79", +"f+ c #717F71", +"g+ c #0E100E", +"h+ c #000100", +"i+ c #111211", +"j+ c #676767", +"k+ c #92D592", +"l+ c #5CEE5C", +"m+ c #66F666", +"n+ c #61FA61", +"o+ c #64FA64", +"p+ c #5FF15F", +"q+ c #76E876", +"r+ c #94B794", +"s+ c #5C605C", +"t+ c #171A17", +"u+ c #1A141A", +"v+ c #5FA45F", +"w+ c #68FA68", +"x+ c #64DF64", +"y+ c #466146", +"z+ c #0C0B0C", +"A+ c #0A080A", +"B+ c #424942", +"C+ c #85BF85", +"D+ c #7DF17D", +"E+ c #65FC65", +"F+ c #5BF05B", +"G+ c #97E797", +"H+ c #829382", +"I+ c #0E0F0E", +"J+ c #2D282D", +"K+ c #60B160", +"L+ c #5BD75B", +"M+ c #355635", +"N+ c #060706", +"O+ c #232023", +"P+ c #728F72", +"Q+ c #7CEC7C", +"R+ c #62F762", +"S+ c #73E873", +"T+ c #5DA75D", +"U+ c #3F603F", +"V+ c #222022", +"W+ c #2C282C", +"X+ c #6FB26F", +"Y+ c #6CFC6C", +"Z+ c #59D059", +"`+ c #304330", +" @ c #292629", +".@ c #85A885", +"+@ c #80F680", +"@@ c #61F961", +"#@ c #64EF64", +"$@ c #71BC71", +"%@ c #405240", +"&@ c #221E22", +"*@ c #85C085", +"=@ c #58CF58", +"-@ c #2B3B2B", +";@ c #191519", +">@ c #779577", +",@ c #92F892", +"'@ c #63FB63", +")@ c #60ED60", +"!@ c #5EA85E", +"~@ c #494249", +"{@ c #88D788", +"]@ c #6CFF6C", +"^@ c #57D657", +"/@ c #2A4B2A", +"(@ c #060406", +"_@ c #597059", +":@ c #99F599", +"<@ c #62F962", +"[@ c #82D682", +"}@ c #586758", +"|@ c #101110", +"1@ c #3E703E", +"2@ c #62EA62", +"3@ c #5EDA5E", +"4@ c #325032", +"5@ c #040604", +"6@ c #314A31", +"7@ c #6AEF6A", +"8@ c #71A371", +"9@ c #323332", +"0@ c #0D0C0D", +"a@ c #639063", +"b@ c #72F572", +"c@ c #6EE56E", +"d@ c #526152", +"e@ c #282428", +"f@ c #71AE71", +"g@ c #6EF86E", +"h@ c #61D761", +"i@ c #346034", +"j@ c #0B070B", +"k@ c #0D100D", +"l@ c #97B597", +"m@ c #7BFF7B", +"n@ c #78F578", +"o@ c #718771", +"p@ c #070107", +"q@ c #335A33", +"r@ c #61F061", +"s@ c #74EB74", +"t@ c #4D6E4D", +"u@ c #0E090E", +"v@ c #2D312D", +"w@ c #5DD45D", +"x@ c #6BFE6B", +"y@ c #6EAD6E", +"z@ c #1F171F", +"A@ c #151515", +"B@ c #559155", +"C@ c #83EF83", +"D@ c #698769", +"E@ c #1B191B", +"F@ c #627C62", +"G@ c #6FEF6F", +"H@ c #5CCF5C", +"I@ c #253025", +"J@ c #263826", +"K@ c #62C962", +"L@ c #7CF37C", +"M@ c #7DA57D", +"N@ c #2E2A2E", +"O@ c #2D232D", +"P@ c #64BE64", +"Q@ c #64FE64", +"R@ c #6EE76E", +"S@ c #5E5C5E", +"T@ c #4A604A", +"U@ c #8EF98E", +"V@ c #5CFF5C", +"W@ c #81F881", +"X@ c #82AE82", +"Y@ c #2A2A2A", +"Z@ c #5A545A", +"`@ c #6AE66A", +" # c #4EB04E", +".# c #408440", +"+# c #69FF69", +"@# c #66F866", +"## c #5BA35B", +"$# c #232123", +"%# c #0D080D", +"&# c #50B150", +"*# c #6AFF6A", +"=# c #73CE73", +"-# c #2B2A2B", +";# c #2D2C2D", +"># c #7DC27D", +",# c #5AFF5A", +"'# c #8EF68E", +")# c #8AAA8A", +"!# c #2A282A", +"~# c #393639", +"{# c #61D861", +"]# c #66EB66", +"^# c #4D704D", +"/# c #4A4C4A", +"(# c #B1F8B1", +"_# c #59FF59", +":# c #82AA82", +"<# c #2A272A", +"[# c #080308", +"}# c #5B8C5B", +"|# c #6BF66B", +"1# c #68FD68", +"2# c #69B669", +"3# c #231D23", +"4# c #040004", +"5# c #346734", +"6# c #6DFF6D", +"7# c #85F885", +"8# c #719571", +"9# c #1C171C", +"0# c #262826", +"a# c #78D278", +"b# c #6EE86E", +"c# c #606560", +"d# c #1B141B", +"e# c #5B945B", +"f# c #92F392", +"g# c #5F7A5F", +"h# c #0D0A0D", +"i# c #070207", +"j# c #628C62", +"k# c #6BF26B", +"l# c #5AC65A", +"m# c #1D111D", +"n# c #342B34", +"o# c #8ABE8A", +"p# c #7AED7A", +"q# c #496B49", +"r# c #080908", +"s# c #4E474E", +"t# c #6ED96E", +"u# c #69EB69", +"v# c #5B6A5B", +"w# c #413F41", +"x# c #A4E6A4", +"y# c #61E161", +"z# c #305030", +"A# c #050005", +"B# c #130913", +"C# c #54B654", +"D# c #57C257", +"E# c #130D13", +"F# c #255425", +"G# c #6BFC6B", +"H# c #84BC84", +"I# c #322C32", +"J# c #6D6D6D", +"K# c #6EED6E", +"L# c #72EC72", +"M# c #626C62", +"N# c #326732", +"O# c #7EF97E", +"P# c #608D60", +"Q# c #111111", +"R# c #1F131F", +"S# c #7BCF7B", +"T# c #75C775", +"U# c #1C161C", +"V# c #0F090F", +"W# c #467946", +"X# c #6EF06E", +"Y# c #375937", +"Z# c #030003", +"`# c #8C898C", +" $ c #74F474", +".$ c #64F064", +"+$ c #4F814F", +"@$ c #181218", +"#$ c #588A58", +"$$ c #86CD86", +"%$ c #373537", +"&$ c #2B222B", +"*$ c #63D563", +"=$ c #59DD59", +"-$ c #254925", +";$ c #211A21", +">$ c #699C69", +",$ c #69FC69", +"'$ c #5F925F", +")$ c #1C141C", +"!$ c #8BAF8B", +"~$ c #75FD75", +"{$ c #5EBF5E", +"]$ c #282328", +"^$ c #282128", +"/$ c #77AA77", +"($ c #8FE98F", +"_$ c #495649", +":$ c #577357", +"<$ c #64EE64", +"[$ c #499E49", +"}$ c #090509", +"|$ c #2D262D", +"1$ c #81B481", +"2$ c #5AA95A", +"3$ c #192219", +"4$ c #1F3D1F", +"5$ c #5ADD5A", +"6$ c #69E769", +"7$ c #5E5E5E", +"8$ c #322B32", +"9$ c #8CBD8C", +"0$ c #80F080", +"a$ c #415741", +"b$ c #201D20", +"c$ c #6CC06C", +"d$ c #5DD05D", +"e$ c #2B1B2B", +"f$ c #353035", +"g$ c #92C792", +"h$ c #68FF68", +"i$ c #5BA05B", +"j$ c #161816", +"k$ c #0F060F", +"l$ c #529852", +"m$ c #62F662", +"n$ c #6EFC6E", +"o$ c #6AA46A", +"p$ c #293329", +"q$ c #79CF79", +"r$ c #7FF17F", +"s$ c #3E563E", +"t$ c #4F6E4F", +"u$ c #67EA67", +"v$ c #6BE56B", +"w$ c #605A60", +"x$ c #163716", +"y$ c #54D754", +"z$ c #65FF65", +"A$ c #76B876", +"B$ c #272627", +"C$ c #534B53", +"D$ c #6ADC6A", +"E$ c #57D157", +"F$ c #251625", +"G$ c #133713", +"H$ c #4FD54F", +"I$ c #68F768", +"J$ c #3A653A", +"K$ c #080208", +"L$ c #332733", +"M$ c #59CE59", +"N$ c #5FBF5F", +"O$ c #143614", +"P$ c #50D450", +"Q$ c #5FA85F", +"R$ c #1C1F1C", +"S$ c #0D060D", +"T$ c #51C151", +"U$ c #75F875", +"V$ c #809680", +"W$ c #61DF61", +"X$ c #2C492C", +"Y$ c #76A276", +"Z$ c #6EFB6E", +"`$ c #67E967", +" % c #576457", +".% c #72FC72", +"+% c #4F794F", +"@% c #0F0C0F", +"#% c #7B737B", +"$% c #70EE70", +"%% c #57DA57", +"&% c #233523", +"*% c #53A853", +"=% c #162016", +"-% c #4D404D", +";% c #64E064", +">% c #60CD60", +",% c #101810", +"'% c #81E681", +")% c #334433", +"!% c #201320", +"~% c #51D451", +"{% c #6BFB6B", +"]% c #70B070", +"^% c #151015", +"/% c #7CFE7C", +"(% c #467246", +"_% c #080608", +":% c #5CCC5C", +"<% c #65F565", +"[% c #5C965C", +"}% c #0F080F", +"|% c #75AF75", +"1% c #252125", +"2% c #A7C0A7", +"3% c #60F060", +"4% c #468246", +"5% c #080108", +"6% c #99F099", +"7% c #394239", +"8% c #A7A5A7", +"9% c #7CFB7C", +"0% c #5AEC5A", +"a% c #317231", +"b% c #6FFF6F", +"c% c #3A693A", +"d% c #848784", +"e% c #72F472", +"f% c #5EEA5E", +"g% c #306830", +"h% c #70A270", +"i% c #241B24", +"j% c #676A67", +"k% c #75E075", +"l% c #535453", +"m% c #5BFF5B", +"n% c #9ADE9A", +"o% c #393A39", +"p% c #4B4E4B", +"q% c #62E462", +"r% c #72D572", +"s% c #4F414F", +"t% c #6DFC6D", +"u% c #355E35", +"v% c #060106", +"w% c #3B3D3B", +"x% c #64CA64", +"y% c #393039", +"z% c #4E7F4E", +"A% c #140E14", +"B% c #323432", +"C% c #5BDD5B", +"D% c #5BC05B", +"E% c #2A202A", +"F% c #67FF67", +"G% c #759D75", +"H% c #231B23", +"I% c #282B28", +"J% c #59DA59", +"K% c #61FE61", +"L% c #55BC55", +"M% c #221822", +"N% c #80B880", +"O% c #282728", +"P% c #1F221F", +"Q% c #56D856", +"R% c #52B852", +"S% c #1D131D", +"T% c #5BCD5B", +"U% c #1F371F", +"V% c #54D554", +"W% c #60FE60", +"X% c #4FB54F", +"Y% c #170E17", +"Z% c #62E062", +"`% c #304D30", +" & c #0B0E0B", +".& c #51D351", +"+& c #4CB14C", +"@& c #120812", +"#& c #7DF57D", +"$& c #4C654C", +"%& c #0A060A", +"&& c #040704", +"*& c #4FD04F", +"=& c #48AE48", +"-& c #0C020C", +";& c #8CFF8C", +">& c #5C785C", +",& c #0E0A0E", +"'& c #50D250", +")& c #45AB45", +"!& c #070007", +"~& c #7FFF7F", +"{& c #508050", +"]& c #0B0C0B", +"^& c #131613", +"/& c #53D553", +"(& c #41A741", +"_& c #3F8D3F", +":& c #0A120A", +"<& c #1E211E", +"[& c #3FA43F", +"}& c #4EA14E", +"|& c #131C13", +"1& c #3DA33D", +"2& c #65B765", +"3& c #1E261E", +"4& c #333633", +"5& c #5CDD5C", +"6& c #7ACC7A", +"7& c #283028", +"8& c #5FE05F", +"9& c #8FE18F", +"0& c #323A32", +"a& c #474A47", +"b& c #9FF09F", +"c& c #3B433B", +"d& c #585B58", +"e& c #66E766", +"f& c #A7F8A7", +"g& c #3F463F", +"h& c #747874", +"i& c #6DEF6D", +"j& c #ADFDAD", +"k& c #A19AA1", +"l& c #7AF97A", +"m& c #58FF58", +"n& c #B5FFB5", +"o& c #464D46", +"p& c #A7B9A7", +"q& c #7BFE7B", +"r& c #B9FFB9", +"s& c #485148", +"t& c #63CA63", +"u& c #9CFF9C", +"v& c #3A533A", +"w& c #4ED34E", +"x& c #235423", +"y& c #3D313D", +"z& c #5FDB5F", +"A& c #1C531C", +"B& c #635163", +"C& c #69E469", +"D& c #205320", +"E& c #748574", +"F& c #6EF36E", +"G& c #8BFF8B", +"H& c #315331", +"I& c #57BC57", +"J& c #65FD65", +"K& c #465146", +"L& c #201420", +"M& c #51CC51", +"N& c #474E47", +"O& c #493B49", +"P& c #66D566", +"Q& c #AEFEAE", +"R& c #424B42", +"S& c #535E53", +"T& c #6AE46A", +"U& c #A4F6A4", +"V& c #3D453D", +"W& c #3E813E", +"X& c #93E593", +"Y& c #353D35", +"Z& c #140914", +"`& c #53A053", +" * c #61F861", +".* c #7FD17F", +"+* c #2B332B", +"@* c #1F1F1F", +"#* c #6CC26C", +"$* c #68FE68", +"%* c #6CBD6C", +"&* c #222A22", +"** c #294329", +"=* c #60DE60", +"-* c #5AAB5A", +";* c #192019", +">* c #688168", +",* c #69F369", +"'* c #429642", +")* c #0E160E", +"!* c #92BD92", +"~* c #77FE77", +"{* c #3D833D", +"]* c #3A2D3A", +"^* c #81FC81", +"/* c #4F724F", +"(* c #7D827D", +"_* c #6CF36C", +":* c #78EE78", +"<* c #465E46", +"[* c #170917", +"}* c #7AC37A", +"|* c #2B472B", +"1* c #475147", +"2* c #65E765", +"3* c #54C954", +"4* c #1B341B", +"5* c #100710", +"6* c #57AB57", +"7* c #62FB62", +"8* c #4DD64D", +"9* c #5DAF5D", +"0* c #343334", +"a* c #5FD45F", +"b* c #193819", +"c* c #5AD75A", +"d* c #578857", +"e* c #161216", +"f* c #507150", +"g* c #68EA68", +"h* c #2C342C", +"i* c #7FD07F", +"j* c #366036", +"k* c #070407", +"l* c #61AC61", +"m* c #67FB67", +"n* c #373037", +"o* c #96C996", +"p* c #73EA73", +"q* c #264126", +"r* c #3A403A", +"s* c #67DC67", +"t* c #342C34", +"u* c #8FC18F", +"v* c #6FB36F", +"w* c #232323", +"x* c #0C000C", +"y* c #789578", +"z* c #6DF86D", +"A* c #2C252C", +"B* c #7EB17E", +"C* c #76FF76", +"D* c #4B704B", +"E* c #0D070D", +"F* c #394739", +"G* c #76DF76", +"H* c #221C22", +"I* c #6C9F6C", +"J* c #92E292", +"K* c #353C35", +"L* c #110C11", +"M* c #57B657", +"N* c #191219", +"O* c #598B59", +"P* c #679867", +"Q* c #415641", +"R* c #5FEB5F", +"S* c #3E763E", +"T* c #7FF97F", +"U* c #395C39", +"V* c #161616", +"W* c #59B159", +"X* c #335D33", +"Y* c #7ACF7A", +"Z* c #293529", +"`* c #375537", +" = c #5EE35E", +".= c #3E423E", +"+= c #9EEA9E", +"@= c #77FF77", +"#= c #628F62", +"$= c #171517", +"%= c #171017", +"&= c #62A562", +"*= c #67FA67", +"== c #332833", +"-= c #87BA87", +";= c #56FF56", +">= c #3B543B", +",= c #070307", +"'= c #0A000A", +")= c #576557", +"!= c #71E871", +"~= c #598759", +"{= c #78FF78", +"]= c #5BAC5B", +"^= c #1B211B", +"/= c #303D30", +"(= c #74D174", +"_= c #4D584D", +":= c #ADFCAD", +"<= c #59FE59", +"[= c #6CF76C", +"}= c #3E653E", +"|= c #090409", +"1= c #57AC57", +"2= c #343134", +"3= c #8ED28E", +"4= c #69B269", +"5= c #1F231F", +"6= c #556355", +"7= c #6AEC6A", +"8= c #4F8F4F", +"9= c #73E373", +"0= c #364B36", +"a= c #222822", +"b= c #65C465", +"c= c #67FD67", +"d= c #375B37", +"e= c #84FD84", +"f= c #618961", +"g= c #110A11", +"h= c #68F668", +"i= c #253225", +"j= c #74D074", +"k= c #2F392F", +"l= c #0B040B", +"m= c #485C48", +"n= c #70E170", +"o= c #131213", +"p= c #5B8A5B", +"q= c #76FD76", +"r= c #81F381", +"s= c #577657", +"t= c #4C484C", +"u= c #6ED16E", +"v= c #404740", +"w= c #7DDC7D", +"x= c #73A973", +"y= c #2A242A", +"z= c #313131", +"A= c #84BB84", +"B= c #141014", +"C= c #608F60", +"D= c #72FF72", +"E= c #5DFE5D", +"F= c #73FF73", +"G= c #7FCA7F", +"H= c #353A35", +"I= c #151315", +"J= c #609660", +"K= c #73F873", +"L= c #373937", +"M= c #83D283", +"N= c #8BE58B", +"O= c #4F574F", +"P= c #0E050E", +"Q= c #456B45", +"R= c #66E666", +"S= c #466346", +"T= c #6BEA6B", +"U= c #60EE60", +"V= c #4B7D4B", +"W= c #0D0B0D", +"X= c #110911", +"Y= c #515251", +"Z= c #69D569", +"`= c #0D110D", +" - c #619361", +".- c #82FC82", +"+- c #4E934E", +"@- c #0E180E", +"#- c #0A040A", +"$- c #4E544E", +"%- c #83D083", +"&- c #343034", +"*- c #80C180", +"=- c #69FA69", +"-- c #65A965", +";- c #252625", +">- c #414241", +",- c #79C879", +"'- c #70FF70", +")- c #090309", +"!- c #365136", +"~- c #5CD75C", +"{- c #66F566", +"]- c #67AB67", +"^- c #2C2D2C", +"/- c #74B674", +"(- c #70FE70", +"_- c #040A04", +":- c #345D34", +"<- c #5ED05E", +"[- c #599F59", +"}- c #2B2C2B", +"|- c #060006", +"1- c #2C312C", +"2- c #69AC69", +"3- c #70FA70", +"4- c #0B080B", +"5- c #2F522F", +"6- c #61C761", +"7- c #71FF71", +"8- c #6FED6F", +"9- c #4F974F", +"0- c #2C302C", +"a- c #5EAC5E", +"b- c #6CFA6C", +"c- c #3E4A3E", +"d- c #86C686", +"e- c #71FC71", +"f- c #9BDF9B", +"g- c #658265", +"h- c #151D15", +"i- c #5EA75E", +"j- c #67F967", +"k- c #090109", +"l- c #434243", +"m- c #71AD71", +"n- c #68E768", +"o- c #6FCA6F", +"p- c #566356", +"q- c #1B0F1B", +"r- c #303130", +"s- c #68A768", +"t- c #282928", +"u- c #517951", +"v- c #71CE71", +"w- c #6EF96E", +"x- c #7FDB7F", +"y- c #5D9B5D", +"z- c #304430", +"A- c #0E070E", +"B- c #444944", +"C- c #72B772", +"D- c #70F970", +"E- c #130F13", +"F- c #3A423A", +"G- c #58A058", +"H- c #61E061", +"I- c #73EF73", +"J- c #6FB76F", +"K- c #465946", +"L- c #1A1C1A", +"M- c #0C030C", +"N- c #7AC87A", +"O- c #151C15", +"P- c #446244", +"Q- c #6EBC6E", +"R- c #5CE35C", +"S- c #62F862", +"T- c #70FB70", +"U- c #6CE66C", +"V- c #59CC59", +"W- c #4E864E", +"X- c #2C2C2C", +"Y- c #3D4E3D", +"Z- c #80CB80", +"`- c #74FF74", +" ; c #181A18", +".; c #3B493B", +"+; c #151F15", +"@; c #272E27", +"#; c #396C39", +"$; c #49A249", +"%; c #64C864", +"&; c #68DF68", +"*; c #64F164", +"=; c #57FF57", +"-; c #5BE45B", +";; c #5DD65D", +">; c #6FAC6F", +",; c #597359", +"'; c #233923", +"); c #0A020A", +"!; c #497649", +"~; c #63D363", +"{; c #213521", +"]; c #62B862", +"^; c #4D9A4D", +"/; c #303430", +"(; c #142114", +"_; c #2F3E2F", +":; c #396339", +"<; c #4F904F", +"[; c #80BA80", +"}; c #75CD75", +"|; c #59DB59", +"1; c #69E969", +"2; c #84FF84", +"3; c #80FF80", +"4; c #7EFF7E", +"5; c #78FB78", +"6; c #6EEF6E", +"7; c #5FDE5F", +"8; c #5ED15E", +"9; c #76C776", +"0; c #639B63", +"a; c #316E31", +"b; c #2E4F2E", +"c; c #272827", +"d; c #130B13", +"e; c #394539", +"f; c #69A769", +"g; c #6BE86B", +"h; c #173917", +"i; c #56DC56", +"j; c #6BB76B", +"k; c #494949", +"l; c #100910", +"m; c #141814", +"n; c #263926", +"o; c #345834", +"p; c #5A7A5A", +"q; c #769676", +"r; c #90B190", +"s; c #ABC2AB", +"t; c #80C680", +"u; c #4AC84A", +"v; c #4CC84C", +"w; c #74C774", +"x; c #A0C4A0", +"y; c #99B899", +"z; c #86A786", +"A; c #678867", +"B; c #3F613F", +"C; c #234023", +"D; c #232E23", +"E; c #1B1C1B", +"F; c #171117", +"G; c #3C533C", +"H; c #60C760", +"I; c #6AFD6A", +"J; c #4ED44E", +"K; c #84CD84", +"L; c #4E644E", +"M; c #1C221C", +"N; c #150D15", +"O; c #322732", +"P; c #222D22", +"Q; c #0F300F", +"R; c #103010", +"S; c #1E2E1E", +"T; c #2E282E", +"U; c #2C242C", +"V; c #251D25", +"W; c #1A121A", +"X; c #0C050C", +"Y; c #262926", +"Z; c #647964", +"`; c #71D971", +" > c #74E474", +".> c #60A460", +"+> c #294F29", +"@> c #1B171B", +"#> c #0D020D", +"$> c #406140", +"%> c #7CB37C", +"&> c #81EF81", +"*> c #64D764", +"=> c #5F885F", +"-> c #2E372E", +";> c #180C18", +">> c #415241", +",> c #5BAA5B", +"'> c #66E266", +")> c #67F467", +"!> c #70CB70", +"~> c #5F6F5F", +"{> c #192819", +"]> c #0C070C", +"^> c #2F312F", +"/> c #4C8D4C", +"(> c #63DE63", +"_> c #71EE71", +":> c #5CB35C", +"<> c #415C41", +"[> c #121512", +"}> c #1C1E1C", +"|> c #213F21", +"1> c #4E7C4E", +"2> c #87C887", +"3> c #78F878", +"4> c #6CE26C", +"5> c #63B663", +"6> c #4A814A", +"7> c #262126", +"8> c #090009", +"9> c #241924", +"0> c #252D25", +"a> c #415B41", +"b> c #5D985D", +"c> c #5AD15A", +"d> c #65F165", +"e> c #63EF63", +"f> c #7AD37A", +"g> c #81A181", +"h> c #4D644D", +"i> c #273327", +"j> c #261B26", +"k> c #1E141E", +"l> c #344E34", +"m> c #7A8D7A", +"n> c #6FBF6F", +"o> c #6BF76B", +"p> c #74FC74", +"q> c #66E966", +"r> c #82CF82", +"s> c #7F947F", +"t> c #2D4C2D", +"u> c #1E321E", +"v> c #242424", +"w> c #0E130E", +"x> c #070707", +"y> c #0F140F", +"z> c #242F24", +"A> c #2B432B", +"B> c #6A806A", +"C> c #6CC36C", +"D> c #5AE35A", +"E> c #72F672", +"F> c #58E258", +"G> c #6CCD6C", +"H> c #7AAB7A", +"I> c #417F41", +"J> c #3A603A", +"K> c #4A524A", +"L> c #384338", +"M> c #1D291D", +"N> c #162316", +"O> c #122112", +"P> c #0D1E0D", +"Q> c #0B1D0B", +"R> c #0C1D0C", +"S> c #102010", +"T> c #172317", +"U> c #1C291C", +"V> c #293429", +"W> c #374237", +"X> c #405140", +"Y> c #386438", +"Z> c #458145", +"`> c #6CA26C", +" , c #7CC67C", +"., c #69DE69", +"+, c #5EF15E", +"@, c #70E770", +"#, c #86DF86", +"$, c #70CE70", +"%, c #60BE60", +"&, c #52B052", +"*, c #49A749", +"=, c #44A244", +"-, c #3F9C3F", +";, c #3B983B", +">, c #3D9A3D", +",, c #43A143", +"', c #4BA84B", +"), c #51B051", +"!, c #58B658", +"~, c #5FBD5F", +"{, c #6FCD6F", +"], c #7ADF7A", +"^, c #68E968", +"/, c #60F260", +"(, c #6DFB6D", +"_, c #63FD63", +":, c #60FB60", +"<, c #5FFA5F", +"[, c #5EF95E", +"}, c #5FF95F", +"|, c #62FC62", +"1, c #153715", +"2, c #163816", +"3, c #51D551", +"4, c #51D651", +"5, c #193B19", +"6, c #52D752", +"7, c #1A3C1A", +"8, c #53D753", +"9, c #5EFD5E", +"0, c #3CA53C", +"a, c #1C3D1C", +"b, c #53D853", +"c, c #42A842", +"d, c #1E3E1E", +"e, c #55D955", +"f, c #6DFA6D", +"g, c #6C9E6C", +"h, c #204120", +"i, c #57DB57", +"j, c #7BF87B", +"k, c #9B949B", +"l, c #234523", +"m, c #7DF77D", +"n, c #9D8F9D", +"o, c #274927", +"p, c #5BDF5B", +"q, c #79F479", +"r, c #948994", +"s, c #2B4D2B", +"t, c #5DE25D", +"u, c #77F177", +"v, c #8D818D", +"w, c #2F512F", +"x, c #60E460", +"y, c #75EF75", +"z, c #857A85", +"A, c #060206", +"B, c #325432", +"C, c #62E662", +"D, c #7D717D", +"E, c #375837", +"F, c #63E863", +"G, c #70EA70", +"H, c #766A76", +"I, c #3B5D3B", +"J, c #6DE86D", +"K, c #6E626E", +"L, c #0A070A", +"M, c #416341", +"N, c #665B66", +"O, c #486A48", +"P, c #68E368", +"Q, c #5C505C", +"R, c #0F0B0F", +"S, c #4F714F", +"T, c #73F773", +"U, c #64DE64", +"V, c #4E434E", +"W, c #110D11", +"X, c #567756", +"Y, c #76FA76", +"Z, c #60DA60", +"`, c #413541", +" ' c #120E12", +".' c #5C7E5C", +"+' c #7AFE7A", +"@' c #5BD65B", +"#' c #151115", +"$' c #658565", +"%' c #171317", +"&' c #698E69", +"*' c #81FF81", +"=' c #53CD53", +"-' c #170B17", +";' c #0D140D", +">' c #479347", +",' c #4DC94D", +"'' c #091609", +")' c #3A983A", +"!' c #4EC54E", +"~' c #101E10", +"{' c #44A344", +"]' c #72FE72", +"^' c #7EB97E", +"/' c #182518", +"(' c #52AF52", +"_' c #7CFA7C", +":' c #9F9A9F", +"<' c #1F2D1F", +"[' c #5EBC5E", +"}' c #75F275", +"|' c #8A828A", +"1' c #273527", +"2' c #6AC96A", +"3' c #6DEA6D", +"4' c #6F6A6F", +"5' c #303E30", +"6' c #79D779", +"7' c #67E467", +"8' c #575257", +"9' c #3B483B", +"0' c #8BE98B", +"a' c #5FDC5F", +"b' c #3F3A3F", +"c' c #465346", +"d' c #9EF99E", +"e' c #54D254", +"f' c #1E181E", +"g' c #A3FFA3", +"h' c #50CA50", +"i' c #2A642A", +"j' c #81C181", +"k' c #387638", +"l' c #73FC73", +"m' c #86A486", +"n' c #151215", +"o' c #518E51", +"p' c #6CF46C", +"q' c #6B886B", +"r' c #242124", +"s' c #63EB63", +"t' c #4E6C4E", +"u' c #323032", +"v' c #8CC98C", +"w' c #2D4A2D", +"x' c #433F43", +"y' c #ADE8AD", +"z' c #56D956", +"A' c #142F14", +"B' c #4D4D4D", +"C' c #C1FFC1", +"D' c #80CA80", +"E' c #2B272B", +"F' c #2B5D2B", +"G' c #68B168", +"H' c #1E151E", +"I' c #437843", +"J' c #61F661", +"K' c #4D994D", +"L' c #1F181F", +"M' c #669966", +"N' c #3E803E", +"O' c #2F292F", +"P' c #88BB88", +"Q' c #75E775", +"R' c #6C656C", +"S' c #3D383D", +"T' c #A3DCA3", +"U' c #63D463", +"V' c #443844", +"W' c #294929", +"X' c #77F977", +"Y' c #52C452", +"Z' c #1B121B", +"`' c #366336", +" ) c #140F14", +".) c #538053", +"+) c #7E767E", +"@) c #221D22", +"#) c #74A174", +"$) c #5BD95B", +"%) c #342834", +"&) c #58BB58", +"*) c #4FC64F", +"=) c #1F3A1F", +"-) c #57D057", +";) c #70EF70", +">) c #7C787C", +",) c #030803", +"') c #030903", +")) c #385438", +"!) c #6BE46B", +"~) c #61F161", +"{) c #55A555", +"]) c #2D7E2D", +"^) c #318231", +"/) c #308230", +"() c #358435", +"_) c #53B053", +":) c #6CF96C", +" . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # $ % & * % = = - * = % % ; $ @ @ > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > + , % ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > > 9 0 a b c d e f g h i j k l m n o p q r s t l u v w x y z A B C D E F > + > G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > H I J K L M N O P Q q p p p p p p p p p p p p p p p p p p p p r R S T U V W X Y Z > + G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > 9 > ` ...+.@.#.t q p p p p p p p p p p p p p p p p p p p p p p p p p p p p r $.%.&.*.=.-.;.>.> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.'.).!.g ~.{.r p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q s ].^.z /.(._.> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . :.<.[.}.|.s p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p r 1.2.3.4.5.> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > 6.7.8.9.0.Q p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q a.b.c.d.e.> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > . f.g.h.v i.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q 1.j.k.l.,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m.n.o.v p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p o p.q.r.. > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > s.t.u.O v.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p j w.x.y._.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G z.A.B.C.$.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q D.E.F.@ > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + 6.G.H.I.q p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q I.J.K.L._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.M.N.O.P.p p p p p p p p p p p p q q r i.n o Q.Q.r r v.q p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p R.S.T.U.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G + V.W.X.Y.p p p p p p p p p p p i.l Z.`. +.+++@+#+$+%+&+*+=+-+;+O >+,+p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p R.'+)+!+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G ~+{+]+t p p p p p p p p p p i.^+/+(+_+:+<+[+}+|+1+2+3+}+4+5+6+7+8+9+0+a+k b+p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q D.c+d+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G e+f+g+h+p p p p p p p p p p i+j+k+l+m+n+$ + @ @ + > > + @ @ + # % o+d+p+q+r+s+t+R p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q u+v+w+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > x+y+z+p p p p p p p p p p A+B+C+D+@ . . . . . G G G . . . G G G . . . . . + E+F+G+H+[ I+m p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q J+K+5.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > L+M+N+p p p p p p p p p p O+P+Q+8 > G . . . . . . . . . . . . . . . . . . . G G G 6.R+S+T+U+V+p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q W+X+Y+G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > Z+`+].p p p p p p p p p p @.@+@. G G . . . . . . . . . . . . . . . . . . . . . . . G G @ @@#@$@%@@.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p P.&@*@L.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > =@-@l p p p p p p p p p p ;@>@,@,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > '@)@!@J+q p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p v.~@{@]@_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > ^@/@t p p p p p p p p p p (@_@:@,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > <@[@}@|@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p $.1@2@. G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > 3@4@5@p p p p p p p p p p p 6@S+@ >.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ 7@8@9@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p 0@a@b@+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G > c@d@].p p p p p p p p p p p e@f@. _.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G G g@h@i@j@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q k@l@m@,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G n@o@i p p p p p p p p p p p p@q@r@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G s@t@u@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p v@w@+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G x@y@z@p p p p p p p p p p p p A@B@e.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C@D@E@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p n F@G@> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V.H@I@q p p p p p p p p p p p q J@K@+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H + L@M@N@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p O@P@Q@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G R@S@n p p p p p p p p p p p p i.T@U@V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G G W@X@Y@p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q Z@`@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > 6. #u@p p p p p p p p p p p p p O .#+#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G + @###$#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p %#&#@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G *#=#-#p p p p p p p p p p p p p p ;#>#V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G ,#'#)#!#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p ~#{#> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]#^#b+p p p p p p p p p p p p p p /#(#_#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H @ W@:#<#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p [#}#|#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 1#2#3#p p p p p p p p p p p p p p 4#5#6#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.G 7#8#9#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p 0#a#*#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G b#c#Q p p p p p p p p p p p p p p d#e#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G G f#g#h#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p i#j#k#> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V.l#m#p p p p p p p p p p p p p p p n#o#,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . >.V.p#q#r#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p s#t#@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G u#v#q p p p p p p p p p p p p p p p w#x#,#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.@ y#z#A#p p p p p p p p p p p p p p p p p p p p p p p p p p p p B#C## . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G @ D#E#p p p p p p p p p p p p p p p p F#G#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.]@H#I#p p p p p p p p p p p p p p p p p p p p p p p p p p p p p J#K#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > L#M#p p p p p p p p p p p p p p p p p@N#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O#P#Q#p p p p p p p p p p p p p p p p p p p p p p p p p p p p R#S#]@G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 6#T#U#p p p p p p p p p p p p p p p p V#W#@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G > X#Y#Z#p p p p p p p p p p p p p p p p p p p p p p p p p p p p `# $_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .$+$v.p p p p p p p p p p p p p p p p @$#$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G _.$$%$p p p p p p p p p p p p p p p p p p p p p p p p p p p p &$*$@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + =$-$p p p p p p p p p p p p p p p p p ;$>$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H ,$'$)$p p p p p p p p p p p p p p p p p p p p p p p p p p p o !$~$_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 {$]$p p p p p p p p p p p p p p p p p ^$/$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#($_$n p p p p p p p p p p p p p p p p p p p p p p p p p p p :$<$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . n+[$}$p p p p p p p p p p p p p p p p p |$1$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G e.2$3$p p p p p p p p p p p p p p p p p p p p p p p p p p p 4$5$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 6$7$p p p p p p p p p p p p p p p p p p 8$9$+ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@0$a$Z#p p p p p p p p p p p p p p p p p p p p p p p p p p b$c$U.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + d$e$p p p p p p p p p p p p p p p p p p f$g$> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G h$i$j$p p p p p p p p p p p p p p p p p p p p p p p p p p k$l$m$. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G n$o$P.p p p p p p p p p p p p p p p p p p p$q$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@r$s$v.p p p p p p p p p p p p p p p p p p p p p p p p p q t$u$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G v$w$p p p p p p p p p p p p p p p p p p p x$y$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G z$A$B$p p p p p p p p p p p p p p p p p p p p p p p p p p C$D$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > E$F$p p p p p p p p p p p p p p p p p p p G$H$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.I$J$K$p p p p p p p p p p p p p p p p p p p p p p p p p L$M$. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G *#N$i.p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > Q$R$p p p p p p p p p p p p p p p p p p p p p p p p p S$T$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.U$V$p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > W$X$A#p p p p p p p p p p p p p p p p p p p p p p p p p Y$Z$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G `$ %p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _..%+%@%p p p p p p p p p p p p p p p p p p p p p p p p p #%$%G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > %%&%p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 6.*%=%p p p p p p p p p p p p p p p p p p p p p p p p p -%;%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 6.>%,%p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@'%)%p p p p p p p p p p p p p p p p p p p p p p p p p !%~%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G {%]%^%p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _./%(%_%p p p p p p p p p p p p p p p p p p p p p p p p P.:%6.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <%[%}%p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |%1%p p p p p p p p p p p p p p p p p p p p p p p p p 2%m@,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3%4%5%p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#6%7%p p p p p p p p p p p p p p p p p p p p p p p p p 8%9%_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > 0%a%q p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H b%c%[#p p p p p p p p p p p p p p p p p p p p p p p p d%e%G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + f%g%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@h%i%p p p p p p p p p p p p p p p p p p p p p p p p j%u#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G V.k%l%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m%n%o%p p p p p p p p p p p p p p p p p p p p p p p p p%q%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V.r%s%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G t%u%v%p p p p p p p p p p p p p p p p p p p p p p p w%F.> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + x%y%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > . z%A%p p p p p p p p p p p p p p p p p p p p p p p B%C%> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > D%E%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G F%G%H%p p p p p p p p p p p p p p p p p p p p p p p I%J%> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K%L%M%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G +#N%O%p p p p p p p p p p p p p p p p p p p p p p p P%Q%> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K%R%S%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ T%U%q p p p p p p p p p p p p p p p p p p p p p p j$V%+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W%X%Y%p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G Z%`%,+p p p p p p p p p p p p p p p p p p p p p p &.&+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; +&@&p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.#&$&%&p p p p p p p p p p p p p p p p p p p p p p &&*&+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; =&-&p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@;&>&,&p p p p p p p p p p p p p p p p p p p p p p @.'&+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; )&!&p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.~&{&]&p p p p p p p p p p p p p p p p p p p p p p ^&/&> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * (&q p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G h$_&:&p p p p p p p p p p p p p p p p p p p p p p <&Q%> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * [&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > }&|&p p p p p p p p p p p p p p p p p p p p p p I%J%> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2&3&p p p p p p p p p p p p p p p p p p p p p p 4&5&> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.6&7&p p p p p p p p p p p p p p p p p p p p p p e 8&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@9&0&p p p p p p p p p p p p p p p p p p p p p p a&<.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#b&c&p p p p p p p p p p p p p p p p p p p p p p d&e&G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#f&g&p p p p p p p p p p p p p p p p p p p p p p h&i&_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _#j&B+p p p p p p p p p p p p p p p p p p p p p p k&l&,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&n&o&p p p p p p p p p p p p p p p p p p p p p p p&q&,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&r&s&p p p p p p p p p p p p p p p p p p p p p A#t&h$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m%u&v&p p p p p p p p p p p p p p p p p p p p p m#w&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H b%x&p p p p p p p p p p p p p p p p p p p p p y&z&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + A&p p p p p p p p p p p p p p p p p p p p p B&C&G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +#D&p p p p p p p p p p p p p p p p p p p p p E&F&G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@G&H&p p p p p p p p p p p p p p p p p p p p A#I&J&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&n&K&p p p p p p p p p p p p p p p p p p p p L&M&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&r&N&p p p p p p p p p p p p p p p p p p p p O&P&> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _#Q&R&p p p p p p p p p p p p p p p p p p p p S&T&> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#U&V&p p p p p p p p p p p p p p p p p p p Z#W&3%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@X&Y&p p p p p p p p p p p p p p p p p p p Z&`& *. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _..*+*p p p p p p p p p p p p p p p p p p p @*#*$*G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G %*&*p p p p p p p p p p p p p p p p p p p **=*@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > -*;*p p p p p p p p p p p p p p p p p p p >*,*_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > '*)*p p p p p p p p p p p p p p p p p p v.!*~*_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 6#{*T p p p p p p p p p p p p p p p p p p ]*A.6.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.^*/*S p p p p p p p p p p p p p p p p p p (*_*V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.:*<*}$p p p p p p p p p p p p p p p p p [*}*z.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z&|*P.p p p p p p p p p p p p p p p p p 1*2*> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ 3*4*q p p p p p p p p p p p p p p p p 5*6*7*G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p G$8*+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.9*3$p p p p p p p p p p p p p p p p p 0*a*> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p b*c*+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V.d*e*p p p p p p p p p p p p p p p p 4#f*g*> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p h*i*> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # j*k*p p p p p p p p p p p p p p p p 0@l*m*G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p n*o*> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G p*q*p p p p p p p p p p p p p p p p p r*s*@ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p t*u*> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W%,#v*w*p p p p p p p p p p p p p p p p x*y*z*_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p A*B*+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . >.C*D*E*p p p p p p p p p p p p p p p p F*G*h$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p H*I*+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _#J*K*p p p p p p p p p p p p p p p p L*M*& _.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p N*O*+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G *#P*d#p p p p p p p p p p p p p p p A#Q*R*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p S$S*_.> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m%T*U*v.p p p p p p p p p p p p p p p V*W*o+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p Z#X*L.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G h$Y*Z*p p p p p p p p p p p p p p p p `* => . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p .=+=m%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.@=#=$=p p p p p p p p p p p p p p p %=&=*=G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p ==-=;=> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . b#>=,=p p p p p p p p p p p p p p '=)=!=@ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p L*~={=>.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > ]=^=p p p p p p p p p p p p p p p /=(=6._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p _=:=<=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.[=}=|=p p p p p p p p p p p p p p m#1=z$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p 2=3=,#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m%V.4=5=p p p p p p p p p p p p p p p 6=7=G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p Q#8=]@G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G ]@9=0=!&p p p p p p p p p p p p p p a=b=c=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p r d=3+,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,#e=f=]&p p p p p p p p p p p p q p g=W h=_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p i=b=> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G F%j=k=v.p p p p p p p p p p p p p l=m=n=z$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p o=p=q=_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W%,#r=s=h p p p p p p p p p p p p p v%t=u=. G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p P.v=w=_#W%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W%<=e.x=y=p p p p p p p p p p p p p p z=A=z._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p B=C=D=E=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E=F=G=H=v.p p p p p p p p p p p p p I=J=K=V.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p L=M=. _.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.N=O=4#p p p p p p p p p p p p p P=Q=R=G _.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p S$S=T=+ _.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G U=V=W=p p p p p p p p p p p p p X=Y=Z=G G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p `= -.-+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.I$+-@-p p p p p p p p p p p p p #-$-%-e._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p &-*-+#G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G . =---;-q p p p p p p p p p p p p q >-,-'-> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p )-!-~-z$. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > {-]-z=4#p p p p p p p p p p p p A#^-/-(-_.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p _-:-<-> V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > ,#_.E [-}-Z#p p p p p p p p p p p p |-1-2-3-> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p 4-5-6-7-_.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m%C*8-9-;-p p p p p p p p p p p p p v.0-a-b-> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Q c-d-e-. ,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V@_.F%f-g-h-q p p p p p p p p p p p p q Y@i-j-G G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p k-l-m-n-+#> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.V@6#d+o-p-q-p p p p p p p p p p p p p l=r-s-[=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p Z#t-u-v-w-. ,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . G z$*#x-y-z-}$p p p p p p p p p p p p p A-B-C-D-+ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p E-F-G-H-6#> > G G . . . . . . . . . . . . . . . . . . . . . G _.. V.I-J-K-L-p p p p p p p p p p p p p p M-Y=N-'-> G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p R.#-p p p p p p p p p p p p p A#O-P-Q-R-S-F%6.G m%V@. . . . . . . . . . . . . . G V@_.@ V.T-U-V-W-X-v%p p p p p p p p p p p p p p |@Y-Z-`-_.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p ;.;+;A#p p p p p p p p p p p p p -&@;#;$;%;&;*;L.'-> G V@_#=;m%. . V@m&_#,#_.> F%7-|#-;;;>;,;';Z.p p p p p p p p p p p p p p );O%!;~;*#+ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p {;];^;/;)-p p p p p p p p p p p p p p P (;_;:;<;[;};|;1;e%m@2;C*V.V.7-3;4;5;6;7;8;9;0;a;b;c;d;q p p p p p p p p p p p p p p k*e;f;g;. ,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p h;i;j-j;k;l;p p p p p p p p p p p p p p p Z#j m;c;n;o;p;q;r;s;t;u;v;w;x;y;z;A;B;C;D;E;%.4#p p p p p p p p p p p p p p p p F;G;H;I;@ G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$J;+ `-K;L;M;{.p p p p p p p p p p p p p p p p p p 5%N;z@^$O;P;Q;R;S;T;U;V;W;X;p p p p p p p p p p p p p p p p p p p Y.Y;Z;`;. ,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$> @ e. >.>+>@>q p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p #>3&$>%>&>6._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ G V@z$1#*>=>->;>p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p @->>,>'>C*V.,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . G _.F%)>!>~>{>]>p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q o=^>/>(>c=V._._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . G _.*#_>:><>&*[>5%p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p A-}>|>1>2>3>G G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . ,.> h$4>5>6>v=7>@&p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p 8>9>0>a>b>c>d>F=F%G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . G z$h$e>f>g>h>i>j>!&p p p p p p p p p p p p p p p p p p p p p p p p v.k>S;l>m>n>W$o>z$. V@_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . G G . *#p>q>r>s>t>u>v>w>x>#-v%Z#q p p p p p p p q v.4#v%[#r#y><&z>A>B>C>D>E>]@> > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . ,.V@. D=K=F>G>H>I>J>K>L>Z*M>N>O>P>Q>R>S>T>U>D;V>W>X>Y>Z>`> ,.,k#6#> V@,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . V@V@+ 6#(-+,@,#,$,%,&,*,=,-,;,>,,,',),!,~,{,],^,/,(,D=h$,.,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . ,.,.> F%]@h$z$_,8 :,<,[,},:,|,, Q@z$h$*#z$. _.,._.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . _.,._.. . > > > > > > > . . . _.,.G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p O$P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p 1,P$+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p 2,3,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p h;4,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p 5,6,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * 1&p p p p p p p p p p p p p p p p p p p p p p 7,8,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9,0,p p p p p p p p p p p p p p p p p p p p p p a,b,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; c,p p p p p p p p p p p p p p p p p p p p p p d,e,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G f,g,p p p p p p p p p p p p p p p p p p p p p p h,i,+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.j,k,p p p p p p p p p p p p p p p p p p p p p v.l,=$> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.m,n,p p p p p p p p p p p p p p p p p p p p p Z#o,p,> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.q,r,p p p p p p p p p p p p p p p p p p p p p 4#s,t,> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.u,v,p p p p p p p p p p p p p p p p p p p p p A#w,x,> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.y,z,p p p p p p p p p p p p p p p p p p p p p A,B,C,. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.L#D,p p p p p p p p p p p p p p p p p p p p p ,=E,F,. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G G,H,p p p p p p p p p p p p p p p p p p p p p |=I,]#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G J,K,p p p p p p p p p p p p p p p p p p p p p L,M,7@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G v$N,p p p p p p p p p p p p p p p p p p p p p Y.O,F&G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G P,Q,p p p p p p p p p p p p p p p p p p p p p R,S,T,G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . U,V,p p p p p p p p p p p p p p p p p p p p p W,X,Y,_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z,`,p p p p p p p p p p p p p p p p p p p p p '.'+'_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > @'O;p p p p p p p p p p p p p p p p p p p p p #'$'~&,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > E$9>p p p p p p p p p p p p p p p p p p p p p %'&'*'V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + ='-'p p p p p p p p p p p p p p p p p p p p p ;'>']@G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + ,'8>p p p p p p p p p p p p p p p p p p p p p '')'V.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ !'p p p p p p p p p p p p p p p p p p p p p p ~'{'V.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G ]'^'p p p p p p p p p p p p p p p p p p p p p p /'('+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,._':'p p p p p p p p p p p p p p p p p p p p p p <'['> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.}'|'p p p p p p p p p p p p p p p p p p p p p p 1'2'. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 3'4'p p p p p p p p p p p p p p p p p p p p p p 5'6'_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 7'8'p p p p p p p p p p p p p p p p p p p p p p 9'0',.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a'b'p p p p p p p p p p p p p p p p p p p p p p c'd',#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > e'f'p p p p p p p p p p p p p p p p p p p p p p m=g',#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ h'Z#p p p p p p p p p p p p p p p p p p p p p q i'e.W%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G D=j'p p p p p p p p p p p p p p p p p p p p p p _%k'@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _.l'm'p p p p p p p p p p p p p p p p p p p p p p n'o'@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G p'q'p p p p p p p p p p p p p p p p p p p p p p r'>;G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s't'p p p p p p p p p p p p p p p p p p p p p p u'v'V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > F>w'p p p p p p p p p p p p p p p p p p p p p p x'y'_#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + z'A'p p p p p p p p p p p p p p p p p p p p p p B'C'=;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G e.D'E'p p p p p p p p p p p p p p p p p p p p p q F']@W%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G 5.G'H'p p p p p p p p p p p p p p p p p p p p p E*I'+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J'K'}%p p p p p p p p p p p p p p p p p p p p p L'M'. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p+N'v.p p p p p p p p p p p p p p p p p p p p p O'P'V@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > Q'R'p p p p p p p p p p p p p p p p p p p p p p S'T',#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > U'V'p p p p p p p p p p p p p p p p p p p p p q W'X'_.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . > Y'Z'p p p p p p p p p p p p p p p p p p p p p i#`'K%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . Q@),p p p p p p p p p p p p p p p p p p p p p p ).)V.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . _.$%+)p p p p p p p p p p p p p p p p p p p p p p @)#)h$G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . $)%)p p p p p p p p p p p p p p p p p p p p p p _ &)V.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . # *)p p p p p p p p p p p p p p p p p p p p p p p =)-)+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . G ;)>),)')')')')')')')')')')')')')')')')')')')')')%.))!). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . ~){)])^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)^)/)()_):)G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . & & ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; & ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . . . . . . . . . . . . . . . . . . . . . . "}; diff --git a/src/ristretto255.h b/src/ristretto255.h index f571ea5..8315cba 100644 --- a/src/ristretto255.h +++ b/src/ristretto255.h @@ -143,11 +143,9 @@ namespace ristretto255 { (const unsigned char*)&sj[0], sj.size() ); - if (i) throw HashReuseException(); + if (i) throw HashReuseException(); //Bug, the library always returns 0 no matter what misuse has happened. return *this; } - - }; static_assert(!has_machine_independent_representation >, "Don't want to partially hash partial hashes"); @@ -216,12 +214,14 @@ namespace ristretto255 { hash(const hash&) = default; // Copy constructor hash& operator=(hash&&) = default; // Move assignment. hash& operator=(const hash&) = default; // Copy assignment. + bool operator==(const hash&) const = default; //Do not need constant time equality test on hashes + auto operator<=>(const hash&) const = delete; //ordering operation on hashes makes no sense. explicit hash(hsh& in) { int i = crypto_generichash_blake2b_final( &in.st, &blob[0], hashsize / 8); assert(i == 0); - if (i) throw HashReuseException(); + if (i) throw HashReuseException(); //Bug, the library always returns 0 no matter what misuse has happened. } template< has_machine_independent_representation T, typename... Args>explicit hash(const T& first, Args... args) { // not restraining the variant args by concept, because they get caught deeper in, @@ -234,19 +234,7 @@ namespace ristretto255 { int i = crypto_generichash_blake2b_final( &in.st, &blob[0], hashsize / 8); - assert(i == 0); - } - hash& operator=(hsh&& in) { - int i = crypto_generichash_blake2b_final( - &in.st, - &blob[0], hashsize / 8); - if (i) throw HashReuseException(); - } - bool operator==(const hash& pt) const& { - return blob == pt.blob; //Do not need constant time equality test on hashes - } - bool operator!=(const hash& pt) const& { - return blob != pt.blob; //Do not need constant time equality test on hashes + if (i) throw HashReuseException(); //Bug, the library always returns 0 no matter what misuse has happened. } }; template diff --git a/src/serialization.h b/src/serialization.h index 0eaf4ca..a026d88 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -113,20 +113,24 @@ // we assume the string is already machine independent, which is to say, we assume // it comes from a utf8 locale. - inline auto serialize(const char* sp) { return std::span(static_cast(static_cast(sp)), strlen(sp) + 1); } + inline auto serialize(const char* sp) { + return std::span(static_cast(static_cast(sp)), strlen(sp) + 1); } inline auto serialize(const decltype(std::declval().ToUTF8()) sz){ return serialize(static_cast(sz)); } - /* Don't do this. Disaster ensues, - + /* Don't do this. Disaster ensues: inline auto serialize(const wxString& wxstr) { - return serialize(static_cast(wxstr.ToUTF8())); - } - If we allowed wxwidgets string to be serializable, all sorts of surprising things + return serialize(static_cast(wxstr.ToUTF8())); } + Instead do this:*/ + std::spanserialize(const wxString&) = delete; + std::spanserialize(const wxString) = delete; + std::spanserialize(wxString&) = delete; + + /*If we allowed wxwidgets string to be serializable, all sorts of surprising things would be serializable in surprising ways, because wxWidgets can convert all sorts of things into strings that you were likely not expecting, in ways - unlikely to be machine independent, so you if you give an object to be + unlikely to be machine independent, so if you give an object to be hashed that you have not provided some correct means for serializing, C++ is apt to unhelpfully and unexpectedly turn it into a wxString, @@ -141,7 +145,6 @@ // On reflection, VLQ format is not convenient for the intended usage (merkle patricia trees // representing SQL indexes, and a better format is to compress leading zero or leading 0xFF bytes // with the length of the run being implied by a count of the bytes following the run) - template class userial : public std::span { public: std::array::digits + 6) / 7> bblob; diff --git a/src/testbed.cpp b/src/testbed.cpp index a0ab14e..d768299 100644 --- a/src/testbed.cpp +++ b/src/testbed.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +//#include //#include /* Any code here can be deleted at will without impact on the @@ -25,7 +26,7 @@ void ascii2test(); extern const uint8_t* const ascii2six; namespace testbed { - using /*ristretto255::hash, ristretto255::hsh, */ristretto255::scalar, + using ristretto255::hash, ristretto255::hsh, ristretto255::scalar, ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin, ro::bin2hex, ro::fasthash, ro::CompileSizedString, ro::base58, ro::has_machine_independent_representation; @@ -61,6 +62,12 @@ If using queumessage, the testbed code will complete while the dialog */ void testbed() { + hsh a_hsh=hsh().hashinto("the quick brown fox", "jumped over the lazy dog"); + hash<256> a_hash = a_hsh; +// wxVersionInfo wx = wxWebView::GetBackendVersionInfo(wxASCII_STR(wxWebViewBackendDefault)); +// wxLogMessage(wx.ToString()); +// wx = wxWebView::GetBackendVersionInfo(wxASCII_STR(wxWebViewBackendEdge)); +// wxLogMessage(wx.ToString()); // queue_error_message("hello world"); // throw MyException("hello world exception", __LINE__, __func__, SrcFilename); } diff --git a/src/unit_test.cpp b/src/unit_test.cpp index 85750b2..02d7d4a 100644 --- a/src/unit_test.cpp +++ b/src/unit_test.cpp @@ -383,20 +383,18 @@ static bool OpenWallet(void) { initialization, should bring up the more complex UI for constructing or selecting your wallet file.*/ ILogMessage("\tWallet file"); - assert(singletonApp->pConfig); - singletonApp->pConfig->SetPath(wxT("/Wallet")); - wxFileName LastUsedSqlite(singletonApp->pConfig->Read(wxT("LastUsed"), wxT(""))); bool fWalletNameOk{ false }; wxStandardPaths& StandardPaths(wxStandardPaths::Get()); StandardPaths.UseAppInfo(3); wxFileName DefaultSqlite(StandardPaths.GetUserLocalDataDir(), "default.wallet"); + wxFileName& LastUsedSqlite(singletonFrame->m_LastUsedWallet); wxLogMessage(wxT("\t\tLastUsed=\"%s\""), LastUsedSqlite.GetFullPath()); if (!LastUsedSqlite.IsOk() || !LastUsedSqlite.HasName() || !LastUsedSqlite.HasExt()) { wxLogMessage(wxT("\t\tDefault=\"%s\""), DefaultSqlite.GetFullPath()); assert(DefaultSqlite.IsOk() && DefaultSqlite.HasName() && DefaultSqlite.HasExt()); if (DefaultSqlite.FileExists()) { LastUsedSqlite = DefaultSqlite; - singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath()); + singletonFrame->m_LastUsedWallet = LastUsedSqlite; fWalletNameOk = true; } } @@ -443,7 +441,8 @@ CREATE TABLE "Keys"( "ROWID" INTEGER PRIMARY KEY, "pubkey" BLOB NOT NULL UNIQUE, "id" integer NOT NULL, - "use" INTEGER NOT NULL); + "use" INTEGER NOT NULL +) STRICT; CREATE UNIQUE INDEX i_pubkey ON Keys (pubkey); CREATE UNIQUE INDEX i_id ON Keys (use, id); @@ -451,17 +450,49 @@ CREATE UNIQUE INDEX i_id ON Keys (use, id); CREATE TABLE "Names"( "ROWID" INTEGER PRIMARY KEY, "name" TEXT NOT NULL UNIQUE -); +) STRICT; CREATE UNIQUE INDEX i_names ON Names (name); CREATE TABLE "Misc"( "ROWID" INTEGER PRIMARY KEY, - "m" BLOB -); -COMMIT;)|"); + "m" ANY +) STRICT; +COMMIT; + +BEGIN IMMEDIATE TRANSACTION; +CREATE VIEW UserZookoIDs AS +SELECT + "Names".name AS name, + "Keys".pubkey AS pubkey +FROM "Names" INNER JOIN "Keys" +ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1 +ORDER BY LOWER("name"), "name" +COLLATE BINARY; +COMMIT; + +BEGIN IMMEDIATE TRANSACTION; +CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN + INSERT OR FAIL INTO "Names" VALUES( + NULL, + NEW."name" + ); + INSERT OR FAIL INTO "Keys" VALUES( + NULL, + NEW."pubkey", + last_insert_rowid(), + 1 + ); +END; + +CREATE TRIGGER DeleteUserZookoID INSTEAD OF DELETE ON UserZookoIDs FOR EACH ROW BEGIN + DELETE FROM "Keys" WHERE "Keys"."pubkey" = OLD."pubkey"; + DELETE FROM "Names" WHERE "Names"."name" = OLD."name"; +END; +COMMIT; +)|"); LastUsedSqlite = DefaultSqlite; - singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath()); + singletonFrame->m_LastUsedWallet = LastUsedSqlite; wxLogMessage(wxT("\t\tConstructing default wallet %s"), DefaultSqlite.GetFullPath()); // We now have a working wallet file with no valid data. Attempting to create a strong random secret, a name, and public and private keys for that name. diff --git a/wxWidgets b/wxWidgets index 71d2e28..73809b8 160000 --- a/wxWidgets +++ b/wxWidgets @@ -1 +1 @@ -Subproject commit 71d2e28c0b32f80f2d39778c65f824c7bd0e8d48 +Subproject commit 73809b8550d3919a95c65f07f94ea91f339b5487