mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 08:50:25 +01:00
Merge branch 'v2_develop' into v2_develop
This commit is contained in:
75
.github/workflows/publish.yml
vendored
75
.github/workflows/publish.yml
vendored
@@ -1,42 +1,42 @@
|
||||
name: Publish Terminal.Gui v2
|
||||
name: Publish Terminal.Gui
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop, v2_release, v2_develop ]
|
||||
tags:
|
||||
- v2.0.0-alpha.*
|
||||
- v*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Build and Publish v2 to Nuget.org
|
||||
name: Build and Publish to Nuget.org
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 #fetch-depth is needed for GitVersion
|
||||
fetch-depth: 0 # fetch-depth is needed for GitVersion
|
||||
|
||||
- name: Install and calculate the new version with GitVersion
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0
|
||||
with:
|
||||
versionSpec: '6.x'
|
||||
versionSpec: '5.x'
|
||||
includePrerelease: true
|
||||
|
||||
- name: Determine Version
|
||||
uses: gittools/actions/gitversion/execute@v0
|
||||
with:
|
||||
useConfigFile: true
|
||||
useConfigFile: true
|
||||
#additionalArguments: /b develop
|
||||
id: gitversion # step id used as reference for output values
|
||||
|
||||
- name: Display GitVersion outputs
|
||||
run: |
|
||||
echo "Version: ${{ steps.gitversion.outputs.SemVer }}"
|
||||
echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.CommitsSinceVersionSource }}"
|
||||
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 7.0
|
||||
dotnet-quality: 'ga'
|
||||
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
|
||||
@@ -48,34 +48,27 @@ jobs:
|
||||
- name: Pack
|
||||
run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}'
|
||||
|
||||
#- name: Test to generate Code Coverage Report
|
||||
# run: |
|
||||
# sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
|
||||
# dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings
|
||||
# mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
|
||||
# - name: Test to generate Code Coverage Report
|
||||
# run: |
|
||||
# sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
|
||||
# dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings
|
||||
# mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
|
||||
|
||||
#- name: Create Test Coverage Badge
|
||||
# uses: simon-k/dotnet-code-coverage-badge@v1.0.0
|
||||
# id: create_coverage_badge
|
||||
# with:
|
||||
# label: Unit Test Coverage
|
||||
# color: brightgreen
|
||||
# path: UnitTests/TestResults/coverage.opencover.xml
|
||||
# gist-filename: code-coverage.json
|
||||
# # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27
|
||||
# gist-id: 90ef67a684cb71db1817921a970f8d27
|
||||
# gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}
|
||||
|
||||
#- name: Print Code Coverage
|
||||
# run: |
|
||||
# echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
|
||||
# echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"
|
||||
# - name: Create Test Coverage Badge
|
||||
# uses: simon-k/dotnet-code-coverage-badge@v1.0.0
|
||||
# id: create_coverage_badge
|
||||
# with:
|
||||
# label: Unit Test Coverage
|
||||
# color: brightgreen
|
||||
# path: UnitTests/TestResults/coverage.opencover.xml
|
||||
# gist-filename: code-coverage.json
|
||||
# gist-id: 90ef67a684cb71db1817921a970f8d27
|
||||
# gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}
|
||||
|
||||
# - name: Print Code Coverage
|
||||
# run: |
|
||||
# echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
|
||||
# echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"
|
||||
|
||||
- name: Publish to NuGet.org
|
||||
run: dotnet nuget push Terminal.Gui/bin/Release/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Unlist from NuGet.org if it's an alpha
|
||||
run: dotnet nuget delete --non-interactive Terminal.Gui ${{ steps.gitversion.outputs.SemVer }} --api-key ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json
|
||||
if: contains(steps.gitversion.outputs.SemVer, 'alpha')
|
||||
|
||||
|
||||
run: dotnet nuget push Terminal.Gui/bin/Release/Terminal.Gui.${{ steps.gitversion.outputs.SemVer }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }}
|
||||
|
||||
107
GitVersion.yml
107
GitVersion.yml
@@ -1,21 +1,14 @@
|
||||
mode: ContinuousDeployment
|
||||
tag-prefix: '[vV]'
|
||||
continuous-delivery-fallback-tag: 'pre'
|
||||
continuous-delivery-fallback-tag: pre
|
||||
branches:
|
||||
# v1_develop:
|
||||
# mode: ContinuousDeployment
|
||||
# tag: pre
|
||||
# regex: ^v1_develop?[/-]
|
||||
# is-release-branch: false
|
||||
# source-branches:
|
||||
# - v1
|
||||
# v1:
|
||||
# tag: rc
|
||||
# increment: Patch
|
||||
# regex: ^v2?[/-]
|
||||
# is-release-branch: false
|
||||
# source-branches: []
|
||||
# is-mainline: true
|
||||
develop:
|
||||
mode: ContinuousDeployment
|
||||
tag: pre
|
||||
regex: develop
|
||||
source-branches:
|
||||
- main
|
||||
pre-release-weight: 100
|
||||
|
||||
v2_develop:
|
||||
mode: ContinuousDeployment
|
||||
@@ -23,28 +16,76 @@ branches:
|
||||
regex: ^v2_develop?[/-]
|
||||
is-release-branch: true
|
||||
tracks-release-branches: true
|
||||
is-source-branch-for: ['v2']
|
||||
#is-source-branch-for: ['v2']
|
||||
source-branches: []
|
||||
v2:
|
||||
mode: ContinuousDeployment
|
||||
is-release-branch: false
|
||||
tag: alpha
|
||||
increment: Patch
|
||||
regex: ^v2?[/-]
|
||||
source-branches: ['v2_develop']
|
||||
|
||||
# feature:
|
||||
# tag: useBranchName
|
||||
# regex: ^features?[/-]
|
||||
# source-branches:
|
||||
# - v1
|
||||
# - v1_develop
|
||||
# - v2
|
||||
# - v2_develop
|
||||
|
||||
main:
|
||||
tag: rc
|
||||
increment: Patch
|
||||
source-branches:
|
||||
- develop
|
||||
- main
|
||||
feature:
|
||||
tag: useBranchName
|
||||
regex: ^features?[/-]
|
||||
source-branches:
|
||||
- develop
|
||||
- main
|
||||
pull-request:
|
||||
tag: PullRequest.{BranchName}
|
||||
increment: Inherit
|
||||
ignore:
|
||||
sha: []
|
||||
merge-message-formats: {}
|
||||
|
||||
|
||||
# next-version: 2.0.0
|
||||
# mode: ContinuousDeployment
|
||||
# tag-prefix: '[vV]'
|
||||
# continuous-delivery-fallback-tag: 'pre'
|
||||
# branches:
|
||||
# # v1_develop:
|
||||
# # mode: ContinuousDeployment
|
||||
# # tag: pre
|
||||
# # regex: ^v1_develop?[/-]
|
||||
# # is-release-branch: false
|
||||
# # source-branches:
|
||||
# # - v1
|
||||
# # v1:
|
||||
# # tag: rc
|
||||
# # increment: Patch
|
||||
# # regex: ^v2?[/-]
|
||||
# # is-release-branch: false
|
||||
# # source-branches: []
|
||||
# # is-mainline: true
|
||||
|
||||
# v2_develop:
|
||||
# mode: ContinuousDeployment
|
||||
# tag: pre
|
||||
# regex: ^v2_develop?[/-]
|
||||
# is-release-branch: true
|
||||
# tracks-release-branches: true
|
||||
# is-source-branch-for: ['v2']
|
||||
# source-branches: []
|
||||
# v2:
|
||||
# mode: ContinuousDeployment
|
||||
# is-release-branch: false
|
||||
# tag: alpha
|
||||
# increment: Patch
|
||||
# regex: ^v2?[/-]
|
||||
# source-branches: ['v2_develop']
|
||||
|
||||
# # feature:
|
||||
# # tag: useBranchName
|
||||
# # regex: ^features?[/-]
|
||||
# # source-branches:
|
||||
# # - v1
|
||||
# # - v1_develop
|
||||
# # - v2
|
||||
# # - v2_develop
|
||||
|
||||
# pull-request:
|
||||
# tag: PullRequest.{BranchName}
|
||||
# increment: Inherit
|
||||
# ignore:
|
||||
# sha: []
|
||||
# merge-message-formats: {}
|
||||
|
||||
@@ -103,15 +103,17 @@ class NetWinVTConsole {
|
||||
static extern uint GetLastError ();
|
||||
}
|
||||
|
||||
internal class NetEvents {
|
||||
internal class NetEvents : IDisposable {
|
||||
ManualResetEventSlim _inputReady = new ManualResetEventSlim (false);
|
||||
ManualResetEventSlim _waitForStart = new ManualResetEventSlim (false);
|
||||
ManualResetEventSlim _winChange = new ManualResetEventSlim (false);
|
||||
Queue<InputResult?> _inputResultQueue = new Queue<InputResult?> ();
|
||||
ConsoleDriver _consoleDriver;
|
||||
volatile ConsoleKeyInfo [] _cki = null;
|
||||
volatile static bool _isEscSeq;
|
||||
bool _stopTasks;
|
||||
ConsoleKeyInfo [] _cki;
|
||||
bool _isEscSeq;
|
||||
CancellationTokenSource _cancellationTokenSource;
|
||||
CancellationToken _cancellationToken;
|
||||
|
||||
#if PROCESS_REQUEST
|
||||
bool _neededProcessRequest;
|
||||
#endif
|
||||
@@ -120,19 +122,16 @@ internal class NetEvents {
|
||||
public NetEvents (ConsoleDriver consoleDriver)
|
||||
{
|
||||
_consoleDriver = consoleDriver ?? throw new ArgumentNullException (nameof (consoleDriver));
|
||||
_cancellationTokenSource = new CancellationTokenSource ();
|
||||
_cancellationToken = _cancellationTokenSource.Token;
|
||||
Task.Run (ProcessInputResultQueue);
|
||||
Task.Run (CheckWindowSizeChange);
|
||||
}
|
||||
|
||||
internal void StopTasks ()
|
||||
{
|
||||
_stopTasks = true;
|
||||
}
|
||||
|
||||
public InputResult? ReadConsoleInput ()
|
||||
{
|
||||
while (true) {
|
||||
if (_stopTasks) {
|
||||
if (_cancellationToken.IsCancellationRequested) {
|
||||
return null;
|
||||
}
|
||||
_waitForStart.Set ();
|
||||
@@ -151,6 +150,24 @@ internal class NetEvents {
|
||||
}
|
||||
}
|
||||
|
||||
static ConsoleKeyInfo ReadConsoleKeyInfo (CancellationToken cancellationToken, bool intercept = true)
|
||||
{
|
||||
// if there is a key available, return it without waiting
|
||||
// (or dispatching work to the thread queue)
|
||||
if (Console.KeyAvailable) {
|
||||
return Console.ReadKey (intercept);
|
||||
}
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested) {
|
||||
Task.Delay (100);
|
||||
if (Console.KeyAvailable) {
|
||||
return Console.ReadKey (intercept);
|
||||
}
|
||||
}
|
||||
cancellationToken.ThrowIfCancellationRequested ();
|
||||
return default;
|
||||
}
|
||||
|
||||
void ProcessInputResultQueue ()
|
||||
{
|
||||
while (true) {
|
||||
@@ -163,9 +180,18 @@ internal class NetEvents {
|
||||
ConsoleKeyInfo newConsoleKeyInfo = default;
|
||||
|
||||
while (true) {
|
||||
ConsoleKeyInfo consoleKeyInfo = Console.ReadKey (true);
|
||||
if (_cancellationToken.IsCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
ConsoleKeyInfo consoleKeyInfo;
|
||||
try {
|
||||
consoleKeyInfo = ReadConsoleKeyInfo (_cancellationToken, true);
|
||||
} catch (OperationCanceledException) {
|
||||
return;
|
||||
}
|
||||
if ((consoleKeyInfo.KeyChar == (char)Key.Esc && !_isEscSeq)
|
||||
|| (consoleKeyInfo.KeyChar != (char)Key.Esc && _isEscSeq)) {
|
||||
|| (consoleKeyInfo.KeyChar != (char)Key.Esc && _isEscSeq)) {
|
||||
|
||||
if (_cki == null && consoleKeyInfo.KeyChar != (char)Key.Esc && _isEscSeq) {
|
||||
_cki = EscSeqUtils.ResizeArray (new ConsoleKeyInfo ((char)Key.Esc, 0,
|
||||
false, false, false), _cki);
|
||||
@@ -179,17 +205,16 @@ internal class NetEvents {
|
||||
_isEscSeq = false;
|
||||
break;
|
||||
} else if (consoleKeyInfo.KeyChar == (char)Key.Esc && _isEscSeq && _cki != null) {
|
||||
if (_cki != null) {
|
||||
ProcessRequestResponse (ref newConsoleKeyInfo, ref key, _cki, ref mod);
|
||||
_cki = null;
|
||||
ProcessRequestResponse (ref newConsoleKeyInfo, ref key, _cki, ref mod);
|
||||
_cki = null;
|
||||
if (Console.KeyAvailable) {
|
||||
_cki = EscSeqUtils.ResizeArray (consoleKeyInfo, _cki);
|
||||
} else {
|
||||
ProcessMapConsoleKeyInfo (consoleKeyInfo);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
_inputResultQueue.Enqueue (new InputResult {
|
||||
EventType = EventType.Key,
|
||||
ConsoleKeyInfo = EscSeqUtils.MapConsoleKeyInfo (consoleKeyInfo)
|
||||
});
|
||||
_isEscSeq = false;
|
||||
ProcessMapConsoleKeyInfo (consoleKeyInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -197,19 +222,25 @@ internal class NetEvents {
|
||||
|
||||
_inputReady.Set ();
|
||||
}
|
||||
|
||||
void ProcessMapConsoleKeyInfo (ConsoleKeyInfo consoleKeyInfo)
|
||||
{
|
||||
_inputResultQueue.Enqueue (new InputResult {
|
||||
EventType = EventType.Key,
|
||||
ConsoleKeyInfo = EscSeqUtils.MapConsoleKeyInfo (consoleKeyInfo)
|
||||
});
|
||||
_isEscSeq = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckWindowSizeChange ()
|
||||
{
|
||||
void RequestWindowSize ()
|
||||
void RequestWindowSize (CancellationToken cancellationToken)
|
||||
{
|
||||
while (true) {
|
||||
while (!cancellationToken.IsCancellationRequested) {
|
||||
// Wait for a while then check if screen has changed sizes
|
||||
Task.Delay (500).Wait ();
|
||||
Task.Delay (500, cancellationToken);
|
||||
|
||||
if (_stopTasks) {
|
||||
return;
|
||||
}
|
||||
int buffHeight, buffWidth;
|
||||
if (((NetDriver)_consoleDriver).IsWinPlatform) {
|
||||
buffHeight = Math.Max (Console.BufferHeight, 0);
|
||||
@@ -227,15 +258,20 @@ internal class NetEvents {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cancellationToken.ThrowIfCancellationRequested ();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (_stopTasks) {
|
||||
if (_cancellationToken.IsCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
_winChange.Wait ();
|
||||
_winChange.Reset ();
|
||||
RequestWindowSize ();
|
||||
try {
|
||||
RequestWindowSize (_cancellationToken);
|
||||
} catch (OperationCanceledException) {
|
||||
return;
|
||||
}
|
||||
_inputReady.Set ();
|
||||
}
|
||||
}
|
||||
@@ -536,6 +572,23 @@ internal class NetEvents {
|
||||
|
||||
_inputResultQueue.Enqueue (inputResult);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
_cancellationTokenSource.Cancel ();
|
||||
_cancellationTokenSource.Dispose ();
|
||||
_cancellationTokenSource = null;
|
||||
FlushIn ();
|
||||
}
|
||||
|
||||
void FlushIn ()
|
||||
{
|
||||
// throws away any typeahead that has been typed by
|
||||
// the user and has not yet been read by the program.
|
||||
while (Console.KeyAvailable) {
|
||||
Console.ReadKey (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class NetDriver : ConsoleDriver {
|
||||
@@ -563,7 +616,7 @@ internal class NetDriver : ConsoleDriver {
|
||||
|
||||
public override void End ()
|
||||
{
|
||||
_mainLoop?._netEvents.StopTasks ();
|
||||
_mainLoop?._netEvents.Dispose ();
|
||||
|
||||
if (IsWinPlatform) {
|
||||
NetWinConsole?.Cleanup ();
|
||||
@@ -611,7 +664,7 @@ internal class NetDriver : ConsoleDriver {
|
||||
|
||||
if (!RunningUnitTests) {
|
||||
Console.TreatControlCAsInput = true;
|
||||
|
||||
|
||||
Cols = Console.WindowWidth;
|
||||
Rows = Console.WindowHeight;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Terminal.Gui {
|
||||
int result = MessageBox.Query (
|
||||
string.Format (Strings.fdDeleteTitle, adjective),
|
||||
string.Format (Strings.fdDeleteBody, adjective),
|
||||
Strings.fdYes, Strings.fdNo);
|
||||
Strings.btnYes, Strings.btnNo);
|
||||
|
||||
try {
|
||||
if (result == 0) {
|
||||
@@ -37,7 +37,7 @@ namespace Terminal.Gui {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
MessageBox.ErrorQuery (Strings.fdDeleteFailedTitle, ex.Message, "Ok");
|
||||
MessageBox.ErrorQuery (Strings.fdDeleteFailedTitle, ex.Message, Strings.btnOk);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -47,14 +47,14 @@ namespace Terminal.Gui {
|
||||
{
|
||||
|
||||
bool confirm = false;
|
||||
var btnOk = new Button ("Ok") {
|
||||
var btnOk = new Button (Strings.btnOk) {
|
||||
IsDefault = true,
|
||||
};
|
||||
btnOk.Clicked += (s, e) => {
|
||||
confirm = true;
|
||||
Application.RequestStop ();
|
||||
};
|
||||
var btnCancel = new Button ("Cancel");
|
||||
var btnCancel = new Button (Strings.btnCancel);
|
||||
btnCancel.Clicked += (s, e) => {
|
||||
confirm = false;
|
||||
Application.RequestStop ();
|
||||
|
||||
81
Terminal.Gui/Resources/Strings.Designer.cs
generated
81
Terminal.Gui/Resources/Strings.Designer.cs
generated
@@ -60,6 +60,69 @@ namespace Terminal.Gui.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cancel.
|
||||
/// </summary>
|
||||
internal static string btnCancel {
|
||||
get {
|
||||
return ResourceManager.GetString("btnCancel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No.
|
||||
/// </summary>
|
||||
internal static string btnNo {
|
||||
get {
|
||||
return ResourceManager.GetString("btnNo", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to OK.
|
||||
/// </summary>
|
||||
internal static string btnOk {
|
||||
get {
|
||||
return ResourceManager.GetString("btnOk", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open.
|
||||
/// </summary>
|
||||
internal static string btnOpen {
|
||||
get {
|
||||
return ResourceManager.GetString("btnOpen", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save.
|
||||
/// </summary>
|
||||
internal static string btnSave {
|
||||
get {
|
||||
return ResourceManager.GetString("btnSave", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save as.
|
||||
/// </summary>
|
||||
internal static string btnSaveAs {
|
||||
get {
|
||||
return ResourceManager.GetString("btnSaveAs", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Yes.
|
||||
/// </summary>
|
||||
internal static string btnYes {
|
||||
get {
|
||||
return ResourceManager.GetString("btnYes", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to _Copy.
|
||||
/// </summary>
|
||||
@@ -267,15 +330,6 @@ namespace Terminal.Gui.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No.
|
||||
/// </summary>
|
||||
internal static string fdNo {
|
||||
get {
|
||||
return ResourceManager.GetString("fdNo", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open.
|
||||
/// </summary>
|
||||
@@ -393,15 +447,6 @@ namespace Terminal.Gui.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Yes.
|
||||
/// </summary>
|
||||
internal static string fdYes {
|
||||
get {
|
||||
return ResourceManager.GetString("fdYes", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to _Back.
|
||||
/// </summary>
|
||||
|
||||
@@ -142,16 +142,16 @@
|
||||
<value>_Dossier</value>
|
||||
</data>
|
||||
<data name="fdFile" xml:space="preserve">
|
||||
<value>_Ficher</value>
|
||||
<value>Ficher</value>
|
||||
</data>
|
||||
<data name="fdSave" xml:space="preserve">
|
||||
<value>_Enregistrer</value>
|
||||
<value>Enregistrer</value>
|
||||
</data>
|
||||
<data name="fdSaveAs" xml:space="preserve">
|
||||
<value>E_nregistrer sous</value>
|
||||
<value>Enregistrer sous</value>
|
||||
</data>
|
||||
<data name="fdOpen" xml:space="preserve">
|
||||
<value>_Ouvrir</value>
|
||||
<value>Ouvrir</value>
|
||||
</data>
|
||||
<data name="fdSelectFolder" xml:space="preserve">
|
||||
<value>Sélection de _dossier</value>
|
||||
@@ -168,4 +168,13 @@
|
||||
<data name="wzNext" xml:space="preserve">
|
||||
<value>Prochai_n...</value>
|
||||
</data>
|
||||
<data name="btnSave" xml:space="preserve">
|
||||
<value>Enregistrer</value>
|
||||
</data>
|
||||
<data name="btnSaveAs" xml:space="preserve">
|
||||
<value>E_nregistrer sous</value>
|
||||
</data>
|
||||
<data name="btnOpen" xml:space="preserve">
|
||||
<value>Ouvrir</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -118,25 +118,25 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ctxCopy" xml:space="preserve">
|
||||
<value>コピー (C)</value>
|
||||
<value>コピー (_C)</value>
|
||||
</data>
|
||||
<data name="ctxCut" xml:space="preserve">
|
||||
<value>切り取り (T)</value>
|
||||
<value>切り取り (_T)</value>
|
||||
</data>
|
||||
<data name="ctxDeleteAll" xml:space="preserve">
|
||||
<value>全て削除 (D)</value>
|
||||
<value>全て削除 (_D)</value>
|
||||
</data>
|
||||
<data name="ctxPaste" xml:space="preserve">
|
||||
<value>貼り付け (P)</value>
|
||||
<value>貼り付け (_P)</value>
|
||||
</data>
|
||||
<data name="ctxRedo" xml:space="preserve">
|
||||
<value>やり直し (R)</value>
|
||||
<value>やり直し (_R)</value>
|
||||
</data>
|
||||
<data name="ctxSelectAll" xml:space="preserve">
|
||||
<value>全て選択 (S)</value>
|
||||
<value>全て選択 (_S)</value>
|
||||
</data>
|
||||
<data name="ctxUndo" xml:space="preserve">
|
||||
<value>元に戻す (U)</value>
|
||||
<value>元に戻す (_U)</value>
|
||||
</data>
|
||||
<data name="fdDirectory" xml:space="preserve">
|
||||
<value>ディレクトリ</value>
|
||||
@@ -154,18 +154,105 @@
|
||||
<value>開く</value>
|
||||
</data>
|
||||
<data name="fdSelectFolder" xml:space="preserve">
|
||||
<value>フォルダーを選択</value>
|
||||
<value>フォルダーを選択 (_S)</value>
|
||||
</data>
|
||||
<data name="fdSelectMixed" xml:space="preserve">
|
||||
<value>混在選択</value>
|
||||
<value>混在選択 (_S)</value>
|
||||
</data>
|
||||
<data name="wzBack" xml:space="preserve">
|
||||
<value>戻る</value>
|
||||
<value>戻る (_B)</value>
|
||||
</data>
|
||||
<data name="wzFinish" xml:space="preserve">
|
||||
<value>終える</value>
|
||||
<value>終わる (_N)</value>
|
||||
</data>
|
||||
<data name="wzNext" xml:space="preserve">
|
||||
<value>次に</value>
|
||||
<value>次に (_N)...</value>
|
||||
</data>
|
||||
<data name="fdDirectoryAlreadyExistsFeedback" xml:space="preserve">
|
||||
<value>同じ名前のディレクトリはすでに存在しました</value>
|
||||
</data>
|
||||
<data name="fdDeleteBody" xml:space="preserve">
|
||||
<value>“{0}”を削除もよろしいですか?この操作は元に戻りません</value>
|
||||
</data>
|
||||
<data name="fdType" xml:space="preserve">
|
||||
<value>タイプ</value>
|
||||
</data>
|
||||
<data name="fdSize" xml:space="preserve">
|
||||
<value>サイズ</value>
|
||||
</data>
|
||||
<data name="fdPathCaption" xml:space="preserve">
|
||||
<value>パスを入力</value>
|
||||
</data>
|
||||
<data name="fdFilename" xml:space="preserve">
|
||||
<value>ファイル名</value>
|
||||
</data>
|
||||
<data name="fdNewTitle" xml:space="preserve">
|
||||
<value>新規ディレクトリ</value>
|
||||
</data>
|
||||
<data name="btnNo" xml:space="preserve">
|
||||
<value>いいえ (_N)</value>
|
||||
</data>
|
||||
<data name="btnYes" xml:space="preserve">
|
||||
<value>はい (_Y)</value>
|
||||
</data>
|
||||
<data name="fdModified" xml:space="preserve">
|
||||
<value>変更日時</value>
|
||||
</data>
|
||||
<data name="fdFileOrDirectoryMustExistFeedback" xml:space="preserve">
|
||||
<value>すでに存在したファイルまたはディレクトリを選択してください</value>
|
||||
</data>
|
||||
<data name="fdDirectoryMustExistFeedback" xml:space="preserve">
|
||||
<value>すでに存在したディレクトリを選択してください</value>
|
||||
</data>
|
||||
<data name="fdFileMustExistFeedback" xml:space="preserve">
|
||||
<value>すでに存在したファイルを選択してください</value>
|
||||
</data>
|
||||
<data name="fdRenamePrompt" xml:space="preserve">
|
||||
<value>名前:</value>
|
||||
</data>
|
||||
<data name="fdDeleteTitle" xml:space="preserve">
|
||||
<value>{0} を削除</value>
|
||||
</data>
|
||||
<data name="fdNewFailed" xml:space="preserve">
|
||||
<value>新規失敗</value>
|
||||
</data>
|
||||
<data name="fdExisting" xml:space="preserve">
|
||||
<value>既存</value>
|
||||
</data>
|
||||
<data name="fdRenameTitle" xml:space="preserve">
|
||||
<value>名前を変更</value>
|
||||
</data>
|
||||
<data name="fdRenameFailedTitle" xml:space="preserve">
|
||||
<value>変更失敗</value>
|
||||
</data>
|
||||
<data name="fdDeleteFailedTitle" xml:space="preserve">
|
||||
<value>削除失敗</value>
|
||||
</data>
|
||||
<data name="fdFileAlreadyExistsFeedback" xml:space="preserve">
|
||||
<value>同じ名前のファイルはすでに存在しました</value>
|
||||
</data>
|
||||
<data name="fdSearchCaption" xml:space="preserve">
|
||||
<value>検索を入力</value>
|
||||
</data>
|
||||
<data name="fdWrongFileTypeFeedback" xml:space="preserve">
|
||||
<value>ファイルタイプが間違っでいます</value>
|
||||
</data>
|
||||
<data name="fdAnyFiles" xml:space="preserve">
|
||||
<value>任意ファイル</value>
|
||||
</data>
|
||||
<data name="btnCancel" xml:space="preserve">
|
||||
<value>キャンセル (_C)</value>
|
||||
</data>
|
||||
<data name="btnOk" xml:space="preserve">
|
||||
<value>OK (_O)</value>
|
||||
</data>
|
||||
<data name="btnOpen" xml:space="preserve">
|
||||
<value>開く (_O)</value>
|
||||
</data>
|
||||
<data name="btnSave" xml:space="preserve">
|
||||
<value>保存 (_S)</value>
|
||||
</data>
|
||||
<data name="btnSaveAs" xml:space="preserve">
|
||||
<value>名前を付けて保存 (_S)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -168,4 +168,13 @@
|
||||
<data name="wzNext" xml:space="preserve">
|
||||
<value>S_eguir</value>
|
||||
</data>
|
||||
<data name="btnSaveAs" xml:space="preserve">
|
||||
<value>Guardar como</value>
|
||||
</data>
|
||||
<data name="btnSave" xml:space="preserve">
|
||||
<value>Guardar</value>
|
||||
</data>
|
||||
<data name="btnOpen" xml:space="preserve">
|
||||
<value>Abrir</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -226,7 +226,7 @@
|
||||
<data name="fdNewTitle" xml:space="preserve">
|
||||
<value>New Folder</value>
|
||||
</data>
|
||||
<data name="fdNo" xml:space="preserve">
|
||||
<data name="btnNo" xml:space="preserve">
|
||||
<value>No</value>
|
||||
</data>
|
||||
<data name="fdRenameFailedTitle" xml:space="preserve">
|
||||
@@ -238,10 +238,25 @@
|
||||
<data name="fdRenameTitle" xml:space="preserve">
|
||||
<value>Rename</value>
|
||||
</data>
|
||||
<data name="fdYes" xml:space="preserve">
|
||||
<data name="btnYes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
<data name="fdExisting" xml:space="preserve">
|
||||
<value>Existing</value>
|
||||
</data>
|
||||
<data name="btnOpen" xml:space="preserve">
|
||||
<value>Open</value>
|
||||
</data>
|
||||
<data name="btnSave" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
<data name="btnSaveAs" xml:space="preserve">
|
||||
<value>Save as</value>
|
||||
</data>
|
||||
<data name="btnOk" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="btnCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
</root>
|
||||
258
Terminal.Gui/Resources/Strings.zh-Hans.resx
Normal file
258
Terminal.Gui/Resources/Strings.zh-Hans.resx
Normal file
@@ -0,0 +1,258 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ctxSelectAll" xml:space="preserve">
|
||||
<value>全选 (_S)</value>
|
||||
</data>
|
||||
<data name="ctxDeleteAll" xml:space="preserve">
|
||||
<value>清空 (_D)</value>
|
||||
</data>
|
||||
<data name="ctxCopy" xml:space="preserve">
|
||||
<value>复制 (_C)</value>
|
||||
</data>
|
||||
<data name="ctxCut" xml:space="preserve">
|
||||
<value>剪切 (_T)</value>
|
||||
</data>
|
||||
<data name="ctxPaste" xml:space="preserve">
|
||||
<value>粘贴 (_P)</value>
|
||||
</data>
|
||||
<data name="ctxUndo" xml:space="preserve">
|
||||
<value>撤销 (_U)</value>
|
||||
</data>
|
||||
<data name="ctxRedo" xml:space="preserve">
|
||||
<value>重做 (_R)</value>
|
||||
</data>
|
||||
<data name="fdDirectory" xml:space="preserve">
|
||||
<value>目录</value>
|
||||
</data>
|
||||
<data name="fdFile" xml:space="preserve">
|
||||
<value>文件</value>
|
||||
</data>
|
||||
<data name="fdSave" xml:space="preserve">
|
||||
<value>保存</value>
|
||||
</data>
|
||||
<data name="fdSaveAs" xml:space="preserve">
|
||||
<value>另存为</value>
|
||||
</data>
|
||||
<data name="fdOpen" xml:space="preserve">
|
||||
<value>打开</value>
|
||||
</data>
|
||||
<data name="wzNext" xml:space="preserve">
|
||||
<value>下一步 (_N)...</value>
|
||||
</data>
|
||||
<data name="fdSelectFolder" xml:space="preserve">
|
||||
<value>选择文件夹 (_S)</value>
|
||||
</data>
|
||||
<data name="fdSelectMixed" xml:space="preserve">
|
||||
<value>混合选择 (_S)</value>
|
||||
</data>
|
||||
<data name="wzBack" xml:space="preserve">
|
||||
<value>返回 (_B)</value>
|
||||
</data>
|
||||
<data name="wzFinish" xml:space="preserve">
|
||||
<value>结束 (_N)</value>
|
||||
</data>
|
||||
<data name="fdDirectoryAlreadyExistsFeedback" xml:space="preserve">
|
||||
<value>已存在相同名称的目录</value>
|
||||
</data>
|
||||
<data name="fdDirectoryMustExistFeedback" xml:space="preserve">
|
||||
<value>必须选择已有的目录</value>
|
||||
</data>
|
||||
<data name="fdFileAlreadyExistsFeedback" xml:space="preserve">
|
||||
<value>已存在相同名称的文件</value>
|
||||
</data>
|
||||
<data name="fdFileMustExistFeedback" xml:space="preserve">
|
||||
<value>必须选择已有的文件</value>
|
||||
</data>
|
||||
<data name="fdFilename" xml:space="preserve">
|
||||
<value>文件名</value>
|
||||
</data>
|
||||
<data name="fdFileOrDirectoryMustExistFeedback" xml:space="preserve">
|
||||
<value>必须选择已有的文件或目录</value>
|
||||
</data>
|
||||
<data name="fdModified" xml:space="preserve">
|
||||
<value>修改时间</value>
|
||||
</data>
|
||||
<data name="fdPathCaption" xml:space="preserve">
|
||||
<value>请输入路径</value>
|
||||
</data>
|
||||
<data name="fdSearchCaption" xml:space="preserve">
|
||||
<value>输入以搜索</value>
|
||||
</data>
|
||||
<data name="fdSize" xml:space="preserve">
|
||||
<value>大小</value>
|
||||
</data>
|
||||
<data name="fdType" xml:space="preserve">
|
||||
<value>类型</value>
|
||||
</data>
|
||||
<data name="fdWrongFileTypeFeedback" xml:space="preserve">
|
||||
<value>文件类型有误</value>
|
||||
</data>
|
||||
<data name="fdAnyFiles" xml:space="preserve">
|
||||
<value>任意文件</value>
|
||||
</data>
|
||||
<data name="fdDeleteBody" xml:space="preserve">
|
||||
<value>您是否要删除“{0}”?此操作不可撤销</value>
|
||||
</data>
|
||||
<data name="fdDeleteFailedTitle" xml:space="preserve">
|
||||
<value>删除失败</value>
|
||||
</data>
|
||||
<data name="fdDeleteTitle" xml:space="preserve">
|
||||
<value>删除 {0}</value>
|
||||
</data>
|
||||
<data name="fdNewFailed" xml:space="preserve">
|
||||
<value>新建失败</value>
|
||||
</data>
|
||||
<data name="fdNewTitle" xml:space="preserve">
|
||||
<value>新建文件夹</value>
|
||||
</data>
|
||||
<data name="btnNo" xml:space="preserve">
|
||||
<value>否 (_N)</value>
|
||||
</data>
|
||||
<data name="fdRenameFailedTitle" xml:space="preserve">
|
||||
<value>重命名失败</value>
|
||||
</data>
|
||||
<data name="fdRenamePrompt" xml:space="preserve">
|
||||
<value>名称:</value>
|
||||
</data>
|
||||
<data name="fdRenameTitle" xml:space="preserve">
|
||||
<value>重命名</value>
|
||||
</data>
|
||||
<data name="btnYes" xml:space="preserve">
|
||||
<value>是 (_Y)</value>
|
||||
</data>
|
||||
<data name="fdExisting" xml:space="preserve">
|
||||
<value>已有</value>
|
||||
</data>
|
||||
<data name="btnOk" xml:space="preserve">
|
||||
<value>确定 (_O)</value>
|
||||
</data>
|
||||
<data name="btnOpen" xml:space="preserve">
|
||||
<value>打开 (_O)</value>
|
||||
</data>
|
||||
<data name="btnSave" xml:space="preserve">
|
||||
<value>保存 (_S)</value>
|
||||
</data>
|
||||
<data name="btnSaveAs" xml:space="preserve">
|
||||
<value>另存为 (_S)</value>
|
||||
</data>
|
||||
<data name="btnCancel" xml:space="preserve">
|
||||
<value>取消 (_C)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -154,7 +154,7 @@ namespace Terminal.Gui {
|
||||
this.NavigateIf (k, Key.CursorUp, this.tableView);
|
||||
};
|
||||
|
||||
this.btnCancel = new Button ("Cancel") {
|
||||
this.btnCancel = new Button (Strings.btnCancel) {
|
||||
Y = Pos.AnchorEnd (1),
|
||||
X = Pos.Function (() =>
|
||||
this.Bounds.Width
|
||||
@@ -710,20 +710,32 @@ namespace Terminal.Gui {
|
||||
this.tbPath.SelectAll ();
|
||||
|
||||
if (string.IsNullOrEmpty (Title)) {
|
||||
switch (OpenMode) {
|
||||
case OpenMode.File:
|
||||
this.Title = $"{Strings.fdOpen} {(MustExist ? Strings.fdExisting + " " : "")}{Strings.fdFile}";
|
||||
break;
|
||||
case OpenMode.Directory:
|
||||
this.Title = $"{Strings.fdOpen} {(MustExist ? Strings.fdExisting + " " : "")}{Strings.fdDirectory}";
|
||||
break;
|
||||
case OpenMode.Mixed:
|
||||
this.Title = $"{Strings.fdOpen} {(MustExist ? Strings.fdExisting : "")}";
|
||||
break;
|
||||
}
|
||||
this.Title = GetDefaultTitle ();
|
||||
}
|
||||
this.LayoutSubviews ();
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a default dialog title, when <see cref="Title"/> is not set or empty,
|
||||
/// result of the function will be shown.
|
||||
/// </summary>
|
||||
protected virtual string GetDefaultTitle ()
|
||||
{
|
||||
List<string> titleParts = new () {
|
||||
Strings.fdOpen
|
||||
};
|
||||
if (MustExist) {
|
||||
titleParts.Add (Strings.fdExisting);
|
||||
}
|
||||
switch (OpenMode) {
|
||||
case OpenMode.File:
|
||||
titleParts.Add (Strings.fdFile);
|
||||
break;
|
||||
case OpenMode.Directory:
|
||||
titleParts.Add (Strings.fdDirectory);
|
||||
break;
|
||||
}
|
||||
return string.Join (' ', titleParts);
|
||||
}
|
||||
|
||||
private void AllowedTypeMenuClicked (int idx)
|
||||
{
|
||||
|
||||
@@ -55,8 +55,7 @@ namespace Terminal.Gui {
|
||||
/// To select more than one file, users can use the spacebar, or control-t.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class OpenDialog : FileDialog {
|
||||
|
||||
public class OpenDialog : FileDialog {
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OpenDialog"/>.
|
||||
/// </summary>
|
||||
@@ -70,9 +69,9 @@ namespace Terminal.Gui {
|
||||
/// <param name="openMode">The open mode.</param>
|
||||
public OpenDialog (string title, List<IAllowedType> allowedTypes = null, OpenMode openMode = OpenMode.File)
|
||||
{
|
||||
this.OpenMode = openMode;
|
||||
OpenMode = openMode;
|
||||
Title = title;
|
||||
Style.OkButtonText = openMode == OpenMode.File ? Strings.fdOpen : openMode == OpenMode.Directory ? Strings.fdSelectFolder : Strings.fdSelectMixed;
|
||||
Style.OkButtonText = openMode == OpenMode.File ? Strings.btnOpen : openMode == OpenMode.Directory ? Strings.fdSelectFolder : Strings.fdSelectMixed;
|
||||
|
||||
if (allowedTypes != null) {
|
||||
AllowedTypes = allowedTypes;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Terminal.Gui {
|
||||
{
|
||||
//: base (title, prompt: Strings.fdSave, nameFieldLabel: $"{Strings.fdSaveAs}:", message: message, allowedTypes) { }
|
||||
Title = title;
|
||||
Style.OkButtonText = Strings.fdSave;
|
||||
Style.OkButtonText = Strings.btnSave;
|
||||
|
||||
if(allowedTypes != null) {
|
||||
AllowedTypes = allowedTypes;
|
||||
@@ -62,5 +62,24 @@ namespace Terminal.Gui {
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetDefaultTitle ()
|
||||
{
|
||||
List<string> titleParts = new () {
|
||||
Strings.fdSave
|
||||
};
|
||||
if (MustExist) {
|
||||
titleParts.Add (Strings.fdExisting);
|
||||
}
|
||||
switch (OpenMode) {
|
||||
case OpenMode.File:
|
||||
titleParts.Add (Strings.fdFile);
|
||||
break;
|
||||
case OpenMode.Directory:
|
||||
titleParts.Add (Strings.fdDirectory);
|
||||
break;
|
||||
}
|
||||
return string.Join (' ', titleParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
.github\workflows\dotnet-core.yml = .github\workflows\dotnet-core.yml
|
||||
GitVersion.yml = GitVersion.yml
|
||||
global.json = global.json
|
||||
nuget.config = nuget.config
|
||||
.github\workflows\publish.yml = .github\workflows\publish.yml
|
||||
README.md = README.md
|
||||
Terminal.sln.DotSettings = Terminal.sln.DotSettings
|
||||
|
||||
181
UICatalog/Scenarios/Localization.cs
Normal file
181
UICatalog/Scenarios/Localization.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
[ScenarioMetadata (Name: "Localization", Description: "Test for localization resources.")]
|
||||
[ScenarioCategory ("Text and Formatting")]
|
||||
[ScenarioCategory ("Tests")]
|
||||
public class Localization : Scenario {
|
||||
public CultureInfo CurrentCulture { get; private set; } = Thread.CurrentThread.CurrentUICulture;
|
||||
|
||||
private CultureInfo [] _cultureInfoSource;
|
||||
private string [] _cultureInfoNameSource;
|
||||
private ComboBox _languageComboBox;
|
||||
private CheckBox _allowAnyCheckBox;
|
||||
private OpenMode _currentOpenMode = OpenMode.File;
|
||||
|
||||
public override void Setup ()
|
||||
{
|
||||
base.Setup ();
|
||||
_cultureInfoSource = Application.SupportedCultures.Append (CultureInfo.InvariantCulture).ToArray ();
|
||||
_cultureInfoNameSource = Application.SupportedCultures.Select (c => $"{c.NativeName} ({c.Name})").Append ("Invariant").ToArray ();
|
||||
var languageMenus = Application.SupportedCultures
|
||||
.Select (c => new MenuItem ($"{c.NativeName} ({c.Name})", "", () => SetCulture (c)))
|
||||
.Concat (
|
||||
new MenuItem [] {
|
||||
null,
|
||||
new MenuItem ("Invariant", "", () => SetCulture (CultureInfo.InvariantCulture))
|
||||
}
|
||||
)
|
||||
.ToArray ();
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_File", new MenuItem [] {
|
||||
new MenuBarItem("_Language", languageMenus),
|
||||
null,
|
||||
new MenuItem ("_Quit", "", Quit),
|
||||
}),
|
||||
});
|
||||
Application.Top.Add (menu);
|
||||
|
||||
var selectLanguageLabel = new Label ("Please select a language.") {
|
||||
X = 2,
|
||||
Y = 1,
|
||||
Width = Dim.Fill (2),
|
||||
AutoSize = true
|
||||
};
|
||||
Win.Add (selectLanguageLabel);
|
||||
|
||||
_languageComboBox = new ComboBox (_cultureInfoNameSource) {
|
||||
X = 2,
|
||||
Y = Pos.Bottom (selectLanguageLabel) + 1,
|
||||
Width = _cultureInfoNameSource.Select (cn => cn.Length + 3).Max (),
|
||||
Height = _cultureInfoNameSource.Length + 1,
|
||||
HideDropdownListOnClick = true,
|
||||
AutoSize = true,
|
||||
SelectedItem = _cultureInfoNameSource.Length - 1
|
||||
};
|
||||
_languageComboBox.SelectedItemChanged += LanguageComboBox_SelectChanged;
|
||||
Win.Add (_languageComboBox);
|
||||
|
||||
var textAndFileDialogLabel = new Label ("Right click on the text field to open a context menu, click the button to open a file dialog.\r\nOpen mode will loop through 'File', 'Directory' and 'Mixed' as 'Open' or 'Save' button clicked.") {
|
||||
X = 2,
|
||||
Y = Pos.Top (_languageComboBox) + 3,
|
||||
Width = Dim.Fill (2),
|
||||
AutoSize = true
|
||||
};
|
||||
Win.Add (textAndFileDialogLabel);
|
||||
|
||||
var textField = new TextView {
|
||||
X = 2,
|
||||
Y = Pos.Bottom (textAndFileDialogLabel) + 1,
|
||||
Width = Dim.Fill (32),
|
||||
Height = 1
|
||||
};
|
||||
Win.Add (textField);
|
||||
|
||||
_allowAnyCheckBox = new CheckBox {
|
||||
X = Pos.Right (textField) + 1,
|
||||
Y = Pos.Bottom (textAndFileDialogLabel) + 1,
|
||||
Checked = false,
|
||||
Text = "Allow any"
|
||||
};
|
||||
Win.Add (_allowAnyCheckBox);
|
||||
|
||||
var openDialogButton = new Button ("Open") {
|
||||
X = Pos.Right (_allowAnyCheckBox) + 1,
|
||||
Y = Pos.Bottom (textAndFileDialogLabel) + 1
|
||||
};
|
||||
openDialogButton.Clicked += (sender, e) => ShowFileDialog (false);
|
||||
Win.Add (openDialogButton);
|
||||
|
||||
var saveDialogButton = new Button ("Save") {
|
||||
X = Pos.Right (openDialogButton) + 1,
|
||||
Y = Pos.Bottom (textAndFileDialogLabel) + 1
|
||||
};
|
||||
saveDialogButton.Clicked += (sender, e) => ShowFileDialog (true);
|
||||
Win.Add (saveDialogButton);
|
||||
|
||||
var wizardLabel = new Label ("Click the button to open a wizard.") {
|
||||
X = 2,
|
||||
Y = Pos.Bottom (textField) + 1,
|
||||
Width = Dim.Fill (2),
|
||||
AutoSize = true
|
||||
};
|
||||
Win.Add (wizardLabel);
|
||||
|
||||
var wizardButton = new Button ("Open _wizard") {
|
||||
X = 2,
|
||||
Y = Pos.Bottom (wizardLabel) + 1
|
||||
};
|
||||
wizardButton.Clicked += (sender, e) => ShowWizard ();
|
||||
Win.Add (wizardButton);
|
||||
|
||||
Win.Unloaded += (sender, e) => Quit ();
|
||||
}
|
||||
|
||||
public void SetCulture (CultureInfo culture)
|
||||
{
|
||||
if (_cultureInfoSource [_languageComboBox.SelectedItem] != culture) {
|
||||
_languageComboBox.SelectedItem = Array.IndexOf (_cultureInfoSource, culture);
|
||||
}
|
||||
if (this.CurrentCulture == culture) return;
|
||||
this.CurrentCulture = culture;
|
||||
Thread.CurrentThread.CurrentUICulture = culture;
|
||||
Application.Refresh ();
|
||||
}
|
||||
private void LanguageComboBox_SelectChanged (object sender, ListViewItemEventArgs e)
|
||||
{
|
||||
if (e.Value is string cultureName) {
|
||||
var index = Array.IndexOf (_cultureInfoNameSource, cultureName);
|
||||
if (index >= 0) {
|
||||
SetCulture (_cultureInfoSource [index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ShowFileDialog (bool isSaveFile)
|
||||
{
|
||||
FileDialog dialog = isSaveFile ? new SaveDialog () : new OpenDialog ("", null, _currentOpenMode);
|
||||
dialog.AllowedTypes = new List<IAllowedType> () {
|
||||
(_allowAnyCheckBox.Checked ?? false) ? new AllowedTypeAny() : new AllowedType("Dynamic link library", ".dll"),
|
||||
new AllowedType("Json", ".json"),
|
||||
new AllowedType("Text", ".txt"),
|
||||
new AllowedType("Yaml", ".yml", ".yaml")
|
||||
};
|
||||
dialog.MustExist = !isSaveFile;
|
||||
dialog.AllowsMultipleSelection = !isSaveFile;
|
||||
_currentOpenMode++;
|
||||
if (_currentOpenMode > OpenMode.Mixed) {
|
||||
_currentOpenMode = OpenMode.File;
|
||||
}
|
||||
Application.Run (dialog);
|
||||
}
|
||||
public void ShowWizard ()
|
||||
{
|
||||
Wizard wizard = new Wizard {
|
||||
Height = 8,
|
||||
Width = 36,
|
||||
Title = "The wizard"
|
||||
};
|
||||
wizard.AddStep (new WizardStep () {
|
||||
HelpText = "Wizard first step",
|
||||
});
|
||||
wizard.AddStep (new WizardStep () {
|
||||
HelpText = "Wizard step 2",
|
||||
NextButtonText = ">>> (_N)"
|
||||
});
|
||||
wizard.AddStep (new WizardStep () {
|
||||
HelpText = "Wizard last step"
|
||||
});
|
||||
Application.Run (wizard);
|
||||
}
|
||||
public void Quit ()
|
||||
{
|
||||
SetCulture (CultureInfo.InvariantCulture);
|
||||
Application.RequestStop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,16 +50,21 @@ namespace Terminal.Gui.ViewsTests {
|
||||
Assert.NotNull (cm.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Show_Hide_IsShow ()
|
||||
private ContextMenu Create_ContextMenu_With_Two_MenuItem (int x, int y)
|
||||
{
|
||||
var cm = new ContextMenu (10, 5,
|
||||
return new ContextMenu (x, y,
|
||||
new MenuBarItem (new MenuItem [] {
|
||||
new MenuItem ("One", "", null),
|
||||
new MenuItem ("Two", "", null)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Show_Hide_IsShow ()
|
||||
{
|
||||
var cm = Create_ContextMenu_With_Two_MenuItem (10, 5);
|
||||
|
||||
cm.Show ();
|
||||
Assert.True (ContextMenu.IsShow);
|
||||
@@ -1140,5 +1145,59 @@ namespace Terminal.Gui.ViewsTests {
|
||||
|
||||
Application.End (rs);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void RequestStop_While_ContextMenu_Is_Open_Does_Not_Throws ()
|
||||
{
|
||||
var cm = Create_ContextMenu_With_Two_MenuItem (10, 5);
|
||||
var top = Application.Top;
|
||||
var isMenuAllClosed = false;
|
||||
MenuBarItem mi = null;
|
||||
var iterations = -1;
|
||||
Application.Iteration += () => {
|
||||
iterations++;
|
||||
if (iterations == 0) {
|
||||
cm.Show ();
|
||||
Assert.True (ContextMenu.IsShow);
|
||||
mi = cm.MenuBar.Menus [0];
|
||||
mi.Action = () => {
|
||||
var dialog1 = new Dialog ();
|
||||
Application.Run (dialog1);
|
||||
Assert.False (ContextMenu.IsShow);
|
||||
Assert.True (isMenuAllClosed);
|
||||
};
|
||||
cm.MenuBar.MenuAllClosed += (_, _) => isMenuAllClosed = true;
|
||||
} else if (iterations == 1) {
|
||||
mi.Action ();
|
||||
} else if (iterations == 2) {
|
||||
Application.RequestStop ();
|
||||
} else if (iterations == 3) {
|
||||
isMenuAllClosed = false;
|
||||
cm.Show ();
|
||||
Assert.True (ContextMenu.IsShow);
|
||||
cm.MenuBar.MenuAllClosed += (_, _) => isMenuAllClosed = true;
|
||||
} else if (iterations == 4) {
|
||||
var exception = Record.Exception (() => Application.RequestStop ());
|
||||
Assert.Null (exception);
|
||||
} else {
|
||||
Application.RequestStop ();
|
||||
}
|
||||
};
|
||||
|
||||
var isTopClosed = false;
|
||||
top.Closing += (_, _) => {
|
||||
var dialog2 = new Dialog ();
|
||||
Application.Run (dialog2);
|
||||
Assert.False (ContextMenu.IsShow);
|
||||
Assert.True (isMenuAllClosed);
|
||||
isTopClosed = true;
|
||||
};
|
||||
|
||||
Application.Run ();
|
||||
|
||||
Assert.True (isTopClosed);
|
||||
Assert.False (ContextMenu.IsShow);
|
||||
Assert.True (isMenuAllClosed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -59,6 +60,8 @@ namespace Terminal.Gui.ViewsTests {
|
||||
[Fact]
|
||||
public void KeyBindings_Command ()
|
||||
{
|
||||
CultureInfo cultureBackup = CultureInfo.CurrentCulture;
|
||||
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
DateField df = new DateField (DateTime.Parse ("12/12/1971"));
|
||||
df.ReadOnly = true;
|
||||
Assert.True (df.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ())));
|
||||
@@ -93,6 +96,7 @@ namespace Terminal.Gui.ViewsTests {
|
||||
df.ReadOnly = false;
|
||||
Assert.True (df.ProcessKey (new KeyEvent (Key.D1, new KeyModifiers ())));
|
||||
Assert.Equal (" 12/02/1971", df.Text);
|
||||
CultureInfo.CurrentCulture = cultureBackup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
nuget.config
Normal file
12
nuget.config
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<config>
|
||||
<add key="defaultPushSource" value="https://api.nuget.org/v3/index.json" />
|
||||
</config>
|
||||
<packageSources>
|
||||
|
||||
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
||||
<clear />
|
||||
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user