added possibility to edit language properties and to create new language files. also some cosmetics, e.g. icons

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1859 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
JKlingen 2012-05-17 09:54:51 +00:00
parent 608ab69082
commit 3e371d5d03
9 changed files with 770 additions and 466 deletions

View file

@ -1,7 +1,7 @@
<Application x:Class="GreenshotLanguageEditor.App" <Application x:Class="GreenshotLanguageEditor.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"> StartupUri="EntriesEditorWindow.xaml">
<Application.Resources> <Application.Resources>
</Application.Resources> </Application.Resources>

View file

@ -1,151 +1,229 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Window <Window
x:Class="GreenshotLanguageEditor.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="GreenshotLanguageEditor.EntriesEditorWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Width="850"
Height="600" Height="600"
Title="Greenshot Language Editor" Title="Greenshot Language Editor"
Icon="icons\icon.ico"> Icon="icons\icon.ico">
<Grid <Grid
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Height="Auto"> Height="Auto">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition <ColumnDefinition
Width="250" /> Width="250" />
<ColumnDefinition <ColumnDefinition
Width="50*" /> Width="50*" />
<ColumnDefinition <ColumnDefinition
Width="50*" /> Width="50*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition <RowDefinition
Height="Auto" /> Height="Auto" />
<RowDefinition <RowDefinition
Height="*" /> Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"
Orientation="Horizontal"> Orientation="Horizontal">
<ComboBox <ComboBox
Grid.Column="0" Grid.Column="0"
Grid.Row="0" Grid.Row="0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Margin="8,8,0,0" Name="language1ComboBox"
Height="20" SelectionChanged="languageComboBoxSelectionChanged"
Name="language1ComboBox" Tag="1"
SelectionChanged="languageComboBoxSelectionChanged" Width="150"
Tag="1" ItemsSource="{Binding LanguageFiles, Mode=OneWay}"
Width="150" DisplayMemberPath="FileName"
ItemsSource="{Binding LanguageFiles}" SelectedItem="{Binding LanguageFile1, Mode=OneWay}"
DisplayMemberPath="FileName" Margin="5,5,5,5"
SelectedItem="{Binding LanguageFile1, Mode=OneWay}"></ComboBox> Height="26"></ComboBox>
<Button <Button
Content="Save" Click="metaButtonClicked"
Click="saveButtonClicked" Tag="1"
Tag="1"></Button> ToolTip="Edit language properties"
<Button Width="26"
Content="Reset" Height="26"
Click="cancelButtonClicked" Margin="0,5,5,5">
Tag="1" /> <Image
</StackPanel> Source="icons\property.png"
<StackPanel Width="16"
Grid.Row="0" Height="16" />
Grid.Column="2" </Button>
Orientation="Horizontal"> <Button
<ComboBox Click="saveButtonClicked"
Grid.Column="0" Tag="1"
Grid.Row="0" ToolTip="Save to file"
HorizontalAlignment="Left" Width="26"
VerticalAlignment="Top" Height="26"
Margin="8,8,0,0" Margin="0,5,5,5">
Height="20" <Image
Name="language2ComboBox" Width="16"
SelectionChanged="languageComboBoxSelectionChanged" Height="16"
Tag="2" Source="icons\disk-black.png" />
Width="150" </Button>
ItemsSource="{Binding LanguageFiles}" <Button
DisplayMemberPath="FileName" Click="cancelButtonClicked"
SelectedItem="{Binding LanguageFile2, Mode=OneWay}"></ComboBox> Tag="1"
<Button ToolTip="Reset (reload from file)"
Content="Save" Width="26"
Click="saveButtonClicked" Height="26"
Tag="2" /> Margin="0,5,5,5">
<Button <Image
Content="Reset" Source="icons\cross.png"
Click="cancelButtonClicked" Width="16"
Tag="2" /> Height="16" />
</StackPanel> </Button>
<DataGrid <Button
Grid.Row="1" Click="newButtonClicked"
Grid.Column="0" Tag="1"
Grid.ColumnSpan="3" ToolTip="Create new file"
Name="LanguageGrid" Width="26"
ItemsSource="{Binding View}" Height="26"
AutoGenerateColumns="False" Margin="0,5,5,5">
IsReadOnly="False" <Image
IsSynchronizedWithCurrentItem="True" Source="icons\new.png"
CellEditEnding="cellEdited"> Width="16"
<DataGrid.RowStyle> Height="16" />
<Style </Button>
TargetType="DataGridRow"> </StackPanel>
<Style.Setters> <StackPanel
<Setter Grid.Row="0"
Property="Background" Grid.Column="2"
Value="{Binding Path=Background}"></Setter> Orientation="Horizontal">
</Style.Setters> <ComboBox
</Style> Grid.Column="0"
</DataGrid.RowStyle> Grid.Row="0"
<DataGrid.Columns> HorizontalAlignment="Left"
<DataGridTextColumn VerticalAlignment="Top"
Header="Key" Name="language2ComboBox"
Binding="{Binding Key}" SelectionChanged="languageComboBoxSelectionChanged"
Width="250" /> Tag="2"
<DataGridTextColumn Width="150"
Header="Language1" ItemsSource="{Binding LanguageFiles, Mode=OneWay}"
Binding="{Binding Entry1}" DisplayMemberPath="FileName"
Width="*"> SelectedItem="{Binding LanguageFile2, Mode=OneWay}"
<DataGridTextColumn.EditingElementStyle> Margin="5,5,5,5"
<Style Height="26"></ComboBox>
TargetType="TextBox"> <Button
<Setter Click="metaButtonClicked"
Property="ScrollViewer.HorizontalScrollBarVisibility" Tag="2"
Value="Auto" /> ToolTip="Edit language properties"
<Setter Width="26"
Property="ScrollViewer.VerticalScrollBarVisibility" Height="26"
Value="Auto" /> Margin="0,5,5,5">
<Setter <Image
Property="MaxHeight" Source="icons\property.png"
Value="300" /> Width="16"
<Setter Height="16" />
Property="AcceptsReturn" </Button>
Value="true" /> <Button
</Style> Click="saveButtonClicked"
</DataGridTextColumn.EditingElementStyle> Tag="2"
</DataGridTextColumn> Width="26"
<DataGridTextColumn Height="26"
Header="Language2" Margin="0,5,5,5">
Binding="{Binding Entry2}" <Image
Width="*"> Source="icons\disk-black.png"
<DataGridTextColumn.EditingElementStyle> Width="16"
<Style Height="16" />
TargetType="TextBox"> </Button>
<Setter <Button
Property="ScrollViewer.HorizontalScrollBarVisibility" Click="cancelButtonClicked"
Value="Auto" /> Tag="2"
<Setter Width="26"
Property="ScrollViewer.VerticalScrollBarVisibility" Height="26"
Value="Auto" /> Margin="0,5,5,5">
<Setter <Image
Property="MaxHeight" Source="icons\cross.png"
Value="300" /> Width="16"
<Setter Height="16" />
Property="AcceptsReturn" </Button>
Value="true" /> <Button
</Style> Click="newButtonClicked"
</DataGridTextColumn.EditingElementStyle> Tag="2"
</DataGridTextColumn> ToolTip="Create new file"
</DataGrid.Columns> Width="26"
</DataGrid> Height="26"
</Grid> Margin="0,5,5,5">
<Image
Source="icons\new.png"
Width="16"
Height="16" />
</Button>
</StackPanel>
<DataGrid
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Name="LanguageGrid"
ItemsSource="{Binding View}"
AutoGenerateColumns="False"
IsReadOnly="False"
IsSynchronizedWithCurrentItem="True"
CellEditEnding="cellEdited">
<DataGrid.RowStyle>
<Style
TargetType="DataGridRow">
<Style.Setters>
<Setter
Property="Background"
Value="{Binding Path=Background}"></Setter>
</Style.Setters>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn
Header="Key"
Binding="{Binding Key}"
Width="250" />
<DataGridTextColumn
Header="Language1"
Binding="{Binding Entry1}"
Width="*">
<DataGridTextColumn.EditingElementStyle>
<Style
TargetType="TextBox">
<Setter
Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Auto" />
<Setter
Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Auto" />
<Setter
Property="MaxHeight"
Value="300" />
<Setter
Property="AcceptsReturn"
Value="true" />
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<DataGridTextColumn
Header="Language2"
Binding="{Binding Entry2}"
Width="*">
<DataGridTextColumn.EditingElementStyle>
<Style
TargetType="TextBox">
<Setter
Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Auto" />
<Setter
Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Auto" />
<Setter
Property="MaxHeight"
Value="300" />
<Setter
Property="AcceptsReturn"
Value="true" />
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window> </Window>

View file

@ -1,309 +1,347 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: http://getgreenshot.org/ * For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Linq;
using System.Windows; using System.Text;
using System.Windows.Controls; using System.Windows;
using System.Windows.Data; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Input;
using System.ComponentModel; using System.Windows.Media;
using System.Xml; using System.Collections.ObjectModel;
using System.ComponentModel;
namespace GreenshotLanguageEditor { using System.Text.RegularExpressions;
/// <summary> using System.Xml;
/// Interaction logic for Window1.xaml
/// </summary> namespace GreenshotLanguageEditor {
public partial class Window1 : Window { /// <summary>
/// Interaction logic for EntriesEditorWindow.xaml
IDictionary<string, LanguageEntry> languageResources = new SortedDictionary<string, LanguageEntry>(); /// </summary>
public IList<LanguageFile> LanguageFiles { public partial class EntriesEditorWindow : Window, INotifyPropertyChanged {
get;
set; private string languagePath;
} IDictionary<string, LanguageEntry> languageResources = new SortedDictionary<string, LanguageEntry>();
// maybe refactor this encapsulating column related info
bool unsavedChangesInLanguage1 = false; IList<LanguageFile> languageFiles;
bool unsavedChangesInLanguage2 = false; public IList<LanguageFile> LanguageFiles {
public LanguageFile LanguageFile1 { get {return languageFiles;}
get; set {languageFiles = value; NotifyPropertyChanged("languageFiles");}
set; }
} public event PropertyChangedEventHandler PropertyChanged;
public LanguageFile LanguageFile2 {
get; private void NotifyPropertyChanged(String info) {
set; if (PropertyChanged != null) {
} PropertyChanged(this, new PropertyChangedEventArgs(info));
}
public ICollectionView View { }
get;
set; // maybe refactor this encapsulating column related info
} bool unsavedChangesInLanguage1 = false;
bool unsavedChangesInLanguage2 = false;
// TODO user should be able to create a new translation file using this app public LanguageFile LanguageFile1 {
// TODO possibility to edit language file meta data, such as version, languagegroup, description, etc. get;
set;
public Window1() { }
public LanguageFile LanguageFile2 {
// TODO remember last selected location get;
set;
/*var dialog = new System.Windows.Forms.FolderBrowserDialog(); }
dialog.ShowNewFolderButton = false;
System.Windows.Forms.DialogResult result = dialog.ShowDialog(); public ICollectionView View {
string languagePath; get;
set;
}
if (result == System.Windows.Forms.DialogResult.OK) {
languagePath = dialog.SelectedPath; public EntriesEditorWindow() {
} else {
this.Close(); /*var dialog = new System.Windows.Forms.FolderBrowserDialog();
return; dialog.ShowNewFolderButton = false;
}*/ System.Windows.Forms.DialogResult result = dialog.ShowDialog();
string languagePath;
string languagePath = @"C:\Users\jens\Documents\Sharpdevelop Projects\Greenshot\trunk\Greenshot\Languages\";
if (result == System.Windows.Forms.DialogResult.OK) {
InitializeComponent(); languagePath = dialog.SelectedPath;
DataContext = this; } else {
this.Activate(); this.Close();
View = CollectionViewSource.GetDefaultView(LoadResources(languagePath)); return;
} }*/
private IList<LanguageEntry> LoadResources(string languagePath) { languagePath = @"C:\Users\jens\Documents\Sharpdevelop Projects\Greenshot\trunk\Greenshot\Languages\";
LanguageFiles = new List<LanguageFile>();
foreach (LanguageFile languageFile in GreenshotLanguage.GetLanguageFiles(languagePath, "language*.xml")) { InitializeComponent();
LanguageFiles.Add(languageFile); DataContext = this;
this.Activate();
if ("en-US".Equals(languageFile.IETF)) {
// we should always start with en-US, so the grid is initialized with the probably most-complete language file as benchmark for translations View = CollectionViewSource.GetDefaultView(LoadResources(languagePath));
LanguageFile1 = languageFile; }
PopulateColumn(languageFile, 1);
} else if(LanguageFile2 == null) { private IList<LanguageEntry> LoadResources(string languagePath) {
LanguageFile2 = languageFile; LanguageFiles = new BindingList<LanguageFile>();
PopulateColumn(languageFile, 2); foreach (LanguageFile languageFile in GreenshotLanguage.GetLanguageFiles(languagePath, "language*.xml")) {
} LanguageFiles.Add(languageFile);
}
if(LanguageFile1 == null) { if ("en-US".Equals(languageFile.IETF)) {
MessageBox.Show("language-en-US.xml does not exist in the location selected. It is needed as reference for the translation."); // we should always start with en-US, so the grid is initialized with the probably most-complete language file as benchmark for translations
this.Close(); LanguageFile1 = languageFile;
} PopulateColumn(languageFile, 1);
return new List<LanguageEntry>(languageResources.Values); } else if(LanguageFile2 == null) {
} LanguageFile2 = languageFile;
PopulateColumn(languageFile, 2);
private void PopulateColumn(LanguageFile languageFile, int columnIndex) { }
ClearColumn(columnIndex); }
IDictionary<string, string> resources = GreenshotLanguage.ReadLanguageFile(languageFile); if(LanguageFile1 == null) {
foreach(string key in resources.Keys) { MessageBox.Show("language-en-US.xml does not exist in the location selected. It is needed as reference for the translation.");
LanguageEntry entry = GetOrCreateLanguageEntry(key); this.Close();
if(columnIndex == 1) entry.Entry1 = resources[key]; }
else if (columnIndex == 2) entry.Entry2 = resources[key]; return new List<LanguageEntry>(languageResources.Values);
else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2"); }
}
if(columnIndex == 1) unsavedChangesInLanguage1 = false; private void PopulateColumn(LanguageFile languageFile, int columnIndex) {
if(columnIndex == 2) unsavedChangesInLanguage2 = false; ClearColumn(columnIndex);
} IDictionary<string, string> resources = GreenshotLanguage.ReadLanguageFile(languageFile);
foreach(string key in resources.Keys) {
private void ClearColumn(int columnIndex) { LanguageEntry entry = GetOrCreateLanguageEntry(key);
// we do not throw out LanguageEntries that do not exist in selected language, if(columnIndex == 1) entry.Entry1 = resources[key];
// so that en-US (loaded at startup) is always the benchmark, even when other languages are displayed else if (columnIndex == 2) entry.Entry2 = resources[key];
foreach(LanguageEntry e in languageResources.Values) { else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2");
if (columnIndex == 1) e.Entry1 = null; }
else if (columnIndex == 2) e.Entry2 = null; if(columnIndex == 1) unsavedChangesInLanguage1 = false;
else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2"); if(columnIndex == 2) unsavedChangesInLanguage2 = false;
} }
}
private void ClearColumn(int columnIndex) {
private LanguageEntry GetOrCreateLanguageEntry(string key) { // we do not throw out LanguageEntries that do not exist in selected language,
LanguageEntry entry; // so that en-US (loaded at startup) is always the benchmark, even when other languages are displayed
if (languageResources.ContainsKey(key)) { foreach(LanguageEntry e in languageResources.Values) {
entry = languageResources[key]; if (columnIndex == 1) e.Entry1 = null;
} else { else if (columnIndex == 2) e.Entry2 = null;
entry = new LanguageEntry(); else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2");
entry.Key = key; }
languageResources.Add(key, entry); }
}
return entry; private LanguageEntry GetOrCreateLanguageEntry(string key) {
} LanguageEntry entry;
if (languageResources.ContainsKey(key)) {
private void saveButtonClicked(object sender, RoutedEventArgs e) { entry = languageResources[key];
int targetColumn = GetTargetColumn((Control)sender); } else {
LanguageFile editedFile = (LanguageFile) (targetColumn == 1 ? language1ComboBox.SelectedItem : language2ComboBox.SelectedItem); entry = new LanguageEntry();
entry.Key = key;
var dialog = new System.Windows.Forms.SaveFileDialog(); languageResources.Add(key, entry);
dialog.AutoUpgradeEnabled = true; }
dialog.DefaultExt = ".xml"; return entry;
dialog.InitialDirectory = Path.GetDirectoryName(editedFile.FilePath); }
dialog.FileName = editedFile.FileName;
dialog.CheckFileExists = true; private void saveButtonClicked(object sender, RoutedEventArgs e) {
System.Windows.Forms.DialogResult result = dialog.ShowDialog(); int targetColumn = GetTargetColumn((Control)sender);
if (result == System.Windows.Forms.DialogResult.OK) { LanguageFile editedFile = (LanguageFile) (targetColumn == 1 ? language1ComboBox.SelectedItem : language2ComboBox.SelectedItem);
CreateXML(dialog.FileName, targetColumn);
} CreateXML(editedFile.FilePath, targetColumn);
} }
private void languageComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { private void languageComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e) {
int targetColumn = GetTargetColumn((Control)sender); int targetColumn = GetTargetColumn((Control)sender);
LanguageFile file = (LanguageFile)((ComboBox)sender).SelectedItem; LanguageFile file = (LanguageFile)((ComboBox)sender).SelectedItem;
if((targetColumn == 1 && file.Equals(LanguageFile1)) || (targetColumn == 2 && file.Equals(LanguageFile2))) { if((targetColumn == 1 && file.Equals(LanguageFile1)) || (targetColumn == 2 && file.Equals(LanguageFile2))) {
// nothing changed // nothing changed
return; return;
} }
if((targetColumn == 1 && unsavedChangesInLanguage1) || (targetColumn == 2 && unsavedChangesInLanguage2)) { if((targetColumn == 1 && unsavedChangesInLanguage1) || (targetColumn == 2 && unsavedChangesInLanguage2)) {
MessageBoxResult res = MessageBox.Show("Do you really want to switch language? Unsaved changes will be lost.", "Confirm language switch", MessageBoxButton.OKCancel, MessageBoxImage.Warning,MessageBoxResult.Cancel,MessageBoxOptions.None); MessageBoxResult res = MessageBox.Show("Do you really want to switch language? Unsaved changes will be lost.", "Confirm language switch", MessageBoxButton.OKCancel, MessageBoxImage.Warning,MessageBoxResult.Cancel,MessageBoxOptions.None);
if(res != MessageBoxResult.OK) { if(res != MessageBoxResult.OK) {
// cancelled by user // cancelled by user
((ComboBox)sender).SelectedItem = (targetColumn == 1) ? LanguageFile1 : LanguageFile2; ((ComboBox)sender).SelectedItem = (targetColumn == 1) ? LanguageFile1 : LanguageFile2;
return; return;
} }
} }
if(targetColumn == 1) LanguageFile1 = file; if(targetColumn == 1) LanguageFile1 = file;
else if(targetColumn == 2) LanguageFile2 = file; else if(targetColumn == 2) LanguageFile2 = file;
PopulateColumn(file, targetColumn); PopulateColumn(file, targetColumn);
} }
private void cancelButtonClicked(object sender, RoutedEventArgs e) { private void cancelButtonClicked(object sender, RoutedEventArgs e) {
int targetColumn = GetTargetColumn((Control)sender); int targetColumn = GetTargetColumn((Control)sender);
if((targetColumn == 1 && unsavedChangesInLanguage1) || (targetColumn == 2 && unsavedChangesInLanguage2)) { if((targetColumn == 1 && unsavedChangesInLanguage1) || (targetColumn == 2 && unsavedChangesInLanguage2)) {
MessageBoxResult res = MessageBox.Show("Do you really want to reset this column? Unsaved changes will be lost.", "Confirm language reset", MessageBoxButton.OKCancel, MessageBoxImage.Warning,MessageBoxResult.Cancel,MessageBoxOptions.None); MessageBoxResult res = MessageBox.Show("Do you really want to reset this column? Unsaved changes will be lost.", "Confirm language reset", MessageBoxButton.OKCancel, MessageBoxImage.Warning,MessageBoxResult.Cancel,MessageBoxOptions.None);
if(res == MessageBoxResult.OK) { if(res == MessageBoxResult.OK) {
LanguageFile file = (LanguageFile)(targetColumn == 1 ? language1ComboBox.SelectedItem : language2ComboBox.SelectedItem); LanguageFile file = (LanguageFile)(targetColumn == 1 ? language1ComboBox.SelectedItem : language2ComboBox.SelectedItem);
PopulateColumn(file, targetColumn); PopulateColumn(file, targetColumn);
} }
} }
} }
private int GetTargetColumn(Control control) { private void newButtonClicked(object sender, RoutedEventArgs e) {
object tag = control.Tag; int targetColumn = GetTargetColumn((Control)sender);
if(tag == null && !tag.Equals("1") && !tag.Equals("2")) { if((targetColumn == 1 && unsavedChangesInLanguage1) || (targetColumn == 2 && unsavedChangesInLanguage2)) {
throw new ApplicationException("Please use the control's Tag property to indicate the column to interact with (1 or 2)."); MessageBoxResult res = MessageBox.Show("Do you really want to discard this column? Unsaved changes will be lost.", "Confirm new language file creation", MessageBoxButton.OKCancel, MessageBoxImage.Warning,MessageBoxResult.Cancel,MessageBoxOptions.None);
} else { if(res != MessageBoxResult.OK) {
return tag.Equals("1") ? 1 : 2; return;
} }
} }
LanguageFile newLang = new LanguageFile();
private void cellEdited(object sender, DataGridCellEditEndingEventArgs e) { newLang.FilePath = languagePath;
if(e.Column.DisplayIndex == 1) unsavedChangesInLanguage1 = true; new MetaEditorWindow(newLang).ShowDialog();
else if(e.Column.DisplayIndex == 2) unsavedChangesInLanguage2 = true; if(newLang.FileName != null && newLang.FileName.Length > 0) {
} ClearColumn(targetColumn);
CreateXML(newLang.FilePath,targetColumn);
public void CreateXML(string savePath, int targetColumn) { LanguageFiles.Add(newLang);
ICollectionView view = (ICollectionView)LanguageGrid.ItemsSource; LanguageFiles = LanguageFiles.OrderBy(f => f.FileName).ToList();
IList<LanguageEntry> entries = (IList<LanguageEntry>)view.SourceCollection; if(targetColumn == 1) {
LanguageFile1 = newLang;
using (XmlTextWriter xmlWriter = new XmlTextWriter(savePath, Encoding.UTF8)) { language1ComboBox.SelectedItem = newLang;
xmlWriter.Formatting = Formatting.Indented; }
xmlWriter.Indentation = 1; else {
xmlWriter.IndentChar = '\t'; LanguageFile2 = newLang;
xmlWriter.WriteStartDocument(); language2ComboBox.SelectedItem = newLang;
xmlWriter.WriteStartElement("language"); }
xmlWriter.WriteAttributeString("description", "testdescription"); PopulateColumn(newLang, targetColumn);
xmlWriter.WriteAttributeString("ietf", "testietf"); }
xmlWriter.WriteAttributeString("version", "testversion"); }
xmlWriter.WriteAttributeString("languagegroup", "testlanguagegroup");
xmlWriter.WriteStartElement("resources"); private void metaButtonClicked(object sender, RoutedEventArgs e) {
foreach(LanguageEntry entry in entries) { int targetColumn = GetTargetColumn((Control)sender);
xmlWriter.WriteStartElement("resource"); new MetaEditorWindow(targetColumn == 1 ? LanguageFile1 : LanguageFile2).ShowDialog();
xmlWriter.WriteAttributeString("name", entry.Key); }
if(targetColumn == 1) xmlWriter.WriteString(entry.Entry1);
else if(targetColumn == 2 ) xmlWriter.WriteString(entry.Entry2); private int GetTargetColumn(Control control) {
else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2"); object tag = control.Tag;
xmlWriter.WriteEndElement(); if(tag == null && !tag.Equals("1") && !tag.Equals("2")) {
} throw new ApplicationException("Please use the control's Tag property to indicate the column to interact with (1 or 2).");
xmlWriter.WriteEndElement(); } else {
xmlWriter.WriteEndElement(); return tag.Equals("1") ? 1 : 2;
xmlWriter.WriteEndDocument(); }
} }
}
private void cellEdited(object sender, DataGridCellEditEndingEventArgs e) {
} if(e.Column.DisplayIndex == 1) unsavedChangesInLanguage1 = true;
else if(e.Column.DisplayIndex == 2) unsavedChangesInLanguage2 = true;
public class LanguageEntry : IEditableObject, INotifyPropertyChanged { }
private string key;
private string entry1; public void CreateXML(string savePath, int targetColumn) {
private string entry2;
public event PropertyChangedEventHandler PropertyChanged; LanguageFile langfile = targetColumn == 1 ? LanguageFile1 : LanguageFile2;
private void NotifyPropertyChanged(String info) { ICollectionView view = (ICollectionView)LanguageGrid.ItemsSource;
if (PropertyChanged != null) { IList<LanguageEntry> entries = (IList<LanguageEntry>)view.SourceCollection;
PropertyChanged(this, new PropertyChangedEventArgs(info));
} using (XmlTextWriter xmlWriter = new XmlTextWriter(savePath, Encoding.UTF8)) {
} xmlWriter.Formatting = Formatting.Indented;
xmlWriter.Indentation = 1;
public Brush Background { xmlWriter.IndentChar = '\t';
get { xmlWriter.WriteStartDocument();
if (String.IsNullOrEmpty(Entry1)) { xmlWriter.WriteStartElement("language");
return Brushes.Red; xmlWriter.WriteAttributeString("description", langfile.Description);
} xmlWriter.WriteAttributeString("ietf", langfile.IETF);
if (String.IsNullOrEmpty(Entry2)) { xmlWriter.WriteAttributeString("version", langfile.Version);
return Brushes.Red; xmlWriter.WriteAttributeString("languagegroup", langfile.Languagegroup);
} xmlWriter.WriteStartElement("resources");
return Brushes.White; foreach(LanguageEntry entry in entries) {
} xmlWriter.WriteStartElement("resource");
} xmlWriter.WriteAttributeString("name", entry.Key);
public string Key { if(targetColumn == 1) xmlWriter.WriteString(entry.Entry1);
get { else if(targetColumn == 2 ) xmlWriter.WriteString(entry.Entry2);
return key; else throw new ArgumentOutOfRangeException("Argument columnIndex must be either 1 or 2");
} xmlWriter.WriteEndElement();
set { }
key = value; xmlWriter.WriteEndElement();
NotifyPropertyChanged("Key"); xmlWriter.WriteEndElement();
} xmlWriter.WriteEndDocument();
} }
}
public string Entry1 {
get {
return entry1;
} }
set {
entry1 = value; public class LanguageEntry : IEditableObject, INotifyPropertyChanged {
NotifyPropertyChanged("Entry1"); private string key;
NotifyPropertyChanged("Background"); private string entry1;
private string entry2;
} public event PropertyChangedEventHandler PropertyChanged;
}
private void NotifyPropertyChanged(String info) {
public string Entry2 { if (PropertyChanged != null) {
get { PropertyChanged(this, new PropertyChangedEventArgs(info));
return entry2; }
} }
set {
entry2 = value; public Brush Background {
NotifyPropertyChanged("Entry2"); get {
NotifyPropertyChanged("Background"); if (String.IsNullOrEmpty(Entry1)) {
} return Brushes.Red;
} }
if (String.IsNullOrEmpty(Entry2)) {
public void BeginEdit() { return Brushes.Red;
}
} return Brushes.White;
}
public void EndEdit() { }
public string Key {
} get {
return key;
public void CancelEdit() { }
set {
} key = value;
} NotifyPropertyChanged("Key");
}
}
public string Entry1 {
get {
return entry1;
}
set {
entry1 = value;
NotifyPropertyChanged("Entry1");
NotifyPropertyChanged("Background");
}
}
public string Entry2 {
get {
return entry2;
}
set {
entry2 = value;
NotifyPropertyChanged("Entry2");
NotifyPropertyChanged("Background");
}
}
public void BeginEdit() {
}
public void EndEdit() {
}
public void CancelEdit() {
}
}
} }

View file

@ -78,23 +78,36 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Language.cs" /> <Compile Include="Language.cs" />
<Compile Include="MetaEditorWindow.xaml.cs">
<DependentUpon>MetaEditorWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\WPFAssemblyInfo.cs" /> <Compile Include="Properties\WPFAssemblyInfo.cs" />
<Compile Include="Window1.xaml.cs"> <Compile Include="EntriesEditorWindow.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
<DependentUpon>Window1.xaml</DependentUpon> <DependentUpon>EntriesEditorWindow.xaml</DependentUpon>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="Window1.xaml" /> <Page Include="MetaEditorWindow.xaml" />
<Page Include="EntriesEditorWindow.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
<None Include="icons\cross.png" /> <Resource Include="icons\cross.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="icons\disk-black.png"> <Resource Include="icons\disk-black.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<LogicalName>icon-save</LogicalName> <LogicalName>icon-save</LogicalName>
</Resource> </Resource>
<Resource Include="icons\new.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="icons\property.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="icons" /> <Folder Include="icons" />

View file

@ -27,11 +27,19 @@ using System.Xml.Linq;
namespace GreenshotLanguageEditor { namespace GreenshotLanguageEditor {
public class LanguageFile { public class LanguageFile {
public string FilePath { public string FilePath {
get; get {return Path.Combine(FileDir,FileName);}
set; set {
FileDir = Path.GetDirectoryName(value);
FileName = Path.GetFileName(value);
}
} }
public string FileDir {
get;
set;
}
public string FileName { public string FileName {
get {return Path.GetFileName(FilePath);} get;
set;
} }
public string IETF { public string IETF {
get; get;

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="GreenshotLanguageEditor.MetaEditorWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="GreenshotLanguageEditor"
Width="320"
Height="243"
Icon="icons\icon.ico">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto"></RowDefinition>
<RowDefinition
Height="Auto"></RowDefinition>
<RowDefinition
Height="Auto"></RowDefinition>
<RowDefinition
Height="Auto"></RowDefinition>
<RowDefinition
Height="Auto"></RowDefinition>
<RowDefinition
Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*"></ColumnDefinition>
<ColumnDefinition
Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Height="22"
Padding="2"
Margin="5">Filename</Label>
<TextBox
Grid.Row="0"
Grid.Column="1"
Height="22"
Margin="5"
Width="150"
Text="{Binding Path=LangFile.FileName, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=TwoWay}"></TextBox>
<Label
Grid.Row="1"
Grid.Column="0"
Height="22"
Padding="2"
Margin="5">Description</Label>
<TextBox
Grid.Row="1"
Grid.Column="1"
Height="22"
Margin="5"
Width="150"
Text="{Binding Path=LangFile.Description, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=TwoWay}"></TextBox>
<Label
Grid.Row="2"
Grid.Column="0"
Height="22"
Padding="2"
Margin="5">IETF</Label>
<TextBox
Grid.Row="2"
Grid.Column="1"
Height="22"
Margin="5"
Width="150"
Text="{Binding Path=LangFile.IETF, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=TwoWay}"></TextBox>
<Label
Grid.Row="3"
Grid.Column="0"
Height="22"
Padding="2"
Margin="5">Language group</Label>
<TextBox
Grid.Row="3"
Grid.Column="1"
Height="22"
Margin="5"
Width="150"
Text="{Binding Path=LangFile.Languagegroup, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=TwoWay}"></TextBox>
<Label
Grid.Row="4"
Grid.Column="0"
Height="22"
Padding="2"
Margin="5">Version</Label>
<TextBox
Grid.Row="4"
Grid.Column="1"
Height="22"
Margin="5"
Width="150"
Text="{Binding Path=LangFile.Version, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=TwoWay}"></TextBox>
<Button
Grid.Row="5"
Grid.Column="1"
Content="Close"
Margin="5,10,5,5"
Name="button1"
Click="button1_Click"></Button>
</Grid>
</Window>

View file

@ -0,0 +1,65 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Text.RegularExpressions;
namespace GreenshotLanguageEditor
{
/// <summary>
/// Interaction logic for LanguageMetaEditor.xaml
/// </summary>
public partial class MetaEditorWindow : Window {
private static Regex FILENAME_PATTERN = new Regex(@"[a-z]+\-[a-z]{2}\-[A-Z]{2}.xml");
private LanguageFile langFile = new LanguageFile();
public LanguageFile LangFile {
get {return langFile;}
set {langFile = value;}
}
public MetaEditorWindow(LanguageFile langFile) {
InitializeComponent();
this.LangFile = langFile;
this.Closing += new System.ComponentModel.CancelEventHandler(OnClosing);
}
void OnClosing(object sender, System.ComponentModel.CancelEventArgs e) {
if(langFile.FileName != null && langFile.FileName.Length != 0 && !FILENAME_PATTERN.IsMatch(langFile.FileName)) {
MessageBox.Show("The filename is not valid, please use a file name like language-en-US.xml","Filename not valid", MessageBoxButton.OK, MessageBoxImage.Stop);
e.Cancel = true;
}
}
void button1_Click(object sender, RoutedEventArgs e) {
this.Close();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B