1 /* 2 * "GEDKeeper", the personal genealogical database editor. 3 * Copyright (C) 2009-2019 by Sergey V. Zhdanovskih. 4 * 5 * This file is part of "GEDKeeper". 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 using System; 22 using BSLib; 23 using Eto.Drawing; 24 using Eto.Forms; 25 using GKCore; 26 using GKCore.Lists; 27 using GKCore.Types; 28 using BSDListItem = BSLib.Design.MVP.Controls.IListItem; 29 30 namespace GKUI.Components 31 { 32 /// <summary> 33 /// 34 /// </summary> 35 public class GKSheetList : Panel, ISheetList 36 { 37 private readonly Button fBtnAdd; 38 private readonly Button fBtnDelete; 39 private readonly Button fBtnEdit; 40 private readonly Button fBtnLinkJump; 41 private readonly Button fBtnMoveUp; 42 private readonly Button fBtnMoveDown; 43 private readonly GKListView fList; 44 45 private EnumSet<SheetButton> fButtons; 46 private ListModel fListModel; 47 private bool fReadOnly; 48 49 50 public event ModifyEventHandler OnModify; 51 52 public event ItemValidatingEventHandler OnItemValidating; 53 54 public event ModifyEventHandler OnBeforeChange; 55 56 57 public EnumSet<SheetButton> Buttons 58 { 59 get { return fButtons; } 60 set { 61 if (fButtons != value) { 62 fButtons = value; 63 UpdateButtons(); 64 } 65 } 66 } 67 68 public ListModel ListModel 69 { 70 get { return fListModel; } 71 set { 72 if (fListModel != value) { 73 if (fListModel != null) { 74 fListModel.SheetList = null; 75 } 76 77 fListModel = value; 78 79 if (fListModel != null) { 80 fListModel.SheetList = this; 81 } 82 } 83 84 UpdateSheet(); 85 } 86 } 87 88 public bool ReadOnly 89 { 90 get { return fReadOnly; } 91 set { SetReadOnly(value); } 92 } 93 94 GKSheetList(Panel owner)95 public GKSheetList(Panel owner) 96 { 97 if (owner == null) 98 throw new ArgumentNullException("owner"); 99 100 fBtnMoveDown = new Button(); 101 fBtnMoveDown.Image = UIHelper.LoadResourceImage("Resources.btn_down.gif"); 102 fBtnMoveDown.Size = UIHelper.ShortButtonSize; 103 fBtnMoveDown.ToolTip = LangMan.LS(LSID.LSID_RecordMoveDown); 104 fBtnMoveDown.Click += ItemMoveDown; 105 106 fBtnMoveUp = new Button(); 107 fBtnMoveUp.Image = UIHelper.LoadResourceImage("Resources.btn_up.gif"); 108 fBtnMoveUp.Size = UIHelper.ShortButtonSize; 109 fBtnMoveUp.ToolTip = LangMan.LS(LSID.LSID_RecordMoveUp); 110 fBtnMoveUp.Click += ItemMoveUp; 111 112 fBtnLinkJump = new Button(); 113 fBtnLinkJump.Image = UIHelper.LoadResourceImage("Resources.btn_jump.gif"); 114 fBtnLinkJump.Size = UIHelper.ShortButtonSize; 115 fBtnLinkJump.ToolTip = LangMan.LS(LSID.LSID_RecordGoto); 116 fBtnLinkJump.Click += ItemJump; 117 118 fBtnDelete = new Button(); 119 fBtnDelete.Image = UIHelper.LoadResourceImage("Resources.btn_rec_delete.gif"); 120 fBtnDelete.Size = UIHelper.ShortButtonSize; 121 fBtnDelete.ToolTip = LangMan.LS(LSID.LSID_MIRecordDelete); 122 fBtnDelete.Click += ItemDelete; 123 124 fBtnEdit = new Button(); 125 fBtnEdit.Image = UIHelper.LoadResourceImage("Resources.btn_rec_edit.gif"); 126 fBtnEdit.Size = UIHelper.ShortButtonSize; 127 fBtnEdit.ToolTip = LangMan.LS(LSID.LSID_MIRecordEdit); 128 fBtnEdit.Click += ItemEdit; 129 130 fBtnAdd = new Button(); 131 fBtnAdd.Image = UIHelper.LoadResourceImage("Resources.btn_rec_new.gif"); 132 fBtnAdd.Size = UIHelper.ShortButtonSize; 133 fBtnAdd.ToolTip = LangMan.LS(LSID.LSID_MIRecordAdd); 134 fBtnAdd.Click += ItemAdd; 135 136 fList = new GKListView(); 137 fList.MouseDoubleClick += List_DoubleClick; 138 fList.KeyDown += List_KeyDown; 139 140 SuspendLayout(); 141 142 var toolbar = new DefStackLayout(Orientation.Vertical, 4, 143 fBtnAdd, fBtnEdit, fBtnDelete, 144 fBtnLinkJump, fBtnMoveUp, fBtnMoveDown); 145 146 var tab = new TableLayout(2, 1); 147 tab.Spacing = new Size(4, 4); 148 tab.SetColumnScale(0, true); 149 tab.SetColumnScale(1, false); 150 tab.Add(fList, 0, 0); 151 tab.Add(toolbar, 1, 0); 152 153 Content = tab; 154 ResumeLayout(); 155 156 owner.SuspendLayout(); 157 owner.Content = this; 158 owner.ResumeLayout(); 159 160 fButtons = EnumSet<SheetButton>.Create(SheetButton.lbAdd, SheetButton.lbEdit, SheetButton.lbDelete); 161 fListModel = null; 162 } 163 Dispose(bool disposing)164 protected override void Dispose(bool disposing) 165 { 166 if (disposing) 167 { 168 fList.Dispose(); 169 fBtnLinkJump.Dispose(); 170 fBtnMoveUp.Dispose(); 171 fBtnMoveDown.Dispose(); 172 fBtnDelete.Dispose(); 173 fBtnEdit.Dispose(); 174 fBtnAdd.Dispose(); 175 } 176 base.Dispose(disposing); 177 } 178 Activate()179 public void Activate() 180 { 181 Focus(); 182 } 183 184 #region Private methods 185 UpdateButtons()186 private void UpdateButtons() 187 { 188 if (fListModel == null) { 189 fBtnAdd.Visible = fButtons.Contains(SheetButton.lbAdd); 190 fBtnDelete.Visible = fButtons.Contains(SheetButton.lbDelete); 191 fBtnEdit.Visible = fButtons.Contains(SheetButton.lbEdit); 192 fBtnLinkJump.Visible = fButtons.Contains(SheetButton.lbJump); 193 fBtnMoveUp.Visible = fButtons.Contains(SheetButton.lbMoveUp); 194 fBtnMoveDown.Visible = fButtons.Contains(SheetButton.lbMoveDown); 195 //fToolBar.Enabled = !fButtons.IsEmpty(); 196 } else { 197 EnumSet<RecordAction> allowedActions = fListModel.AllowedActions; 198 fBtnAdd.Visible = allowedActions.Contains(RecordAction.raAdd); 199 fBtnDelete.Visible = allowedActions.Contains(RecordAction.raDelete); 200 fBtnEdit.Visible = allowedActions.Contains(RecordAction.raEdit); 201 fBtnLinkJump.Visible = allowedActions.Contains(RecordAction.raJump); 202 fBtnMoveUp.Visible = allowedActions.Contains(RecordAction.raMoveUp); 203 fBtnMoveDown.Visible = allowedActions.Contains(RecordAction.raMoveDown); 204 //fToolBar.Visible = !allowedActions.IsEmpty(); 205 } 206 } 207 SetReadOnly(bool value)208 private void SetReadOnly(bool value) 209 { 210 fReadOnly = value; 211 fBtnAdd.Enabled = !fReadOnly; 212 fBtnDelete.Enabled = !fReadOnly; 213 fBtnEdit.Enabled = !fReadOnly; 214 fBtnMoveUp.Enabled = !fReadOnly; 215 fBtnMoveDown.Enabled = !fReadOnly; 216 217 fList.BackgroundColor = (fReadOnly) ? SystemColors.Control : SystemColors.WindowBackground; 218 } 219 List_DoubleClick(object sender, EventArgs e)220 private void List_DoubleClick(object sender, EventArgs e) 221 { 222 ItemEdit(sender, e); 223 } 224 List_KeyDown(object sender, KeyEventArgs e)225 private void List_KeyDown(object sender, KeyEventArgs e) 226 { 227 if (e.Control) 228 { 229 switch (e.Key) { 230 case Keys.I: 231 ItemAdd(sender, e); 232 break; 233 case Keys.D: 234 ItemDelete(sender, e); 235 break; 236 case Keys.Enter: 237 ItemEdit(sender, e); 238 break; 239 } 240 } 241 } 242 RestoreSelected(object itemData)243 private void RestoreSelected(object itemData) 244 { 245 Activate(); 246 fList.Activate(); 247 248 if (itemData != null) fList.SelectItem(itemData); 249 } 250 DoBeforeChange(ModifyEventArgs eArgs)251 private void DoBeforeChange(ModifyEventArgs eArgs) 252 { 253 var eventHandler = (ModifyEventHandler)OnBeforeChange; 254 if (eventHandler != null) { 255 eventHandler(this, eArgs); 256 } 257 } 258 DoModify(ModifyEventArgs eArgs)259 private void DoModify(ModifyEventArgs eArgs) 260 { 261 DoBeforeChange(eArgs); 262 263 if (fListModel != null) { 264 fListModel.Modify(this, eArgs); 265 266 if (eArgs.IsChanged) { 267 UpdateSheet(); 268 } 269 } 270 271 var eventHandler = (ModifyEventHandler)OnModify; 272 if (eventHandler != null) { 273 eventHandler(this, eArgs); 274 } 275 } 276 ValidateItem(object item)277 private bool ValidateItem(object item) 278 { 279 var args = new ItemValidatingEventArgs(item); 280 281 var eventHandler = (ItemValidatingEventHandler)OnItemValidating; 282 if (eventHandler == null) 283 { 284 return true; 285 } 286 287 eventHandler(this, args); 288 return args.IsAvailable; 289 } 290 ItemAdd(object sender, EventArgs e)291 private void ItemAdd(object sender, EventArgs e) 292 { 293 if (fReadOnly) return; 294 295 var eArgs = new ModifyEventArgs(RecordAction.raAdd, null); 296 DoModify(eArgs); 297 RestoreSelected(eArgs.ItemData); 298 } 299 ItemEdit(object sender, EventArgs e)300 private void ItemEdit(object sender, EventArgs e) 301 { 302 object itemData = GetSelectedData(); 303 if (fReadOnly || itemData == null) return; 304 305 if (!ValidateItem(itemData)) return; 306 307 var eArgs = new ModifyEventArgs(RecordAction.raEdit, itemData); 308 DoModify(eArgs); 309 RestoreSelected(eArgs.ItemData); 310 } 311 ItemDelete(object sender, EventArgs e)312 private void ItemDelete(object sender, EventArgs e) 313 { 314 object itemData = GetSelectedData(); 315 if (fReadOnly || itemData == null) return; 316 317 if (!ValidateItem(itemData)) return; 318 319 var eArgs = new ModifyEventArgs(RecordAction.raDelete, itemData); 320 DoModify(eArgs); 321 } 322 ItemJump(object sender, EventArgs e)323 private void ItemJump(object sender, EventArgs e) 324 { 325 object itemData = GetSelectedData(); 326 if (itemData == null) return; 327 328 if (!ValidateItem(itemData)) return; 329 330 var eArgs = new ModifyEventArgs(RecordAction.raJump, itemData); 331 DoModify(eArgs); 332 } 333 ItemMoveUp(object sender, EventArgs e)334 private void ItemMoveUp(object sender, EventArgs e) 335 { 336 object itemData = GetSelectedData(); 337 if (fReadOnly || itemData == null) return; 338 339 var eArgs = new ModifyEventArgs(RecordAction.raMoveUp, itemData); 340 DoModify(eArgs); 341 RestoreSelected(eArgs.ItemData); 342 } 343 ItemMoveDown(object sender, EventArgs e)344 private void ItemMoveDown(object sender, EventArgs e) 345 { 346 object itemData = GetSelectedData(); 347 if (fReadOnly || itemData == null) return; 348 349 var eArgs = new ModifyEventArgs(RecordAction.raMoveDown, itemData); 350 DoModify(eArgs); 351 RestoreSelected(eArgs.ItemData); 352 } 353 354 #endregion 355 ClearColumns()356 public void ClearColumns() 357 { 358 fList.ClearColumns(); 359 } 360 ResizeColumn(int columnIndex)361 public void ResizeColumn(int columnIndex) 362 { 363 fList.ResizeColumn(columnIndex); 364 } 365 AddColumn(string caption, int width, bool autoSize)366 public void AddColumn(string caption, int width, bool autoSize) 367 { 368 fList.AddColumn(caption, width, autoSize); 369 } 370 BeginUpdate()371 public void BeginUpdate() 372 { 373 fList.BeginUpdate(); 374 } 375 EndUpdate()376 public void EndUpdate() 377 { 378 fList.EndUpdate(); 379 } 380 AddItem(object rowData, params object[] columnValues)381 public BSDListItem AddItem(object rowData, params object[] columnValues) 382 { 383 return fList.AddItem(rowData, columnValues); 384 } 385 ClearItems()386 public void ClearItems() 387 { 388 fList.ClearItems(); 389 } 390 SelectItem(int index)391 public void SelectItem(int index) 392 { 393 fList.SelectItem(index); 394 } 395 UpdateSheet()396 public void UpdateSheet() 397 { 398 UpdateButtons(); 399 400 if (fListModel != null) { 401 if (fList.Columns.Count == 0 || fListModel.ColumnsHaveBeenChanged) { 402 fList.ClearColumns(); 403 fListModel.UpdateColumns(fList); 404 } 405 406 fListModel.UpdateContents(); 407 } 408 } 409 GetSelectedData()410 public object GetSelectedData() 411 { 412 return fList.GetSelectedData(); 413 } 414 } 415 } 416