Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions Quick Link/CustomApplicationContext.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using QuickLink.Properties;
using System;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Windows.Forms;

namespace QuickLink
{
[SupportedOSPlatform("windows")]
class CustomApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
Expand All @@ -27,11 +29,10 @@ public CustomApplicationContext()
}
},
Visible = true,

};
trayIcon.MouseClick += new MouseEventHandler(OnLeftClick);

hotkey.KeyPressed += new EventHandler<KeyPressedEventArgs>((object sender, KeyPressedEventArgs e) => ShowQuickInputForm());
hotkey.KeyPressed += (sender, e) => ShowQuickInputForm();
hotkey.RegisterHotKey(ModifierKeys.Control | ModifierKeys.Win, Keys.R);
}

Expand Down
4 changes: 3 additions & 1 deletion Quick Link/GlobalKeyboardHotkey.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Windows.Forms;

namespace QuickLink
{
[SupportedOSPlatform("windows")]
public sealed class GlobalKeyboardHotkey : IDisposable
{
// Registers a hot key with Windows.
Expand Down Expand Up @@ -65,7 +67,7 @@ public void Dispose()
public GlobalKeyboardHotkey()
{
// register the event of the inner native window.
_window.KeyPressed += delegate (object sender, KeyPressedEventArgs args)
_window.KeyPressed += (sender, args) =>
{
if (KeyPressed != null)
KeyPressed(this, args);
Expand Down
4 changes: 2 additions & 2 deletions Quick Link/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace QuickLink
{
internal static class Program
{
static Mutex mutex = new Mutex(true, "{6d5a148c-92e2-42ee-bf0e-f8cc887619fd}");
private static readonly Mutex mutex = new Mutex(true, "{6d5a148c-92e2-42ee-bf0e-f8cc887619fd}");

[STAThread]
static void Main()
{
Expand All @@ -22,7 +23,6 @@ static void Main()
{
MessageBox.Show("Quick Link is already running.");
}

}
}
}
6 changes: 5 additions & 1 deletion Quick Link/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
Expand All @@ -10,10 +11,13 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Benjamin Knoop")]
[assembly: AssemblyProduct("Quick Link")]
[assembly: AssemblyCopyright("Copyright © 2024, 2025")]
[assembly: AssemblyCopyright("Copyright © 2024-2026, Benjamin Knoop")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Diese Assembly ist Windows-spezifisch; reduziert CA1416-Warnungen für Windows-APIs.
[assembly: SupportedOSPlatform("windows")]

// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
Expand Down
124 changes: 15 additions & 109 deletions Quick Link/Quick Link.csproj
Original file line number Diff line number Diff line change
@@ -1,128 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EF4B0D54-A24D-4E76-AB9D-40DB857AC8DE}</ProjectGuid>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<RootNamespace>QuickLink</RootNamespace>
<AssemblyName>QuickLink</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject>QuickLink.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>SpiraPlan-FavIcon.ico</ApplicationIcon>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Use SDK default items for compile and embedded resources -->
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>true</EnableDefaultEmbeddedResourceItems>
<!-- Keep custom AssemblyInfo and don't auto-generate assembly attributes -->
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

<!-- Let SDK implicitly include all .cs files and embedded resources in the project directory -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CustomApplicationContext.cs" />
<Compile Include="GlobalKeyboardHotkey.cs" />
<Compile Include="QuickInputForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="QuickInputForm.Designer.cs">
<DependentUpon>QuickInputForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="QuickInputForm.resx">
<DependentUpon>QuickInputForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="Properties\Settings.settings" Generator="SettingsSingleFileGenerator" LastGenOutput="Settings.Designer.cs" />
<None Include="App.config" />
</ItemGroup>

<ItemGroup>
<None Include="artifact-Requirement.png" />
<None Include="artifact-Incident.png" />
<None Include="app-icon-SpiraPlan-192x192.png" />
<None Include="artifact-TestCase.png" />
<Content Include="SpiraPlan-FavIcon.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 und x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

</Project>
32 changes: 28 additions & 4 deletions Quick Link/QuickInputForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
using System.Windows.Forms;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Runtime.Versioning;
using QuickLink.Properties;

namespace QuickLink
{
[SupportedOSPlatform("windows")]
public partial class QuickInputForm : Form
{
private const int CP_NOCLOSE_BUTTON = 0x200;
Expand All @@ -16,11 +18,11 @@ private enum TicketType { REQUIREMENT, INCIDENT, TESTCASE };
public QuickInputForm()
{
InitializeComponent();
this.Deactivate += new System.EventHandler((object sender, EventArgs e) => Hide());
this.KeyDown += new KeyEventHandler(OnEnterPressed);
TopMost = true;
Deactivate += (sender, e) => Hide();
KeyDown += new KeyEventHandler(OnEnterPressed);
TextBox.KeyDown += new KeyEventHandler(OnEnterPressed);
TextBox.Select();
this.TopMost = true;
}

public void ShowAndInitialize()
Expand Down Expand Up @@ -168,8 +170,30 @@ private void OpenTicket(string validatedTicketString)
}
string url = CreateSpiraUrl(ticketType, "1011", number);
Console.WriteLine("Opening {0}", url);
Process.Start(url);
OpenUrl(url);
}

private void OpenUrl(string url)
{
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
Console.WriteLine("Invalid URL: " + url);
return;
}

try
{
var psi = new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
};
Process.Start(psi);
}
catch (Exception ex)
{
Console.WriteLine("Error opening URL: " + ex.Message);
}
}
}
}