Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PT Run][New Plugin] Time zone plugin #11431

Merged
merged 70 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
d679b4c
Initial commit - simple idea for a time zone plugin
TobiasSekan May 9, 2021
d8e5c01
Translations, better search results, copy to clipboard, cleanup
TobiasSekan May 24, 2021
8715d99
fix typo
TobiasSekan May 24, 2021
5db4b2d
Add shortcut search and prepare JSON for later usage
TobiasSekan May 29, 2021
b96e83e
Fix typo
TobiasSekan May 30, 2021
b09843b
Use timezone Data only from JSON
Oct 20, 2021
6aa06b4
Exclude json file from spell checker
Oct 21, 2021
08d353d
fix wrong dst
Oct 21, 2021
2455b8c
Improved results (title, subtitle, tooltip) and fix namespace/class p…
Oct 21, 2021
33f2a58
Always show full offset (-##:## and +##:##)
Oct 22, 2021
e698f61
Add and show timezone names (first pass)
Oct 22, 2021
b81262f
Fix typos
Oct 22, 2021
0c8eed1
fix build
Oct 22, 2021
ce63b40
JSON: fix wrong minus sign and put extra country info the end
Oct 22, 2021
c2d8d15
Improved Subtitle for many matched countries and allow full offset se…
Oct 22, 2021
266421c
Allow more than one names for time zones and remove leftover
Oct 27, 2021
70f00df
Add military time zone names, and fix name result
Oct 27, 2021
50dcc5e
Only use one JSON entry for one time zone
Oct 27, 2021
7a4c72a
Use TimeSpan for offset, use build-in calculation for time in time zone
Oct 28, 2021
fb69ce9
add descriptions for JSON schema
Oct 28, 2021
f9a4463
Fix typos
Oct 28, 2021
08cadbd
Split out names in separate properties
Oct 29, 2021
af503f8
Add many time names, time zone names and shortcuts
Oct 29, 2021
7d64e13
Add additional options and most code documentation
Nov 2, 2021
97e0df9
Fix unreadable TimeSpans in JSON and rename helper class
Nov 12, 2021
b090785
Fix not allowed commas in JSON file
Nov 12, 2021
7e3e016
Cut to long time and time zone names in title
Nov 12, 2021
d9b5ac9
Fix missing results for names and offsets
Nov 12, 2021
98deef5
Better result and show only one result when offset are identical (res…
Nov 12, 2021
6d78cea
Show generic name fot time zones without names
TobiasSekan Dec 28, 2021
c54be3a
Typo fixes
TobiasSekan Dec 28, 2021
b8bb367
Fix not working serach by shortcuts
TobiasSekan Dec 30, 2021
26b4844
Fix german resx file -> english resx file
TobiasSekan Dec 30, 2021
3fe4821
Translate all names and countires
TobiasSekan Dec 30, 2021
e06c6b5
Fix not working context menu
TobiasSekan Dec 30, 2021
2a27086
Typo fixes, fix wrong shortcut in names, comments, few better variabl…
TobiasSekan Jan 4, 2022
9794f3e
New symbols - thx to niels9001
TobiasSekan Jan 4, 2022
da6294c
Search by shortcuts for time names
TobiasSekan Jan 4, 2022
1ae4bde
update schema
TobiasSekan Jan 4, 2022
75f9ad0
Add more time zone names and shortcuts (second pass), make spell chec…
TobiasSekan Jan 5, 2022
ac01b25
Reduce matching checks
TobiasSekan Jan 6, 2022
2b8a28b
Show shortcuts in tool-tips, avoid string converting
TobiasSekan Jan 6, 2022
1758687
Show only names that match the query
TobiasSekan Jan 6, 2022
ca6307b
Make all translatable (Part 1)
TobiasSekan Jan 7, 2022
80bb87e
Make all translatable (part 2 of 2)
TobiasSekan Jan 10, 2022
67b2671
XML Doc
TobiasSekan Jan 10, 2022
dc2d781
Fix plugin name (type)
TobiasSekan Jan 10, 2022
edf7f2d
Fix Typos
TobiasSekan Jan 19, 2022
7295a0a
Add TimeZone Plugint to WXS
TobiasSekan Jan 19, 2022
f5228fa
Add TimeZone plugin to sign pipeline
TobiasSekan Jan 19, 2022
5f55714
Add Documentation
TobiasSekan Jan 19, 2022
0b496ab
Remove double spell entries
TobiasSekan Jan 19, 2022
e391be2
Remove TODO leftovers
TobiasSekan Jan 19, 2022
1f10468
Fix for results with no countries
TobiasSekan Jan 27, 2022
54d2f0d
Fix typos
TobiasSekan Jan 27, 2022
3416eed
fix typos
TobiasSekan Jan 27, 2022
b5c2f66
Fix broken siolution after rebase
TobiasSekan Jan 30, 2022
3f2d960
Update target framework to make build happy
TobiasSekan Jan 31, 2022
5809b65
fix wrong guid count in WXS
TobiasSekan Feb 1, 2022
e9062dd
fix wrong output folder (setup wasn’t found files)
TobiasSekan Feb 1, 2022
0e00606
try fix from @jaimecbernardo
TobiasSekan Feb 8, 2022
bdda556
Address feedback from @jsoref - fix spell check
TobiasSekan Feb 8, 2022
660820c
typo fix - one leftover in expect.txt
TobiasSekan Feb 8, 2022
ce97467
Switch to .NET6 and update dokumentation
TobiasSekan Feb 11, 2022
34098be
Address feedbacks, and fix search bug
TobiasSekan Feb 21, 2022
4b2c167
Merge branch 'main' into TimeZonePlugin
TobiasSekan Feb 21, 2022
1c3543d
fix installer build error
jaimecbernardo Feb 22, 2022
3b147b8
fix spellchecker
jaimecbernardo Feb 22, 2022
dd31377
Merge pull request #2 from jaimecbernardo/pr11431-fix-gh-errors
TobiasSekan Feb 23, 2022
cb26b1c
Address feedback from @htcfreek
TobiasSekan Feb 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Translations, better search results, copy to clipboard, cleanup
  • Loading branch information
TobiasSekan committed Jan 27, 2022
commit d8e5c018575658ca8499ad665ee9e6264e24b843
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Microsoft.PowerToys.Run.Plugin.TimeZone.Properties;
using Wox.Plugin;
using Wox.Plugin.Logger;

namespace Microsoft.PowerToys.Run.Plugin.TimeZone.Helper
{
/// <summary>
/// Helper class to easier work with context menu entries
/// </summary>
internal static class ContextMenuHelper
{
/// <summary>
/// Return a list with all context menu entries for the given <see cref="Result"/>
/// <para>Symbols taken from <see href="https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font"/></para>
/// </summary>
/// <param name="result">The result for the context menu entires</param>
/// <param name="assemblyName">The name of the this assembly</param>
/// <returns>A list with context menu entries</returns>
internal static List<ContextMenuResult> GetContextMenu(Result result, string assemblyName)
{
if (!(result?.ContextData is TimeZoneInfo timeZoneInfo))
{
return new List<ContextMenuResult>(0);
}

var list = new List<ContextMenuResult>
{
new ContextMenuResult
{
AcceleratorKey = Key.C,
AcceleratorModifiers = ModifierKeys.Control,
Action = _ => TryToCopyToClipBoard(GetTimeInTimeZone(timeZoneInfo)),
FontFamily = "Segoe MDL2 Assets",
Glyph = "\xE8C8", // E8C8 => Symbol: Copy
PluginName = assemblyName,
Title = $"{Resources.CopyTime} (Ctrl+C)",
},
};

return list;
}

/// <summary>
/// Return a human readable time of the current time in the given <see cref="TimeZoneInfo"/>.
/// </summary>
/// <param name="timeZoneInfo">The <see cref="TimeZoneInfo"/> to calculate the current time in it.</param>
/// <returns>A human readable time.</returns>
private static string GetTimeInTimeZone(TimeZoneInfo timeZoneInfo)
{
var timeInTimeZone = TimeZoneInfo.ConvertTime(DateTime.UtcNow, timeZoneInfo);
var stringToCopy = $"{timeInTimeZone:HH:mm:ss}";
return stringToCopy;
}

#pragma warning disable CA1031 // Do not catch general exception types

/// <summary>
/// Copy the given text to the clipboard
/// </summary>
/// <param name="text">The text to copy to the clipboard</param>
/// <returns><see langword="true"/>The text successful copy to the clipboard, otherwise <see langword="false"/></returns>
private static bool TryToCopyToClipBoard(in string text)
{
try
{
Clipboard.Clear();
Clipboard.SetText(text);
return true;
}
catch (Exception exception)
{
Log.Exception("Can't copy to clipboard", exception, typeof(Main));
return false;
}
}

#pragma warning restore CA1031 // Do not catch general exception types
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.PowerToys.Run.Plugin.TimeZone.Properties;
using Mono.Collections.Generic;
using Wox.Plugin;

namespace Microsoft.PowerToys.Run.Plugin.TimeZone.Helper
{
/// <summary>
/// Helper class to easier work with results
/// </summary>
internal static class ResultHelper
{
/// <summary>
/// Return a list of <see cref="Result"/>s based on the given <see cref="Query"/>.
/// </summary>
/// <param name="query">The <see cref="Query"/> to filter the <see cref="Results"/>.</param>
/// <returns>A list with <see cref="Result"/>s.</returns>
internal static IEnumerable<Result> GetResults(Query query, string iconPath)
{
var searchFor = GetSerchString(query);
var timeZoneInfos = TimeZoneInfo.GetSystemTimeZones();
var results = new Collection<Result>();
var utcNow = DateTime.UtcNow;

foreach (var timeZoneInfo in timeZoneInfos)
{
if (TimeZoneInfoMatchQuery(timeZoneInfo, searchFor))
{
var result = GetResult(timeZoneInfo, utcNow, iconPath);
results.Add(result);
}
}

var orderResults = results.OrderBy(result => result.Title);
return orderResults;
}

/// <summary>
/// Return the string to search, based on the given <see cref="Query"/>.
/// </summary>
/// <param name="query">The <see cref="Query"/> that contain the string to search.</param>
/// <returns>A string for a search.</returns>
private static string GetSerchString(Query query)
{
var secondChar = query.Search.ElementAtOrDefault(1);

if (secondChar == '0')
{
return query.Search;
}

if (!char.IsDigit(secondChar))
{
return query.Search;
}

// Allow the user to direct search for "+9", instead of "+09".
var searchFor = query.Search;

if (query.Search.StartsWith('+'))
{
searchFor = "+0" + query.Search.Substring(1);
}

if (query.Search.StartsWith('-'))
{
searchFor = "-0" + query.Search.Substring(1);
}

return searchFor;
}

/// <summary>
/// Check if the given <see cref="TimeZoneInfo"/> contains a value that match the given <see cref="string"/> .
/// </summary>
/// <param name="timeZoneInfo">The <see cref="TimeZoneInfo"/> to check.</param>
/// <param name="searchFor">The <see cref="string"/> that should match.</param>
/// <returns><see langword="true"/> if it's match, otherwise <see langword="false"/>.</returns>
private static bool TimeZoneInfoMatchQuery(TimeZoneInfo timeZoneInfo, string searchFor)
{
if (timeZoneInfo.DisplayName.Contains(searchFor, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}

if (timeZoneInfo.StandardName.Contains(searchFor, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}

if (timeZoneInfo.DaylightName.Contains(searchFor, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}

return false;
}

/// <summary>
/// Return a <see cref="Result"/> based on the given <see cref="TimeZoneInfo"/>.
/// </summary>
/// <param name="timeZoneInfo">The <see cref="TimeZoneInfo"/> that contain the information for the <see cref="Result"/>.</param>
/// <param name="utcNow">The current time in UTC for the <see cref="Result"/>.</param>
/// <returns>A <see cref="Result"/>.</returns>
private static Result GetResult(TimeZoneInfo timeZoneInfo, DateTime utcNow, string iconPath)
{
var title = GetTitle(timeZoneInfo, utcNow);
var timeInTimeZone = TimeZoneInfo.ConvertTime(utcNow, timeZoneInfo);

var toolTip = $"{Resources.StandardName}: {timeZoneInfo.StandardName}"
+ $"{Environment.NewLine}{Resources.DaylightName}: {timeZoneInfo.DaylightName}"
+ $"{Environment.NewLine}{Resources.DisplayName}: {timeZoneInfo.DisplayName}"
+ $"{Environment.NewLine}{Resources.Offset}: {timeZoneInfo.BaseUtcOffset}";

var result = new Result
{
ContextData = timeZoneInfo,
IcoPath = iconPath,
SubTitle = $"{Resources.CurrentTime}: {timeInTimeZone:HH:mm:ss}",
Title = title,
ToolTipData = new ToolTipData(title, toolTip),
};

return result;
}

/// <summary>
/// Return the title for a <see cref="Result"/> and <see cref="ToolTipData"/>
/// </summary>
/// <param name="timeZoneInfo">The <see cref="TimeZoneInfo"/> for the title.</param>
/// <param name="utcNow">The current time in UTC, only need for time zones that support daylight time.</param>
/// <returns>A title for a <see cref="Result"/> or <see cref="ToolTipData"/>.</returns>
private static string GetTitle(TimeZoneInfo timeZoneInfo, DateTime utcNow)
{
if (!timeZoneInfo.SupportsDaylightSavingTime)
{
return timeZoneInfo.StandardName;
}

if (!timeZoneInfo.IsDaylightSavingTime(utcNow))
{
return timeZoneInfo.StandardName;
}

return timeZoneInfo.DaylightName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
using System.Linq;
using System.Reflection;
using ManagedCommon;
using Microsoft.PowerToys.Run.Plugin.TimeZone.Helper;
using Microsoft.PowerToys.Run.Plugin.TimeZone.Properties;
using Wox.Plugin;

namespace Microsoft.PowerToys.Run.Plugin.TimeZone
{
public class Main : IPlugin, IPluginI18n, IDisposable
public class Main : IPlugin, IContextMenu, IPluginI18n, IDisposable
{
/// <summary>
/// The name of this assembly
Expand Down Expand Up @@ -70,35 +71,18 @@ public List<Result> Query(Query query)
return new List<Result>(0);
}

var timeZones = TimeZoneInfo.GetSystemTimeZones();
var results = new List<Result>(timeZones.Count);
var utcNow = DateTime.UtcNow;

foreach (var timeZone in timeZones)
{
if (!timeZone.DaylightName.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase)
&& !timeZone.DaylightName.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}

var title = timeZone.SupportsDaylightSavingTime && timeZone.IsDaylightSavingTime(utcNow)
? timeZone.DaylightName
: timeZone.StandardName;

var timeInTimeZone = TimeZoneInfo.ConvertTime(utcNow, timeZone);

var result = new Result
{
Title = title,
SubTitle = $"Time: {timeInTimeZone:HH:mm:ss}",
ToolTipData = new ToolTipData(title, $"Offset: {timeZone.BaseUtcOffset}"),
};

results.Add(result);
}
var results = ResultHelper.GetResults(query, _defaultIconPath).ToList();
return results;
}

return results.OrderBy(result => result.Title).ToList();
/// <summary>
/// Return a list context menu entries for a given <see cref="Result"/> (shown at the right side of the result)
/// </summary>
/// <param name="selectedResult">The <see cref="Result"/> for the list with context menu entries</param>
/// <returns>A list context menu entries</returns>
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return ContextMenuHelper.GetContextMenu(selectedResult, _assemblyName);
}

/// <summary>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading