fix #151 Add context menu for programs

This commit is contained in:
qianlifeng 2014-10-24 13:09:51 +08:00
parent c61db8c957
commit f399ef8f69
13 changed files with 76 additions and 22 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

View File

@ -92,7 +92,7 @@ namespace Wox.Plugin.FindFile
} }
return true; return true;
}, },
IcoPath = "Images/edit.png" IcoPath = "Images/open.png"
}); });
if (!record.IsFolder) if (!record.IsFolder)

View File

@ -54,9 +54,6 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Images\edit.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\find.png"> <Content Include="Images\find.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@ -66,6 +63,9 @@
<Content Include="Images\file.png"> <Content Include="Images\file.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Images\open.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\warning.png"> <Content Include="Images\warning.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>

View File

@ -78,7 +78,7 @@ namespace Wox.Infrastructure
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
static extern bool UrlIs(string pszUrl, int UrlIs); static extern bool UrlIs(string pszUrl, int UrlIs);
static void ShellExecCmdLine(IntPtr hInstance, IntPtr hwnd, string command, string startDir, global::System.Diagnostics.ProcessWindowStyle nShow, ShellExecCmdLineFlags dwSeclFlags) static void ShellExecCmdLine(IntPtr hInstance, IntPtr hwnd, string command, string startDir, global::System.Diagnostics.ProcessWindowStyle nShow, ShellExecCmdLineFlags dwSeclFlags,bool runAsAdministrator = false)
{ {
string cmd = command; string cmd = command;
string args = null; string args = null;
@ -143,6 +143,7 @@ namespace Wox.Infrastructure
startInfo.UseShellExecute = true; startInfo.UseShellExecute = true;
startInfo.Arguments = args; startInfo.Arguments = args;
startInfo.FileName = cmd; startInfo.FileName = cmd;
if (runAsAdministrator) startInfo.Verb = "runas";
startInfo.WindowStyle = global::System.Diagnostics.ProcessWindowStyle.Normal; startInfo.WindowStyle = global::System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.ErrorDialog = (dwSeclFlags | ShellExecCmdLineFlags.SECL_NO_UI) == 0; startInfo.ErrorDialog = (dwSeclFlags | ShellExecCmdLineFlags.SECL_NO_UI) == 0;
startInfo.ErrorDialogParentHandle = hwnd; startInfo.ErrorDialogParentHandle = hwnd;
@ -280,17 +281,12 @@ namespace Wox.Infrastructure
hresult); hresult);
} }
public static void Start(string cmd) public static void Start(string cmd, bool runAsAdministrator = false)
{ {
Start(cmd, false); Start(cmd, false, IntPtr.Zero,runAsAdministrator);
} }
public static void Start(string cmd, bool showErrorDialog) public static void Start(string cmd, bool showErrorDialog, IntPtr errorDialogHwnd, bool runAsAdministrator = false)
{
Start(cmd, false, IntPtr.Zero);
}
public static void Start(string cmd, bool showErrorDialog, IntPtr errorDialogHwnd)
{ {
cmd = cmd.Trim(); // PathRemoveBlanks cmd = cmd.Trim(); // PathRemoveBlanks
cmd = Environment.ExpandEnvironmentVariables(cmd); // SHExpandEnvironmentStrings cmd = Environment.ExpandEnvironmentVariables(cmd); // SHExpandEnvironmentStrings
@ -306,7 +302,8 @@ namespace Wox.Infrastructure
cmd, cmd,
null, // i have no ideas about this field null, // i have no ideas about this field
global::System.Diagnostics.ProcessWindowStyle.Normal, global::System.Diagnostics.ProcessWindowStyle.Normal,
ShellExecCmdLineFlags.SECL__IGNORE_ERROR | ShellExecCmdLineFlags.SECL_USE_IDLIST | ShellExecCmdLineFlags.SECL_LOG_USAGE | (showErrorDialog ? 0 : ShellExecCmdLineFlags.SECL_NO_UI) ShellExecCmdLineFlags.SECL__IGNORE_ERROR | ShellExecCmdLineFlags.SECL_USE_IDLIST | ShellExecCmdLineFlags.SECL_LOG_USAGE | (showErrorDialog ? 0 : ShellExecCmdLineFlags.SECL_NO_UI),
runAsAdministrator
); );
if (!string.IsNullOrEmpty(home) && Directory.Exists(home)) Environment.CurrentDirectory = oldCwd; if (!string.IsNullOrEmpty(home) && Directory.Exists(home)) Environment.CurrentDirectory = oldCwd;
} }

View File

@ -42,6 +42,31 @@ namespace Wox.Plugin.SystemPlugins.Program
context.API.HideApp(); context.API.HideApp();
context.API.ShellRun(c.ExecutePath); context.API.ShellRun(c.ExecutePath);
return true; return true;
},
ContextMenu = new List<Result>()
{
new Result()
{
Title = "Open",
Action = _ =>
{
context.API.HideApp();
context.API.ShellRun(c.ExecutePath);
return true;
},
IcoPath = "Images/open.png"
},
new Result()
{
Title = "Open With Administrator",
Action = _ =>
{
context.API.HideApp();
context.API.ShellRun(c.ExecutePath,true);
return true;
},
IcoPath = "Images/cmd.png"
}
} }
}).ToList(); }).ToList();
} }
@ -84,11 +109,11 @@ namespace Wox.Plugin.SystemPlugins.Program
Type sourceClass; Type sourceClass;
if (SourceTypes.TryGetValue(source.Type, out sourceClass)) if (SourceTypes.TryGetValue(source.Type, out sourceClass))
{ {
ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] {typeof (ProgramSource)}); ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) });
if (constructorInfo != null) if (constructorInfo != null)
{ {
IProgramSource programSource = IProgramSource programSource =
constructorInfo.Invoke(new object[] {source}) as IProgramSource; constructorInfo.Invoke(new object[] { source }) as IProgramSource;
sources.Add(programSource); sources.Add(programSource);
} }
} }
@ -106,7 +131,7 @@ namespace Wox.Plugin.SystemPlugins.Program
} }
// filter duplicate program // filter duplicate program
tempPrograms = tempPrograms.GroupBy(x => new {x.ExecutePath, x.ExecuteName}) tempPrograms = tempPrograms.GroupBy(x => new { x.ExecutePath, x.ExecuteName })
.Select(g => g.First()).ToList(); .Select(g => g.First()).ToList();
programs = tempPrograms; programs = tempPrograms;

View File

@ -9,7 +9,7 @@ namespace Wox.Plugin
void PushResults(Query query,PluginMetadata plugin, List<Result> results); void PushResults(Query query,PluginMetadata plugin, List<Result> results);
bool ShellRun(string cmd); bool ShellRun(string cmd, bool runAsAdministrator = false);
void ChangeQuery(string query, bool requery = false); void ChangeQuery(string query, bool requery = false);

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Windows; using System.Windows;
using Wox.Plugin;
namespace Wox.Converters namespace Wox.Converters
{ {
@ -21,4 +23,23 @@ namespace Wox.Converters
return this; return this;
} }
} }
public class ContextMenuEmptyToWidthConverter : ConvertorBase<ContextMenuEmptyToWidthConverter>
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
List<Result> results = value as List<Result>;
return results == null || results.Count == 0 ? 0 : 17;
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
} }

BIN
Wox/Images/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

BIN
Wox/Images/open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

View File

@ -720,14 +720,14 @@ namespace Wox
this.Opacity = this.AllowsTransparency ? UserSettingStorage.Instance.Opacity : 1; this.Opacity = this.AllowsTransparency ? UserSettingStorage.Instance.Opacity : 1;
} }
public bool ShellRun(string cmd) public bool ShellRun(string cmd, bool runAsAdministrator = false)
{ {
try try
{ {
if (string.IsNullOrEmpty(cmd)) if (string.IsNullOrEmpty(cmd))
throw new ArgumentNullException(); throw new ArgumentNullException();
Wox.Infrastructure.WindowsShellRun.Start(cmd); WindowsShellRun.Start(cmd, runAsAdministrator);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)

View File

@ -7,7 +7,7 @@
mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100"> mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100">
<!-- set max height of listbox to allow 6 results showed at once --> <!-- set max height of listbox to allow 6 results showed at once -->
<ListBox x:Name="lbResults" MaxHeight="300" PreviewMouseDown="LbResults_OnPreviewMouseDown" Style="{DynamicResource BaseListboxStyle}" SelectionChanged ="lbResults_SelectionChanged" Focusable="False" KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard"> <ListBox x:Name="lbResults" MaxHeight="300" HorizontalContentAlignment="Stretch" PreviewMouseDown="LbResults_OnPreviewMouseDown" Style="{DynamicResource BaseListboxStyle}" SelectionChanged ="lbResults_SelectionChanged" Focusable="False" KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard">
<ListBox.Resources> <ListBox.Resources>
<!--SelectedItem with focus--> <!--SelectedItem with focus-->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource ItemSelectedBackgroundColor}"/> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource ItemSelectedBackgroundColor}"/>
@ -24,6 +24,7 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="32"></ColumnDefinition> <ColumnDefinition Width="32"></ColumnDefinition>
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition x:Name="contextMenuDefinition" Width="0"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" Source="{Binding FullIcoPath,Converter={StaticResource ImageConverter},IsAsync=True}" > <Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" Source="{Binding FullIcoPath,Converter={StaticResource ImageConverter},IsAsync=True}" >
</Image> </Image>
@ -32,14 +33,16 @@
<RowDefinition></RowDefinition> <RowDefinition></RowDefinition>
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition> <RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Style="{DynamicResource ItemTitleStyle}" VerticalAlignment="Center" ToolTip="{Binding Title}" x:Name="tbTitle" Text="{Binding Title}"></TextBlock> <TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left" VerticalAlignment="Center" ToolTip="{Binding Title}" x:Name="tbTitle" Text="{Binding Title}"></TextBlock>
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding SubTitle}" Visibility="{Binding SubTitle, Converter={converters:StringNullOrEmptyToVisibilityConverter}}" Grid.Row="1" x:Name="tbSubTitle" Text="{Binding SubTitle}"></TextBlock> <TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding SubTitle}" Visibility="{Binding SubTitle, Converter={converters:StringNullOrEmptyToVisibilityConverter}}" Grid.Row="1" x:Name="tbSubTitle" Text="{Binding SubTitle}"></TextBlock>
</Grid> </Grid>
<Image Grid.Column="2" VerticalAlignment="Center" Margin="5 0 0 0" Width="12" x:Name="contextMenu" Source="Images/menu.png" ToolTip="Shift + Enter to open context menu"></Image>
</Grid> </Grid>
<DataTemplate.Triggers> <DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True"> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="tbTitle" Property="Style" Value="{DynamicResource ItemTitleSelectedStyle}"/> <Setter TargetName="tbTitle" Property="Style" Value="{DynamicResource ItemTitleSelectedStyle}"/>
<Setter TargetName="tbSubTitle" Property="Style" Value="{DynamicResource ItemSubTitleSelectedStyle}"/> <Setter TargetName="tbSubTitle" Property="Style" Value="{DynamicResource ItemSubTitleSelectedStyle}"/>
<Setter TargetName="contextMenuDefinition" Property="Width" Value="{Binding ContextMenu, Converter={converters:ContextMenuEmptyToWidthConverter}}"/>
</DataTrigger> </DataTrigger>
</DataTemplate.Triggers> </DataTemplate.Triggers>
</DataTemplate> </DataTemplate>

View File

@ -392,6 +392,14 @@
<Resource Include="Images\restart.png" /> <Resource Include="Images\restart.png" />
<Resource Include="Images\web_search.png" /> <Resource Include="Images\web_search.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Resource Include="Images\menu.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<Resource Include="Images\open.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<PropertyGroup> <PropertyGroup>