Never really figured out why my code was breaking

fixed it by looking for funny things that deviated from
the sameples,  and doing various recommended safe things,
and found a few sql errors, and one by one the crashes
went away.

The new wxWidgets just seems less tolerant of little careless
stuff that is not right.
This commit is contained in:
Cheng 2023-10-18 10:23:55 +00:00
parent bd08d22cef
commit d59729f396
No known key found for this signature in database
GPG Key ID: 571C3A9C3B9E6FCA
38 changed files with 7894 additions and 350 deletions

View File

@ -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}
)

View File

@ -1,14 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*">
</assemblyIdentity>
</dependentAssembly>
</dependency>
<application> <application>
<windowsSettings> <windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage> <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings> </windowsSettings>
</application> </application>
</assembly> </assembly>

View File

@ -4,10 +4,26 @@
// this icon is used with wxFrame::SetIcon() // this icon is used with wxFrame::SetIcon()
AAArho ICON "../docs/rho.ico" AAArho ICON "../docs/rho.ico"
// set this to 1 if you don't want to use manifest resource (manifest resource // and alphabetically (!), so put this icon first and give it a name
// is needed to enable visual styles on Windows XP - see docs/msw/winxp.txt // starting with "a"
// for more information) 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 #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, ... // to enable full High DPI suppport, we need to opt in into Per-Monitor (V2) DPI awareness,
#include "wx/msw/wx.rc" // 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"

29
msvc/winConfigWidgets.bat Normal file
View File

@ -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
)

3
samples/README.txt Normal file
View File

@ -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

62
samples/config/app.cpp Normal file
View File

@ -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;
}

26
samples/config/app.h Normal file
View File

@ -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 <zeitlin@dptmaths.ens-cachan.fr>
// 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;
};

20
samples/config/config.rc Normal file
View File

@ -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"

31
samples/config/config.sln Normal file
View File

@ -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

View File

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectName>config</ProjectName>
<ProjectGuid>{D2B749B3-2C84-506D-B503-5049D1C8A6B1}</ProjectGuid>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.34031.279</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\build\$(Configuration)\</OutDir>
<IntDir>..\..\build\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>true</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\build\$(Configuration)\</OutDir>
<IntDir>..\..\build\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>true</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.\..\..\lib\vc_x64_lib\mswud;.\..\..\include;.;.\..\..\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</Midl>
<ClCompile>
<AdditionalOptions>/Zc:__cplusplus /utf-8 </AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\wxWidgets\lib\vc_x64_lib\mswud;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>Use</PrecompiledHeader>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\wxWidgets\lib\vc_x64_lib\mswud;.\..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>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)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
<AdditionalOptions> /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../../wxWidgets/lib/vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.\..\..\lib\vc_x64_lib\mswu;.\..\..\include;.;.\..\..\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\..\wxWidgets\lib\vc_x64_lib\mswu;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalOptions>/Zc:__cplusplus /utf-8 </AdditionalOptions>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\wxWidgets\lib\vc_x64_lib\mswu;..\..\wxWidgets\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>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)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalOptions> /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../../wxWidgets/lib/vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="app.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="frame.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="config.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="app.h" />
<ClInclude Include="frame.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<Manifest Include="..\..\msvc\wallet.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

161
samples/config/frame.cpp Normal file
View File

@ -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");
}

19
samples/config/frame.h Normal file
View File

@ -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;
};

View File

@ -0,0 +1 @@
#include "stdafx.h"

22
samples/config/stdafx.h Normal file
View File

@ -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"

134
samples/dialogs/app.cpp Normal file
View File

@ -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);
}

38
samples/dialogs/app.h Normal file
View File

@ -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;
};

893
samples/dialogs/dialogs.cpp Normal file
View File

@ -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

321
samples/dialogs/dialogs.h Normal file
View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{8241F179-E1E6-5760-8B4F-5CE0D518BE5B}</ProjectGuid>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.34031.279</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\build\$(Configuration)\</OutDir>
<IntDir>..\..\build\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>true</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\build\$(Configuration)\</OutDir>
<IntDir>..\..\build\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>true</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</Midl>
<ClCompile>
<AdditionalOptions>/MP /Zc:__cplusplus /utf-8 %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>Use</PrecompiledHeader>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswud;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>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)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../..\wxWidgets\lib\vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>../../build/Debug/dialogs.pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
<AdditionalOptions> /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib %(AdditionalOptions)</AdditionalOptions>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</Midl>
<ClCompile>
<AdditionalOptions>/MP /Zc:__cplusplus /utf-8 %(AdditionalOptions)</AdditionalOptions>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE=1;_CRT_NON_CONFORMING_SWPRINTFS=1;_SCL_SECURE_NO_WARNINGS=1;__WXMSW__;NDEBUG;_UNICODE;_WINDOWS;NOPCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>../..\wxWidgets\lib\vc_x64_lib\mswu;../..\wxWidgets\include;.;../..\wxWidgets\samples;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>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)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../..\wxWidgets\lib\vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>../../build/Release/dialogs.pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalOptions> /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib %(AdditionalOptions)</AdditionalOptions>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="app.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="dialogs.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="frame.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="app.h" />
<ClInclude Include="dialogs.h" />
<ClInclude Include="frame.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="dialogs.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="../..\msvc\wallet.manifest" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="tips.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

3222
samples/dialogs/frame.cpp Normal file

File diff suppressed because it is too large Load Diff

298
samples/dialogs/frame.h Normal file
View File

@ -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
};

View File

@ -0,0 +1 @@
#include "stdafx.h"

133
samples/dialogs/stdafx.h Normal file
View File

@ -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 <wx/stdpaths.h>
#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"

157
samples/dialogs/tip.xpm Normal file
View File

@ -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."
};

18
samples/dialogs/tips.txt Normal file
View File

@ -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().

View File

@ -2,11 +2,11 @@
wxIMPLEMENT_APP(App); wxIMPLEMENT_APP(App);
App::App() App::App() : m_Config("wallet", "rho")
{ {
assert (singletonApp == nullptr); assert (singletonApp == nullptr);
singletonApp = this; singletonApp = this;
wxConfigBase::DontCreateOnDemand();
} }
App::~App() App::~App()
@ -18,41 +18,40 @@ App::~App()
} }
bool App::OnInit() bool App::OnInit()
{ if (wxApp::OnInit()) { {
pConfig = std::unique_ptr<wxConfig>(new wxConfig("wallet", "rho")); if (wxApp::OnInit()) {
/* This causes the non volatile config data to be stored under rho\wallet wxConfigBase* pConfig = &m_Config;
We will generally place data in the database, and if additional executables need their own data /* This causes the non volatile config data to be stored under rho\wallet
in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */ We will generally place data in the database, and if additional executables need their own data
pConfig->SetRecordDefaults(false); in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */
/* pConfig corresponds to the Windows Registry entry /* pConfig corresponds to the Windows Registry entry
Computer\HKEY_CURRENT_USER\Software\rho\wallet Computer\HKEY_CURRENT_USER\Software\rho\wallet
Contrary to wxWidgets documentation, the config data on windows is by default stored in Contrary to wxWidgets documentation, the config data on windows is by default stored in
HKCU, HKEY_CURRENT_USER, not in HKLM, HKEY_LOCAL_MACHINE. HKCU, HKEY_CURRENT_USER, not in HKLM, HKEY_LOCAL_MACHINE.
We probably should have placed per user data in an sqlite3 file in We probably should have placed per user data in an sqlite3 file in
wxStandardPaths::GetUserDataDir() wxStandardPaths::GetUserDataDir()
Data global to all users has to go in an sqlite3 file in wxStandardPaths::GetAppDocumentsDir() Data global to all users has to go in an sqlite3 file in wxStandardPaths::GetAppDocumentsDir()
or wxStandardPaths::GetLocalDataDir() or wxStandardPaths::GetLocalDataDir()
User local database will record the derivation of all secrets, and what wallets along the path 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 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 no privacy sensitive information, and will also hold data global to all users on a particular
machine. machine.
A wallet's secret can be stored in a file - we will eventually provide passwords for files, 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, 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 a sophisticated attacker can perform an offline brute force attack, thus a human memorable
password only provides protection against casual and opportunistic attackers. password only provides protection against casual and opportunistic attackers.
If the file is insecure, password needs to impossible to remember, and stored somewhere secure..*/ If the file is insecure, password needs to impossible to remember, and stored somewhere secure..*/
Frame* frame = new Frame(pConfig->GetAppName());
Frame* frame = new Frame(pConfig->GetAppName()); frame->Show(true); //Frame, being top level unowned window, is owned by the one and only message pump
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();
if (m_display_in_front && singletonFrame != nullptr && singletonFrame->m_pLogWindow != nullptr) singletonFrame->m_pLogWindow->GetFrame()->Raise(); return true;
return true; }
} else return false;
else return false;
} }
int App::OnRun() int App::OnRun()
@ -196,8 +195,7 @@ void App::OnError(wxCommandEvent& event)
} }
int App::OnExit() int App::OnExit()
{ { if (errorCode)wxLogDebug("%s", szError);
assert(pConfig.get()); m_Config.Flush();
if (errorCode)wxLogDebug("%s", szError);
return 0; return 0;
} }

View File

@ -3,10 +3,6 @@
class App : public wxApp class App : public wxApp
{ {
public: public:
std::unique_ptr<wxConfig>pConfig;
// 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(); App();
virtual ~App(); virtual ~App();
virtual bool OnInit() wxOVERRIDE; virtual bool OnInit() wxOVERRIDE;
@ -22,6 +18,10 @@ public:
bool m_log_focus_events{ false }; bool m_log_focus_events{ false };
bool m_quick_unit_test{ false }; bool m_quick_unit_test{ false };
bool m_complete_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<wxString> m_params; wxVector<wxString> m_params;
}; };

View File

@ -71,7 +71,7 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
} }
Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this); Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this);
this->SetSize(this->GetParent()->GetClientSize()); this->SetSize(this->GetParent()->GetClientSize());
singletonFrame->m_LastUsedSqlite.Assign(walletfile); singletonFrame->m_LastUsedWallet.Assign(walletfile);
wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) }; wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) };
singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu. singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu.

View File

@ -7,21 +7,22 @@
Frame* singletonFrame{nullptr}; Frame* singletonFrame{nullptr};
void Frame::RestorePositionFromConfig(const wxSize& bestSize) { void Frame::RestorePositionFromConfig(const wxSize& bestSize) {
wxConfigBase* pConfig = &singletonApp->m_Config;
// SetPath() understands ".." but you should probably never use it. // 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 // restore frame position and size
int x = singletonApp->pConfig->ReadLong(wxT("x"), scr.x / 4); int x = pConfig->ReadLong(wxT("x"), scr.x / 4);
int y = singletonApp->pConfig->ReadLong(wxT("y"), scr.y / 4); int y = pConfig->ReadLong(wxT("y"), scr.y / 4);
int w = singletonApp->pConfig->ReadLong(wxT("w"), scr.x / 2); int w = pConfig->ReadLong(wxT("w"), scr.x / 2);
int h = singletonApp->pConfig->ReadLong(wxT("h"), scr.y / 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); 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); 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)); 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)); y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10));
this->Move(x, y); 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); this->SetSize(w, h);
singletonApp->pConfig->SetPath(wxT("/"));
if (singletonApp->m_display || m_pLogWindow != nullptr) { if (singletonApp->m_display || m_pLogWindow != nullptr) {
m_pLogWindow->GetFrame()->SetSize(w, h); m_pLogWindow->GetFrame()->SetSize(w, h);
if (singletonApp->m_display_in_front) { if (singletonApp->m_display_in_front) {
@ -39,31 +40,32 @@ void Frame::RestorePositionFromConfig(const wxSize& bestSize) {
} }
void Frame::StorePositionToConfig() { void Frame::StorePositionToConfig() {
if (singletonApp->pConfig) { wxConfigBase* pConfig = &singletonApp->m_Config;
singletonApp->pConfig->SetPath(wxT("/MainFrame")); if (pConfig) {
pConfig->SetPath(wxT("/MainFrame"));
if (this->IsMaximized()) { if (this->IsMaximized()) {
singletonApp->pConfig->Write(wxT("Maximized"), true); pConfig->Write(wxT("Maximized"), true);
} }
else { else {
// save the frame position // save the frame position
int x, y, w, h; int x, y, w, h;
this->GetSize(&w, &h); this->GetSize(&w, &h);
this->GetPosition(&x, &y); this->GetPosition(&x, &y);
singletonApp->pConfig->Write(wxT("x"), (long)x); pConfig->Write(wxT("x"), (long)x);
singletonApp->pConfig->Write(wxT("y"), (long)y); pConfig->Write(wxT("y"), (long)y);
singletonApp->pConfig->Write(wxT("w"), (long)w); pConfig->Write(wxT("w"), (long)w);
singletonApp->pConfig->Write(wxT("h"), (long)h); pConfig->Write(wxT("h"), (long)h);
singletonApp->pConfig->Write(wxT("Maximized"), false); pConfig->Write(wxT("Maximized"), false);
} }
singletonApp->pConfig->SetPath(wxT("/")); pConfig->SetPath(wxT("/"));
} }
} }
// main frame ctor // main frame ctor
Frame::Frame(wxString wxs) Frame::Frame(const wxString& wxs)
: wxFrame(nullptr, myID_MAINFRAME, wxs, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, wxs), : wxFrame(nullptr, myID_MAINFRAME, wxs, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, wxs),
m_panel(), m_panel(),
m_LastUsedSqlite() m_LastUsedWallet()
{ {
try { try {
assert(singletonFrame == nullptr); 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->Append(wxID_OPEN, menu_strings[0].tail[2][0], menu_strings[0].tail[2][1]);
menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN); menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN);
{ auto _ = new wxMenuItem(menuFile, wxID_CLOSE); { 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->Append(_);
menuFile->Bind(wxEVT_MENU, &Frame::OnMyCloseMPanel, this, wxID_CLOSE); 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->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG);
menuFile->Append(wxID_EXIT); menuFile->Append(wxID_EXIT);
menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT);
@ -149,16 +151,34 @@ Frame::Frame(wxString wxs)
CreateStatusBar(); CreateStatusBar();
menuBar->EnableTop(1, false); //disable edit menu. menuBar->EnableTop(1, false); //disable edit menu.
// child controls // child controls
m_LastUsedSqlite.Assign(singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")));
wxPanel* panel{ nullptr }; 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 { try {
if (m_LastUsedSqlite.IsOk()) if (m_LastUsedWallet.IsOk())
{ //Try to load an existing file. { //Try to load an existing file.
panel = new display_wallet(this, m_LastUsedSqlite); panel = new display_wallet(this, m_LastUsedWallet);
} }
else { else {
panel = new welcome_to_rhocoin(this); panel = new welcome_to_rhocoin(this);
} }
} }
catch (const std::exception& e) { catch (const std::exception& e) {
// if the attempt to load an existing wallet file fails, // if the attempt to load an existing wallet file fails,
@ -167,12 +187,12 @@ Frame::Frame(wxString wxs)
queue_error_message(e.what()); queue_error_message(e.what());
panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame. 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 // 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. // 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 // but I have the concept of the primary child of the frame window, while
// wxWidgets lacks that concept. // wxWidgets lacks that concept.
// m_panel signifies the child window of the frame that currently matters. // m_panel signifies the child window of the frame that currently matters.
m_panel = panel;
this->RestorePositionFromConfig(ClientToWindowSize(m_panel->GetBestSize())); this->RestorePositionFromConfig(ClientToWindowSize(m_panel->GetBestSize()));
SetClientSize(GetClientSize()); SetClientSize(GetClientSize());
} }
@ -211,14 +231,13 @@ void Frame::OnAbout(wxCommandEvent& event)
void Frame::OnDeleteConfiguration(wxCommandEvent&) void Frame::OnDeleteConfiguration(wxCommandEvent&)
{ {
std::unique_ptr<wxConfigBase>pConfig{ wxConfigBase::Set(nullptr) }; wxConfigBase* pConfig = &singletonApp->m_Config;
if (pConfig) if (pConfig)
{ {
if (pConfig->DeleteAll()) if (pConfig->DeleteAll())
{ {
wxLogMessage(wxT("Config file/registry key successfully deleted.")); wxLogMessage(wxT("Config file/registry key successfully deleted."));
wxConfigBase::DontCreateOnDemand(); wxConfigBase::DontCreateOnDemand();
pConfig.release();
} }
else else
{ {
@ -270,7 +289,9 @@ CREATE TABLE "Misc"(
"ROWID" INTEGER PRIMARY KEY, "ROWID" INTEGER PRIMARY KEY,
"m" ANY "m" ANY
) STRICT; ) STRICT;
COMMIT;
BEGIN IMMEDIATE TRANSACTION;
CREATE VIEW UserZookoIDs AS CREATE VIEW UserZookoIDs AS
SELECT SELECT
"Names".name AS name, "Names".name AS name,
@ -279,7 +300,9 @@ FROM "Names" INNER JOIN "Keys"
ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1 ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1
ORDER BY LOWER("name"), "name" ORDER BY LOWER("name"), "name"
COLLATE BINARY; COLLATE BINARY;
COMMIT;
BEGIN IMMEDIATE TRANSACTION;
CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN
INSERT OR FAIL INTO "Names" VALUES( INSERT OR FAIL INTO "Names" VALUES(
NULL, NULL,
@ -291,15 +314,14 @@ CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW
last_insert_rowid(), last_insert_rowid(),
1 1
); );
END END;
CREATE TRIGGER DeleteUserZookoID INSTEAD OF DELETE ON UserZookoIDs FOR EACH ROW BEGIN CREATE TRIGGER DeleteUserZookoID INSTEAD OF DELETE ON UserZookoIDs FOR EACH ROW BEGIN
DELETE FROM "Keys" WHERE "Keys"."pubkey" = OLD."pubkey"; DELETE FROM "Keys" WHERE "Keys"."pubkey" = OLD."pubkey";
DELETE FROM "Names" WHERE "Names"."name" = OLD."name"; DELETE FROM "Names" WHERE "Names"."name" = OLD."name";
END END;
COMMIT;
)|");
COMMIT;)|");
wxLogMessage("\t\tConstructing default wallet %s", filename.GetFullPath()); 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. // 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"); 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)) 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, wxFileDialog dialog(this,
sz_new_wallet_new_secret, sz_new_wallet_new_secret,
wxStandardPaths::Get().GetUserLocalDataDir(), wxstrWalletPath,
sz_default_wallet_name, wxstrWalletName,
sz_wallet_files_title, wxString::Format
wxFD_SAVE | wxFD_OVERWRITE_PROMPT); ("wallet (*.wallet)|*.wallet|All (%s)|%s",
dialog.SetFilterIndex(1); wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
);
dialog.SetFilterIndex(m_FileDialogFilterIndex);
if (dialog.ShowModal() == wxID_OK) if (dialog.ShowModal() == wxID_OK)
{ {
wxLogMessage("%s, filter %d", wxLogMessage("%s, filter %d",
dialog.GetPath(), dialog.GetFilterIndex()); dialog.GetPath(),
hide_panel hid(m_panel); dialog.GetFilterIndex()
wxString wxStrWallet{ dialog.GetDirectory() + "/" + dialog.GetFilename() }; );
wxFileName wxFileWallet(wxStrWallet); wxFileName wxFileWallet(dialog.GetPath());
ristretto255::hash<256> WalletSecret{ wxStrWallet.ToUTF8() }; ristretto255::hash<256> WalletSecret( wxFileWallet.GetFullPath().ToUTF8());
NewWallet(wxFileWallet, WalletSecret); NewWallet(wxFileWallet, WalletSecret);
wxLogMessage("new wallet created: %s", wxStrWallet); wxLogMessage("new wallet created: %s", wxFileWallet.GetFullPath());
if (m_panel)m_panel->Destroy(); if (m_panel)m_panel->Close(true);
m_panel = new display_wallet(this, wxFileWallet); m_panel = nullptr;
m_panel->Show(); 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&) { void Frame::OnFileOpen(wxCommandEvent&) {
wxString directory{ wxT("") }; wxString directory(wxEmptyString);
wxString file{ wxT("") }; wxString file(wxEmptyString);
if (m_LastUsedSqlite.IsOk()) { if (m_LastUsedWallet.IsOk()) {
directory = m_LastUsedSqlite.GetPath(); directory = m_LastUsedWallet.GetPath();
file = m_LastUsedSqlite.GetFullName(); if (m_LastUsedWallet.FileExists()) {
file = m_LastUsedWallet.GetFullName();
}
} }
else {
wxFileDialog m_LastUsedWallet = m_DefaultWalletLocation;
dialog(this, sz_open_wallet_file, directory, file, directory = m_LastUsedWallet.GetPath();
sz_wallet_files_title, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR); 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) if (dialog.ShowModal() == wxID_CANCEL)
return; // the user changed idea... return; // the user changed idea...
wxLogMessage("Opening %s", dialog.GetPath()); wxLogMessage("Opening %s", dialog.GetPath());
wxFileName walletfile(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. // the correct derived destructor regardless of what kind of object it is.
m_panel = nullptr;
display_wallet* panel = new display_wallet(this, walletfile); display_wallet* panel = new display_wallet(this, walletfile);
m_panel = panel; 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&) { void Frame::RecreateWalletFromExistingSecret(wxCommandEvent&) {
@ -403,13 +446,6 @@ void Frame::OnMyCloseMPanel(wxCommandEvent& event) {
if (m_panel) { if (m_panel) {
if (!m_panel->Close(false)) throw MyException("Close cancelled"); 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) { void Frame::OnMenuOpen(wxMenuEvent& evt) {
@ -423,10 +459,14 @@ void Frame::OnMenuOpen(wxMenuEvent& evt) {
Frame::~Frame() { Frame::~Frame() {
assert(singletonFrame == this); assert(singletonFrame == this);
singletonFrame = nullptr; singletonFrame = nullptr;
wxConfigBase* pConfig = wxConfigBase::Get(); wxConfigBase& Config = singletonApp->m_Config;
if (pConfig == nullptr)return;
StorePositionToConfig(); StorePositionToConfig();
if (singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")) != m_LastUsedSqlite.GetFullPath()) { Config.SetPath(wxT("/TipOfTheDay"));
pConfig->Write(wxT("/Wallet/LastUsed"), m_LastUsedSqlite.GetFullPath()); 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();
} }

View File

@ -57,13 +57,16 @@ public:
}; };
class Frame : public wxFrame class Frame : public wxFrame
{ { int m_TipOfTheDayIndex;
int m_FileDialogFilterIndex;
public: public:
bool m_showTipsAtStartup;
wxFileName m_LastUsedWallet;
wxFileName m_DefaultWalletLocation;
Frame(const wxString& title);
virtual ~Frame();
wxLogWindow*m_pLogWindow{ nullptr }; wxLogWindow*m_pLogWindow{ nullptr };
std::unique_ptr<wxLogNull>m_pLogNull{ nullptr }; std::unique_ptr<wxLogNull>m_pLogNull{ nullptr };
Frame(wxString);
~Frame();
wxFileName m_LastUsedSqlite;
wxPanel* m_panel{nullptr}; //The once current child panel. wxPanel* m_panel{nullptr}; //The once current child panel.
private: private:
typedef MenuLink<Frame> MenuLink; typedef MenuLink<Frame> MenuLink;

File diff suppressed because it is too large Load Diff

View File

@ -143,11 +143,9 @@ namespace ristretto255 {
(const unsigned char*)&sj[0], (const unsigned char*)&sj[0],
sj.size() sj.size()
); );
if (i) throw HashReuseException(); if (i) throw HashReuseException(); //Bug, the library always returns 0 no matter what misuse has happened.
return *this; return *this;
} }
}; };
static_assert(!has_machine_independent_representation<hsh<256> >, "Don't want to partially hash partial hashes"); static_assert(!has_machine_independent_representation<hsh<256> >, "Don't want to partially hash partial hashes");
@ -216,12 +214,14 @@ namespace ristretto255 {
hash(const hash&) = default; // Copy constructor hash(const hash&) = default; // Copy constructor
hash& operator=(hash&&) = default; // Move assignment. hash& operator=(hash&&) = default; // Move assignment.
hash& operator=(const hash&) = default; // Copy 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<hashsize>& in) { explicit hash(hsh<hashsize>& in) {
int i = crypto_generichash_blake2b_final( int i = crypto_generichash_blake2b_final(
&in.st, &in.st,
&blob[0], hashsize / 8); &blob[0], hashsize / 8);
assert(i == 0); 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) { 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, // 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( int i = crypto_generichash_blake2b_final(
&in.st, &in.st,
&blob[0], hashsize / 8); &blob[0], hashsize / 8);
assert(i == 0); if (i) throw HashReuseException(); //Bug, the library always returns 0 no matter what misuse has happened.
}
hash& operator=(hsh<hashsize>&& in) {
int i = crypto_generichash_blake2b_final(
&in.st,
&blob[0], hashsize / 8);
if (i) throw HashReuseException();
}
bool operator==(const hash<hashsize>& pt) const& {
return blob == pt.blob; //Do not need constant time equality test on hashes
}
bool operator!=(const hash<hashsize>& pt) const& {
return blob != pt.blob; //Do not need constant time equality test on hashes
} }
}; };
template<unsigned int hashsize = 256> template<unsigned int hashsize = 256>

View File

@ -113,20 +113,24 @@
// we assume the string is already machine independent, which is to say, we assume // we assume the string is already machine independent, which is to say, we assume
// it comes from a utf8 locale. // it comes from a utf8 locale.
inline auto serialize(const char* sp) { return std::span(static_cast<char*>(static_cast<std::nullptr_t>(sp)), strlen(sp) + 1); } inline auto serialize(const char* sp) {
return std::span(static_cast<const byte*>(static_cast<std::nullptr_t>(sp)), strlen(sp) + 1); }
inline auto serialize(const decltype(std::declval<wxString>().ToUTF8()) sz){ inline auto serialize(const decltype(std::declval<wxString>().ToUTF8()) sz){
return serialize(static_cast<const char*>(sz)); return serialize(static_cast<const char*>(sz));
} }
/* Don't do this. Disaster ensues, /* Don't do this. Disaster ensues:
inline auto serialize(const wxString& wxstr) { inline auto serialize(const wxString& wxstr) {
return serialize(static_cast<const char*>(wxstr.ToUTF8())); return serialize(static_cast<const char*>(wxstr.ToUTF8())); }
} Instead do this:*/
If we allowed wxwidgets string to be serializable, all sorts of surprising things std::span<const byte>serialize(const wxString&) = delete;
std::span<const byte>serialize(const wxString) = delete;
std::span<const byte>serialize(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 would be serializable in surprising ways, because wxWidgets can convert all
sorts of things into strings that you were likely not expecting, in ways 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 hashed that you have not provided some correct means for serializing, C++ is
apt to unhelpfully and unexpectedly turn it into a wxString, 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 // 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 // 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) // with the length of the run being implied by a count of the bytes following the run)
template<std::unsigned_integral T> class userial : public std::span<byte> { template<std::unsigned_integral T> class userial : public std::span<byte> {
public: public:
std::array<byte, (std::numeric_limits<T>::digits + 6) / 7> bblob; std::array<byte, (std::numeric_limits<T>::digits + 6) / 7> bblob;

View File

@ -1,4 +1,5 @@
#include "stdafx.h" #include "stdafx.h"
//#include <wx/webview.h>
//#include <mbctype.h> //#include <mbctype.h>
/* Any code here can be deleted at will without impact on the /* Any code here can be deleted at will without impact on the
@ -25,7 +26,7 @@ void ascii2test();
extern const uint8_t* const ascii2six; extern const uint8_t* const ascii2six;
namespace testbed { namespace testbed {
using /*ristretto255::hash, ristretto255::hsh, */ristretto255::scalar, using ristretto255::hash, ristretto255::hsh, ristretto255::scalar,
ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin, ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin,
ro::bin2hex, ro::fasthash, ro::CompileSizedString, ro::bin2hex, ro::fasthash, ro::CompileSizedString,
ro::base58, ro::has_machine_independent_representation; ro::base58, ro::has_machine_independent_representation;
@ -61,6 +62,12 @@ If using queumessage, the testbed code will complete while the dialog
*/ */
void testbed() { 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"); // queue_error_message("hello world");
// throw MyException("hello world exception", __LINE__, __func__, SrcFilename); // throw MyException("hello world exception", __LINE__, __func__, SrcFilename);
} }

View File

@ -383,20 +383,18 @@ static bool OpenWallet(void) {
initialization, should bring up the more complex UI for constructing or selecting your initialization, should bring up the more complex UI for constructing or selecting your
wallet file.*/ wallet file.*/
ILogMessage("\tWallet file"); ILogMessage("\tWallet file");
assert(singletonApp->pConfig);
singletonApp->pConfig->SetPath(wxT("/Wallet"));
wxFileName LastUsedSqlite(singletonApp->pConfig->Read(wxT("LastUsed"), wxT("")));
bool fWalletNameOk{ false }; bool fWalletNameOk{ false };
wxStandardPaths& StandardPaths(wxStandardPaths::Get()); wxStandardPaths& StandardPaths(wxStandardPaths::Get());
StandardPaths.UseAppInfo(3); StandardPaths.UseAppInfo(3);
wxFileName DefaultSqlite(StandardPaths.GetUserLocalDataDir(), "default.wallet"); wxFileName DefaultSqlite(StandardPaths.GetUserLocalDataDir(), "default.wallet");
wxFileName& LastUsedSqlite(singletonFrame->m_LastUsedWallet);
wxLogMessage(wxT("\t\tLastUsed=\"%s\""), LastUsedSqlite.GetFullPath()); wxLogMessage(wxT("\t\tLastUsed=\"%s\""), LastUsedSqlite.GetFullPath());
if (!LastUsedSqlite.IsOk() || !LastUsedSqlite.HasName() || !LastUsedSqlite.HasExt()) { if (!LastUsedSqlite.IsOk() || !LastUsedSqlite.HasName() || !LastUsedSqlite.HasExt()) {
wxLogMessage(wxT("\t\tDefault=\"%s\""), DefaultSqlite.GetFullPath()); wxLogMessage(wxT("\t\tDefault=\"%s\""), DefaultSqlite.GetFullPath());
assert(DefaultSqlite.IsOk() && DefaultSqlite.HasName() && DefaultSqlite.HasExt()); assert(DefaultSqlite.IsOk() && DefaultSqlite.HasName() && DefaultSqlite.HasExt());
if (DefaultSqlite.FileExists()) { if (DefaultSqlite.FileExists()) {
LastUsedSqlite = DefaultSqlite; LastUsedSqlite = DefaultSqlite;
singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath()); singletonFrame->m_LastUsedWallet = LastUsedSqlite;
fWalletNameOk = true; fWalletNameOk = true;
} }
} }
@ -443,7 +441,8 @@ CREATE TABLE "Keys"(
"ROWID" INTEGER PRIMARY KEY, "ROWID" INTEGER PRIMARY KEY,
"pubkey" BLOB NOT NULL UNIQUE, "pubkey" BLOB NOT NULL UNIQUE,
"id" integer NOT NULL, "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_pubkey ON Keys (pubkey);
CREATE UNIQUE INDEX i_id ON Keys (use, id); 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"( CREATE TABLE "Names"(
"ROWID" INTEGER PRIMARY KEY, "ROWID" INTEGER PRIMARY KEY,
"name" TEXT NOT NULL UNIQUE "name" TEXT NOT NULL UNIQUE
); ) STRICT;
CREATE UNIQUE INDEX i_names ON Names (name); CREATE UNIQUE INDEX i_names ON Names (name);
CREATE TABLE "Misc"( CREATE TABLE "Misc"(
"ROWID" INTEGER PRIMARY KEY, "ROWID" INTEGER PRIMARY KEY,
"m" BLOB "m" ANY
); ) STRICT;
COMMIT;)|"); 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; LastUsedSqlite = DefaultSqlite;
singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath()); singletonFrame->m_LastUsedWallet = LastUsedSqlite;
wxLogMessage(wxT("\t\tConstructing default wallet %s"), DefaultSqlite.GetFullPath()); 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. // 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.

@ -1 +1 @@
Subproject commit 71d2e28c0b32f80f2d39778c65f824c7bd0e8d48 Subproject commit 73809b8550d3919a95c65f07f94ea91f339b5487