comparison FrmMainWindow.cs @ 98:fac0636ae13b

Re #308: Make GTK# UI translatable * Make undo/redo menus translate on language change * Organise English language file * Resolve warnings by adding in dialogs that use translated strings when equipment amounts are out of range
author IBBoard <dev@ibboard.co.uk>
date Sun, 02 Jan 2011 21:03:15 +0000
parents b4416ca69153
children 8777e4f64d8e
comparison
equal deleted inserted replaced
97:6d2c8ad0d8f1 98:fac0636ae13b
38 private static readonly string AppTitle = "WarFoundry"; 38 private static readonly string AppTitle = "WarFoundry";
39 private const int CATEGORY_BUTTON_SEPARATOR_INDEX = 6; 39 private const int CATEGORY_BUTTON_SEPARATOR_INDEX = 6;
40 private Preferences preferences; 40 private Preferences preferences;
41 private ILog logger = LogManager.GetLogger(typeof(FrmMainWindow)); 41 private ILog logger = LogManager.GetLogger(typeof(FrmMainWindow));
42 private CommandStack commandStack; 42 private CommandStack commandStack;
43 private Dictionary<ToolButton, Category> categoryMap = new Dictionary<ToolButton, Category>();
44 private Dictionary<WFObjects.Unit, UnitDisplayWidget> unitToWidgetMap = new Dictionary<WFObjects.Unit,UnitDisplayWidget>(); 43 private Dictionary<WFObjects.Unit, UnitDisplayWidget> unitToWidgetMap = new Dictionary<WFObjects.Unit,UnitDisplayWidget>();
45 private ObjectAddDelegate UnitAddedMethod; 44 private ObjectAddDelegate UnitAddedMethod;
46 private ObjectRemoveDelegate UnitRemovedMethod; 45 private ObjectRemoveDelegate UnitRemovedMethod;
47 private DoubleValChangedDelegate PointsValueChangedMethod; 46 private DoubleValChangedDelegate PointsValueChangedMethod;
48 private FailedUnitRequirementDelegate FailedUnitRequirementMethod; 47 private FailedUnitRequirementDelegate FailedUnitRequirementMethod;
223 protected override void Translate() 222 protected override void Translate()
224 { 223 {
225 base.Translate(); 224 base.Translate();
226 SetAppTitle(); 225 SetAppTitle();
227 treeUnits.GetColumn(0).Title = Translation.GetTranslation("armyCategoryColumnTitle", "categories"); 226 treeUnits.GetColumn(0).Title = Translation.GetTranslation("armyCategoryColumnTitle", "categories");
227 RebuildUndoRedoMenus();
228 } 228 }
229 229
230 private void Retranslate() 230 private void Retranslate()
231 { 231 {
232 Translate(); 232 Translate();
412 { 412 {
413 get { return preferences; } 413 get { return preferences; }
414 set { preferences = value; } 414 set { preferences = value; }
415 } 415 }
416 416
417 /*public AbstractNativeWarFoundryFactory Factory
418 {
419 get { return WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(Constants.ExecutablePath, factoryType); }
420 }*/
421
422 protected void OnDeleteEvent(object sender, DeleteEventArgs a) 417 protected void OnDeleteEvent(object sender, DeleteEventArgs a)
423 { 418 {
424 Application.Quit(); 419 Application.Quit();
425 a.RetVal = true; 420 a.RetVal = true;
426 } 421 }
462 457
463 protected virtual void OnAddUnitActivated(object sender, System.EventArgs e) 458 protected virtual void OnAddUnitActivated(object sender, System.EventArgs e)
464 { 459 {
465 if (sender is ToolButton) 460 if (sender is ToolButton)
466 { 461 {
467 Category cat = null; 462 ToolButton toolButton = (ToolButton)sender;
468 categoryMap.TryGetValue((ToolButton)sender, out cat); 463 Category cat = (Category)toolButton.Data["Category"];
469 464
470 if (cat != null) 465 if (cat != null)
471 { 466 {
472 logger.DebugFormat("Show FrmNewUnit for {0}", cat.Name); 467 logger.DebugFormat("Show FrmNewUnit for {0}", cat.Name);
473 FrmNewUnit newUnit = new FrmNewUnit(WarFoundryCore.CurrentArmy.Race, cat, WarFoundryCore.CurrentArmy); 468 FrmNewUnit newUnit = new FrmNewUnit(WarFoundryCore.CurrentArmy.Race, cat, WarFoundryCore.CurrentArmy);
632 627
633 for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--) 628 for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--)
634 { 629 {
635 toolbar.Remove(toolbar.Children[i]); 630 toolbar.Remove(toolbar.Children[i]);
636 } 631 }
637
638 categoryMap.Clear();
639 } 632 }
640 633
641 private void AddCategoryButtons(Category[] cats) 634 private void AddCategoryButtons(Category[] cats)
642 { 635 {
643 if (cats != null && cats.Length > 0) 636 if (cats != null && cats.Length > 0)
647 foreach (Category cat in cats) 640 foreach (Category cat in cats)
648 { 641 {
649 ToolButton button = new ToolButton("gtk-add"); 642 ToolButton button = new ToolButton("gtk-add");
650 button.Label = cat.Name; 643 button.Label = cat.Name;
651 button.TooltipText = Translation.GetTranslation("bttnCreateFromCat", "{0}", cat.Name); 644 button.TooltipText = Translation.GetTranslation("bttnCreateFromCat", "{0}", cat.Name);
652 //TODO: See if we can associate data in some way, the same as we can with SWF. For now we just use the map. 645 button.Data["Category"] = cat;
653 categoryMap.Add(button, cat);
654 button.Clicked += new System.EventHandler(OnAddUnitActivated); 646 button.Clicked += new System.EventHandler(OnAddUnitActivated);
655 toolbar.Insert(button, -1); 647 toolbar.Insert(button, -1);
656 } 648 }
657 } 649 }
658 650
670 { 662 {
671 undoMenuButton.Sensitive = commandStack.CanUndo(); 663 undoMenuButton.Sensitive = commandStack.CanUndo();
672 miUndo.Sensitive = undoMenuButton.Sensitive; 664 miUndo.Sensitive = undoMenuButton.Sensitive;
673 redoMenuButton.Sensitive = commandStack.CanRedo(); 665 redoMenuButton.Sensitive = commandStack.CanRedo();
674 miRedo.Sensitive = redoMenuButton.Sensitive; 666 miRedo.Sensitive = redoMenuButton.Sensitive;
667
668 RebuildUndoRedoMenus();
669
670 bttnSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy != null;
671 miSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy != null;
672 }
673
674 private void RebuildUndoRedoMenus()
675 {
675 int redoLength = commandStack.RedoLength; 676 int redoLength = commandStack.RedoLength;
676
677 int maxRedo = Math.Min(10, redoLength); 677 int maxRedo = Math.Min(10, redoLength);
678 678
679 //TODO: Add tooltips
680 if (redoLength > 0) 679 if (redoLength > 0)
681 { 680 {
682 Menu menu = new Menu(); 681 Menu menu = new Menu();
683 Command com; 682 Command com;
684 MenuItem mi; 683 MenuItem mi;
685 684
686 for (int i = 0; i < maxRedo; i++) 685 for (int i = 0; i < maxRedo; i++)
687 { 686 {
688 com = commandStack.PeekRedoCommand(i + 1); 687 com = commandStack.PeekRedoCommand(i + 1);
689 688
690 if (com == null) 689 if (com == null)
691 { 690 {
692 break; 691 break;
693 } 692 }
694 693
695 mi = new MenuItem(com.Description); 694 mi = new MenuItem(com.Description);
696 mi.Activated += new EventHandler(RedoMenuActivated); 695 mi.Activated += new EventHandler(RedoMenuActivated);
697 menu.Append(mi); 696 menu.Append(mi);
698 } 697 }
699 698
705 redoMenuButton.Menu = null; 704 redoMenuButton.Menu = null;
706 } 705 }
707 706
708 int undoLength = commandStack.UndoLength; 707 int undoLength = commandStack.UndoLength;
709 int maxUndo = Math.Min(10, undoLength); 708 int maxUndo = Math.Min(10, undoLength);
710 709
711 if (undoLength > 0) 710 if (undoLength > 0)
712 { 711 {
713 Menu menu = new Menu(); 712 Menu menu = new Menu();
714 Command com; 713 Command com;
715 MenuItem mi; 714 MenuItem mi;
716 715
717 for (int i = 0; i < maxUndo; i++) 716 for (int i = 0; i < maxUndo; i++)
718 { 717 {
719 com = commandStack.PeekUndoCommand(i + 1); 718 com = commandStack.PeekUndoCommand(i + 1);
720 719
721 if (com == null) 720 if (com == null)
722 { 721 {
723 break; 722 break;
724 } 723 }
725 724
726 mi = new MenuItem(com.UndoDescription); 725 mi = new MenuItem(com.UndoDescription);
727 mi.Activated += new EventHandler(UndoMenuActivated); 726 mi.Activated += new EventHandler(UndoMenuActivated);
728 menu.Add(mi); 727 menu.Add(mi);
729 } 728 }
730 729
733 } 732 }
734 else 733 else
735 { 734 {
736 undoMenuButton.Menu = null; 735 undoMenuButton.Menu = null;
737 } 736 }
738
739 bttnSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy != null;
740 miSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy != null;
741 } 737 }
742 738
743 private void RedoMenuActivated(object sender, EventArgs e) 739 private void RedoMenuActivated(object sender, EventArgs e)
744 { 740 {
745 if (sender is MenuItem) 741 if (sender is MenuItem)
791 } 787 }
792 } 788 }
793 789
794 private bool OpenArmy() 790 private bool OpenArmy()
795 { 791 {
796 FileChooserDialog fileDialog = new FileChooserDialog("Open army", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept); 792 string title = Translation.GetTranslation("openArmyDialog", "open army");
793 string cancelText = Translation.GetTranslation("bttnCancel", "cancel");
794 string openText = Translation.GetTranslation("bttnOpen", "open");
795 FileChooserDialog fileDialog = new FileChooserDialog(title, this, FileChooserAction.Open, cancelText, ResponseType.Cancel, openText, ResponseType.Accept);
797 FileFilter filter = new FileFilter(); 796 FileFilter filter = new FileFilter();
798 filter.AddPattern("*.army"); 797 filter.AddPattern("*.army");
799 filter.Name = "WarFoundry Army files (*.army)"; 798 filter.Name = Translation.GetTranslation("armyFileFilter", "WarFoundry .army files");
800 fileDialog.AddFilter(filter); 799 fileDialog.AddFilter(filter);
801 int response = fileDialog.Run(); 800 int response = fileDialog.Run();
802 string filePath = null; 801 string filePath = null;
803 802
804 if (response == (int)ResponseType.Accept) 803 if (response == (int)ResponseType.Accept)
812 bool success = false; 811 bool success = false;
813 812
814 if (filePath != null) 813 if (filePath != null)
815 { 814 {
816 FileInfo file = new FileInfo(filePath); 815 FileInfo file = new FileInfo(filePath);
817 Army army = WarFoundryLoader.GetDefault().LoadArmy(file); 816 Army army = null;
817
818 try
819 {
820 army = WarFoundryLoader.GetDefault().LoadArmy(file);
821 }
822 catch (Exception ex)
823 {
824 logger.Error("Error while loading army file " + filePath, ex);
825 }
818 826
819 if (army != null) 827 if (army != null)
820 { 828 {
821 logger.Debug("Loaded army " + army.ID); 829 logger.Debug("Loaded army " + army.ID);
822 success = true; 830 success = true;
824 loadedArmyPath = filePath; 832 loadedArmyPath = filePath;
825 logger.Debug("Army loading complete"); 833 logger.Debug("Army loading complete");
826 } 834 }
827 else 835 else
828 { 836 {
829 logger.ErrorFormat("Failed to load {0} as an army file", filePath); 837 MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Translation.GetTranslation("OpenFailed", "File open failed. Please check log file"));
830 MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, file.Name + " could not be loaded.\n\nIf the file is an army file then please check your file loaders."); 838 dialog.Title = Translation.GetTranslation("OpenFailedTitle", "File open failed");
831 dialog.Title = "Failed to open army";
832 dialog.Run(); 839 dialog.Run();
833 dialog.Hide(); 840 dialog.Hide();
834 dialog.Dispose(); 841 dialog.Dispose();
835 } 842 }
836 } 843 }
854 return success; 861 return success;
855 } 862 }
856 863
857 private bool SaveCurrentArmyAs() 864 private bool SaveCurrentArmyAs()
858 { 865 {
859 FileChooserDialog fileDialog = new FileChooserDialog("Save file as", this, FileChooserAction.Save, "Cancel", ResponseType.Cancel, "Save", ResponseType.Accept); 866 string title = Translation.GetTranslation("saveArmyDialog", "save army");
867 string cancelText = Translation.GetTranslation("bttnCancel", "cancel");
868 string saveText = Translation.GetTranslation("bttnSave", "save");
869 FileChooserDialog fileDialog = new FileChooserDialog(title, this, FileChooserAction.Save, cancelText, ResponseType.Cancel, saveText, ResponseType.Accept);
860 FileFilter filter = new FileFilter(); 870 FileFilter filter = new FileFilter();
861 filter.AddPattern("*.army"); 871 filter.AddPattern("*.army");
862 filter.Name = "WarFoundry Army files (*.army)"; 872 filter.Name = Translation.GetTranslation("armyFileFilter", "WarFoundry .army files");
863 fileDialog.AddFilter(filter); 873 fileDialog.AddFilter(filter);
864 int response = fileDialog.Run(); 874 int response = fileDialog.Run();
865 string filePath = null; 875 string filePath = null;
866 876
867 if (response == (int)ResponseType.Accept) 877 if (response == (int)ResponseType.Accept)
879 { 889 {
880 bool success = false; 890 bool success = false;
881 891
882 if (filePath != null) 892 if (filePath != null)
883 { 893 {
884 if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, filePath)) 894 bool saveSuccess = false;
895
896 try
897 {
898 saveSuccess = WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, filePath);
899 }
900 catch (Exception ex)
901 {
902 logger.Error("Error while saving army file to " + filePath, ex);
903 }
904
905 if (saveSuccess)
885 { 906 {
886 miSaveArmy.Sensitive = false; 907 miSaveArmy.Sensitive = false;
887 bttnSaveArmy.Sensitive = false; 908 bttnSaveArmy.Sensitive = false;
888 CommandStack.setCleanMark(); 909 CommandStack.setCleanMark();
889 loadedArmyPath = filePath; 910 loadedArmyPath = filePath;
890 success = true; 911 success = true;
891 } 912 }
892 else 913 else
893 { 914 {
894 MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "Failed to save file to " + filePath); 915 MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Translation.GetTranslation("SaveFailed", "File save failed. Please check log file"));
895 dialog.Title = "Army save failed"; 916 dialog.Title = Translation.GetTranslation("SaveFailedTitle", "File save failed");
896 dialog.Run(); 917 dialog.Run();
897 dialog.Hide(); 918 dialog.Hide();
898 dialog.Dispose(); 919 dialog.Dispose();
899 } 920 }
900 } 921 }
909 { 930 {
910 bool canClose = false; 931 bool canClose = false;
911 932
912 if (CommandStack.IsDirty()) 933 if (CommandStack.IsDirty())
913 { 934 {
914 MessageDialog dia = new MessageDialog(this, DialogFlags.DestroyWithParent, MessageType.Question, ButtonsType.YesNo, "The army \"" + WarFoundryCore.CurrentArmy.Name + "\" has been modified.\r\nSave changes before closing army?"); 935 string message = Translation.GetTranslation("SaveChangesQuestion", "Save changes to army before closing?", WarFoundryCore.CurrentArmy.Name);
915 dia.AddButton("Cancel", ResponseType.Cancel); 936 MessageDialog dia = new MessageDialog(this, DialogFlags.DestroyWithParent, MessageType.Question, ButtonsType.None, message);
937 dia.AddButton(Translation.GetTranslation("bttnDiscard", "lose changes"), ResponseType.No);
938 Button button = (Button)dia.AddButton(Translation.GetTranslation("bttnCancel", "cancel"), ResponseType.Cancel);
939 button.Image = new Image("gtk-cancel", IconSize.Button);
940 button = (Button)dia.AddButton(Translation.GetTranslation("bttnSave", "save"), ResponseType.Yes);
941 button.Image = new Image("gtk-save", IconSize.Button);
942 dia.Title = Translation.GetTranslation("SaveChangesTitle", "Save changes?");
916 ResponseType dr = (ResponseType)dia.Run(); 943 ResponseType dr = (ResponseType)dia.Run();
917 dia.Hide(); 944 dia.Hide();
918 dia.Dispose(); 945 dia.Dispose();
919 946
920 if (dr == ResponseType.Yes) 947 if (dr == ResponseType.Yes)