1 /* 2 KeePass Password Safe - The Open-Source Password Manager 3 Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 using System; 21 using System.Collections.Generic; 22 using System.ComponentModel; 23 using System.Diagnostics; 24 using System.Drawing; 25 using System.Globalization; 26 using System.Text; 27 using System.Windows.Forms; 28 using System.Xml.Serialization; 29 30 using KeePass.Resources; 31 using KeePass.UI; 32 33 using KeePassLib; 34 using KeePassLib.Security; 35 36 namespace KeePass.App.Configuration 37 { 38 public enum AceMainWindowLayout 39 { 40 Default = 0, 41 SideBySide = 1 42 } 43 44 [Flags] 45 public enum AceListGrouping 46 { 47 Auto = 0, 48 On = 1, 49 Off = 2, 50 51 // Additional flags: use value > Primary 52 53 Primary = 0x0F // Auto/On/Off are primary states 54 } 55 56 public enum AceEscAction 57 { 58 None = 0, 59 Lock = 1, 60 Minimize = 2, 61 MinimizeToTray = 3, 62 Exit = 4 63 } 64 65 public sealed class AceMainWindow 66 { AceMainWindow()67 public AceMainWindow() 68 { 69 } 70 71 private int m_posX = AppDefs.InvalidWindowValue; 72 public int X 73 { 74 get { return m_posX; } 75 set { m_posX = value; } 76 } 77 78 private int m_posY = AppDefs.InvalidWindowValue; 79 public int Y 80 { 81 get { return m_posY; } 82 set { m_posY = value; } 83 } 84 85 private int m_sizeW = AppDefs.InvalidWindowValue; 86 public int Width 87 { 88 get { return m_sizeW; } 89 set { m_sizeW = value; } 90 } 91 92 private int m_sizeH = AppDefs.InvalidWindowValue; 93 public int Height 94 { 95 get { return m_sizeH; } 96 set { m_sizeH = value; } 97 } 98 99 private bool m_bMax = false; 100 [DefaultValue(false)] 101 public bool Maximized 102 { 103 get { return m_bMax; } 104 set { m_bMax = value; } 105 } 106 107 private double m_dSplitterHorz = double.Epsilon; 108 public double SplitterHorizontalFrac 109 { 110 get { return m_dSplitterHorz; } 111 set { m_dSplitterHorz = value; } 112 } 113 114 private double m_dSplitterVert = double.Epsilon; 115 public double SplitterVerticalFrac 116 { 117 get { return m_dSplitterVert; } 118 set { m_dSplitterVert = value; } 119 } 120 121 private AceMainWindowLayout m_layout = AceMainWindowLayout.Default; 122 [DefaultValue(AceMainWindowLayout.Default)] 123 public AceMainWindowLayout Layout 124 { 125 get { return m_layout; } 126 set { m_layout = value; } 127 } 128 129 private bool m_bTop = false; 130 [DefaultValue(false)] 131 public bool AlwaysOnTop 132 { 133 get { return m_bTop; } 134 set { m_bTop = value; } 135 } 136 137 private bool m_bCloseMin = false; 138 [DefaultValue(false)] 139 public bool CloseButtonMinimizesWindow 140 { 141 get { return m_bCloseMin; } 142 set { m_bCloseMin = value; } 143 } 144 145 // For backward compatibility only; use EscAction instead 146 private bool m_bEscMin = false; 147 [DefaultValue(false)] 148 public bool EscMinimizesToTray 149 { 150 get { return m_bEscMin; } 151 set { m_bEscMin = value; } 152 } 153 154 private AceEscAction m_aEsc = AceEscAction.Lock; 155 [DefaultValue(AceEscAction.Lock)] 156 public AceEscAction EscAction 157 { 158 get { return m_aEsc; } 159 set { m_aEsc = value; } 160 } 161 162 private bool m_bMinToTray = false; 163 [DefaultValue(false)] 164 public bool MinimizeToTray 165 { 166 get { return m_bMinToTray; } 167 set { m_bMinToTray = value; } 168 } 169 170 private bool m_bFullPath = false; 171 [DefaultValue(false)] 172 public bool ShowFullPathInTitle 173 { 174 get { return m_bFullPath; } 175 set { m_bFullPath = value; } 176 } 177 178 // private bool m_bFullPathOnTab = false; 179 // [DefaultValue(false)] 180 // public bool ShowFullPathOnTab 181 // { 182 // get { return m_bFullPathOnTab; } 183 // set { m_bFullPathOnTab = value; } 184 // } 185 186 // private bool m_bDbNameOnTab = false; 187 // [DefaultValue(false)] 188 // public bool ShowDatabaseNameOnTab 189 // { 190 // get { return m_bDbNameOnTab; } 191 // set { m_bDbNameOnTab = value; } 192 // } 193 194 private bool m_bDropToBackAfterCopy = false; 195 [DefaultValue(false)] 196 public bool DropToBackAfterClipboardCopy 197 { 198 get { return m_bDropToBackAfterCopy; } 199 set { m_bDropToBackAfterCopy = value; } 200 } 201 202 private bool m_bMinAfterCopy = false; 203 [DefaultValue(false)] 204 public bool MinimizeAfterClipboardCopy 205 { 206 get { return m_bMinAfterCopy; } 207 set { m_bMinAfterCopy = value; } 208 } 209 210 private bool m_bMinAfterAutoType = false; 211 [DefaultValue(false)] 212 public bool MinimizeAfterAutoType 213 { 214 get { return m_bMinAfterAutoType; } 215 set { m_bMinAfterAutoType = value; } 216 } 217 218 private bool m_bMinAfterLocking = true; 219 [DefaultValue(true)] 220 public bool MinimizeAfterLocking 221 { 222 get { return m_bMinAfterLocking; } 223 set { m_bMinAfterLocking = value; } 224 } 225 226 private bool m_bMinAfterOpeningDb = false; 227 [DefaultValue(false)] 228 public bool MinimizeAfterOpeningDatabase 229 { 230 get { return m_bMinAfterOpeningDb; } 231 set { m_bMinAfterOpeningDb = value; } 232 } 233 234 private bool m_bQuickFindSearchInPasswords = false; 235 [DefaultValue(false)] 236 public bool QuickFindSearchInPasswords 237 { 238 get { return m_bQuickFindSearchInPasswords; } 239 set { m_bQuickFindSearchInPasswords = value; } 240 } 241 242 private bool m_bQuickFindExcludeExpired = false; 243 [DefaultValue(false)] 244 public bool QuickFindExcludeExpired 245 { 246 get { return m_bQuickFindExcludeExpired; } 247 set { m_bQuickFindExcludeExpired = value; } 248 } 249 250 private bool m_bQuickFindDerefData = false; 251 [DefaultValue(false)] 252 public bool QuickFindDerefData 253 { 254 get { return m_bQuickFindDerefData; } 255 set { m_bQuickFindDerefData = value; } 256 } 257 258 private bool m_bFocusResAfterQuickFind = false; 259 [DefaultValue(false)] 260 public bool FocusResultsAfterQuickFind 261 { 262 get { return m_bFocusResAfterQuickFind; } 263 set { m_bFocusResAfterQuickFind = value; } 264 } 265 266 private bool m_bFocusQuickFindOnRestore = false; 267 /// <summary> 268 /// Focus the quick search box when restoring the main 269 /// window. Here 'restoring' actually means unminimizing, 270 /// i.e. restoring or maximizing the window. 271 /// </summary> 272 [DefaultValue(false)] 273 public bool FocusQuickFindOnRestore 274 { 275 get { return m_bFocusQuickFindOnRestore; } 276 set { m_bFocusQuickFindOnRestore = value; } 277 } 278 279 private bool m_bFocusQuickFindOnUntray = false; 280 [DefaultValue(false)] 281 public bool FocusQuickFindOnUntray 282 { 283 get { return m_bFocusQuickFindOnUntray; } 284 set { m_bFocusQuickFindOnUntray = value; } 285 } 286 287 private bool m_bCopyUrls = false; 288 [DefaultValue(false)] 289 public bool CopyUrlsInsteadOfOpening 290 { 291 get { return m_bCopyUrls; } 292 set { m_bCopyUrls = value; } 293 } 294 295 private bool m_bEntrySelGroupSel = true; 296 [DefaultValue(true)] 297 public bool EntrySelGroupSel 298 { 299 get { return m_bEntrySelGroupSel; } 300 set { m_bEntrySelGroupSel = value; } 301 } 302 303 private bool m_bDisableSaveIfNotModified = false; 304 /// <summary> 305 /// Disable 'Save' button (instead of graying it out) if the database 306 /// hasn't been modified. 307 /// </summary> 308 [DefaultValue(false)] 309 public bool DisableSaveIfNotModified 310 { 311 get { return m_bDisableSaveIfNotModified; } 312 set { m_bDisableSaveIfNotModified = value; } 313 } 314 315 private bool m_bHideCloseDbTb = true; 316 [DefaultValue(true)] 317 public bool HideCloseDatabaseButton 318 { 319 get { return m_bHideCloseDbTb; } 320 set { m_bHideCloseDbTb = value; } 321 } 322 323 private AceToolBar m_tb = new AceToolBar(); 324 public AceToolBar ToolBar 325 { 326 get { return m_tb; } 327 set 328 { 329 if(value == null) throw new ArgumentNullException("value"); 330 m_tb = value; 331 } 332 } 333 334 private AceEntryView m_ev = new AceEntryView(); 335 public AceEntryView EntryView 336 { 337 get { return m_ev; } 338 set 339 { 340 if(value == null) throw new ArgumentNullException("value"); 341 m_ev = value; 342 } 343 } 344 345 private AceTanView m_tan = new AceTanView(); 346 public AceTanView TanView 347 { 348 get { return m_tan; } 349 set 350 { 351 if(value == null) throw new ArgumentNullException("value"); 352 m_tan = value; 353 } 354 } 355 356 private List<AceColumn> m_lColumns = new List<AceColumn>(); 357 [XmlArray("EntryListColumnCollection")] 358 [XmlArrayItem("Column")] 359 public List<AceColumn> EntryListColumns 360 { 361 get { return m_lColumns; } 362 set 363 { 364 if(value == null) throw new ArgumentNullException("value"); 365 m_lColumns = value; 366 } 367 } 368 369 private string m_strDisplayIndices = string.Empty; 370 [DefaultValue("")] 371 public string EntryListColumnDisplayOrder 372 { 373 get { return m_strDisplayIndices; } 374 set 375 { 376 if(value == null) throw new ArgumentNullException("value"); 377 m_strDisplayIndices = value; 378 } 379 } 380 381 private bool m_bAutoResizeColumns = false; 382 [DefaultValue(false)] 383 public bool EntryListAutoResizeColumns 384 { 385 get { return m_bAutoResizeColumns; } 386 set { m_bAutoResizeColumns = value; } 387 } 388 389 private bool m_bAlternatingBgColor = true; 390 [DefaultValue(true)] 391 public bool EntryListAlternatingBgColors 392 { 393 get { return m_bAlternatingBgColor; } 394 set { m_bAlternatingBgColor = value; } 395 } 396 397 private int m_argbAltBgColor = 0; 398 [DefaultValue(0)] 399 public int EntryListAlternatingBgColor 400 { 401 get { return m_argbAltBgColor; } 402 set { m_argbAltBgColor = value; } 403 } 404 405 private bool m_bResolveFieldRefs = false; 406 [DefaultValue(false)] 407 public bool EntryListShowDerefData 408 { 409 get { return m_bResolveFieldRefs; } 410 set { m_bResolveFieldRefs = value; } 411 } 412 413 private bool m_bResolveFieldRefsAsync = false; 414 [DefaultValue(false)] 415 public bool EntryListShowDerefDataAsync 416 { 417 get { return m_bResolveFieldRefsAsync; } 418 set { m_bResolveFieldRefsAsync = value; } 419 } 420 421 private bool m_bDerefDataWithRefs = true; 422 [DefaultValue(true)] 423 public bool EntryListShowDerefDataAndRefs 424 { 425 get { return m_bDerefDataWithRefs; } 426 set { m_bDerefDataWithRefs = value; } 427 } 428 429 // private bool m_bGridLines = false; 430 // public bool ShowGridLines 431 // { 432 // get { return m_bGridLines; } 433 // set { m_bGridLines = value; } 434 // } 435 436 private ListSorter m_pListSorter = null; 437 public ListSorter ListSorting 438 { 439 get 440 { 441 if(m_pListSorter == null) m_pListSorter = new ListSorter(); 442 return m_pListSorter; 443 } 444 set 445 { 446 if(value == null) throw new ArgumentNullException("value"); 447 m_pListSorter = value; 448 } 449 } 450 451 private int m_iLgMain = (int)AceListGrouping.Auto; 452 [DefaultValue((int)AceListGrouping.Auto)] 453 public int ListGrouping // AceListGrouping 454 { 455 get { return m_iLgMain; } 456 set { m_iLgMain = value; } 457 } 458 459 private bool m_bShowEntriesOfSubGroups = false; 460 [DefaultValue(false)] 461 public bool ShowEntriesOfSubGroups 462 { 463 get { return m_bShowEntriesOfSubGroups; } 464 set { m_bShowEntriesOfSubGroups = value; } 465 } 466 FindColumn(AceColumnType t)467 public AceColumn FindColumn(AceColumnType t) 468 { 469 foreach(AceColumn c in m_lColumns) 470 { 471 if(c.Type == t) return c; 472 } 473 474 return null; 475 } 476 FindColumns(AceColumnType t)477 internal List<AceColumn> FindColumns(AceColumnType t) 478 { 479 List<AceColumn> l = new List<AceColumn>(); 480 481 foreach(AceColumn c in m_lColumns) 482 { 483 if(c.Type == t) l.Add(c); 484 } 485 486 return l; 487 } 488 IsColumnHidden(AceColumnType t)489 public bool IsColumnHidden(AceColumnType t) 490 { 491 return IsColumnHidden(t, (t == AceColumnType.Password)); 492 } 493 IsColumnHidden(AceColumnType t, bool bDefault)494 public bool IsColumnHidden(AceColumnType t, bool bDefault) 495 { 496 foreach(AceColumn c in m_lColumns) 497 { 498 if(c.Type == t) return c.HideWithAsterisks; 499 } 500 501 return bDefault; 502 } 503 ShouldHideCustomString(string strCustomName, ProtectedString psValue)504 public bool ShouldHideCustomString(string strCustomName, 505 ProtectedString psValue) 506 { 507 foreach(AceColumn c in m_lColumns) 508 { 509 if((c.Type == AceColumnType.CustomString) && 510 (c.CustomName == strCustomName)) 511 return c.HideWithAsterisks; 512 } 513 if(psValue != null) return psValue.IsProtected; 514 return false; 515 } 516 } 517 518 public sealed class AceEntryView 519 { AceEntryView()520 public AceEntryView() 521 { 522 } 523 524 private bool m_bShow = true; 525 [DefaultValue(true)] 526 public bool Show 527 { 528 get { return m_bShow; } 529 set { m_bShow = value; } 530 } 531 532 // private bool m_bHideProtectedCustomStrings = true; 533 // [DefaultValue(true)] 534 // public bool HideProtectedCustomStrings 535 // { 536 // get { return m_bHideProtectedCustomStrings; } 537 // set { m_bHideProtectedCustomStrings = value; } 538 // } 539 } 540 541 public sealed class AceTanView 542 { AceTanView()543 public AceTanView() 544 { 545 } 546 547 private bool m_bSimple = true; 548 [DefaultValue(true)] 549 public bool UseSimpleView 550 { 551 get { return m_bSimple; } 552 set { m_bSimple = value; } 553 } 554 555 private bool m_bIndices = true; 556 [DefaultValue(true)] 557 public bool ShowIndices 558 { 559 get { return m_bIndices; } 560 set { m_bIndices = value; } 561 } 562 } 563 564 public enum AceColumnType 565 { 566 Title = 0, 567 UserName, 568 Password, 569 Url, 570 Notes, 571 CreationTime, 572 LastModificationTime, 573 LastAccessTime, 574 ExpiryTime, 575 Uuid, 576 Attachment, 577 578 CustomString, 579 580 PluginExt, // Column data provided by a plugin 581 582 OverrideUrl, 583 Tags, 584 ExpiryTimeDateOnly, 585 Size, 586 HistoryCount, 587 AttachmentCount, 588 LastPasswordModTime, 589 AutoTypeEnabled, 590 AutoTypeSequences, 591 592 Count // Virtual identifier representing the number of types 593 } 594 595 public sealed class AceColumn 596 { 597 private AceColumnType m_type = AceColumnType.Count; 598 public AceColumnType Type 599 { 600 get { return m_type; } 601 set 602 { 603 if(((int)value >= 0) && ((int)value < (int)AceColumnType.Count)) 604 m_type = value; 605 else { Debug.Assert(false); } 606 } 607 } 608 609 private string m_strCustomName = string.Empty; 610 [DefaultValue("")] 611 public string CustomName 612 { 613 get { return m_strCustomName; } 614 set 615 { 616 if(value == null) throw new ArgumentNullException("value"); 617 m_strCustomName = value; 618 } 619 } 620 621 private int m_nWidth = -1; 622 public int Width 623 { 624 get { return m_nWidth; } 625 set { m_nWidth = value; } 626 } 627 628 private bool m_bHide = false; 629 [DefaultValue(false)] 630 public bool HideWithAsterisks 631 { 632 get { return m_bHide; } 633 set { m_bHide = value; } 634 } 635 AceColumn()636 public AceColumn() 637 { 638 } 639 AceColumn(AceColumnType t)640 public AceColumn(AceColumnType t) 641 { 642 m_type = t; 643 } 644 AceColumn(AceColumnType t, string strCustomName, bool bHide, int nWidth)645 public AceColumn(AceColumnType t, string strCustomName, bool bHide, 646 int nWidth) 647 { 648 m_type = t; 649 m_strCustomName = strCustomName; 650 m_bHide = bHide; 651 m_nWidth = nWidth; 652 } 653 GetDisplayName()654 public string GetDisplayName() 655 { 656 string str = string.Empty; 657 658 switch(m_type) 659 { 660 case AceColumnType.Title: str = KPRes.Title; break; 661 case AceColumnType.UserName: str = KPRes.UserName; break; 662 case AceColumnType.Password: str = KPRes.Password; break; 663 case AceColumnType.Url: str = KPRes.Url; break; 664 case AceColumnType.Notes: str = KPRes.Notes; break; 665 case AceColumnType.CreationTime: str = KPRes.CreationTime; break; 666 case AceColumnType.LastModificationTime: str = KPRes.LastModificationTime; break; 667 case AceColumnType.LastAccessTime: str = KPRes.LastAccessTime; break; 668 case AceColumnType.ExpiryTime: str = KPRes.ExpiryTime; break; 669 case AceColumnType.Uuid: str = KPRes.Uuid; break; 670 case AceColumnType.Attachment: str = KPRes.Attachments; break; 671 case AceColumnType.CustomString: str = m_strCustomName; break; 672 case AceColumnType.PluginExt: str = m_strCustomName; break; 673 case AceColumnType.OverrideUrl: str = KPRes.UrlOverride; break; 674 case AceColumnType.Tags: str = KPRes.Tags; break; 675 case AceColumnType.ExpiryTimeDateOnly: str = KPRes.ExpiryTimeDateOnly; break; 676 case AceColumnType.Size: str = KPRes.Size; break; 677 case AceColumnType.HistoryCount: 678 str = KPRes.History + " (" + KPRes.Count + ")"; break; 679 case AceColumnType.AttachmentCount: 680 str = KPRes.Attachments + " (" + KPRes.Count + ")"; break; 681 case AceColumnType.LastPasswordModTime: str = KPRes.LastModTimePwHist; break; 682 case AceColumnType.AutoTypeEnabled: 683 str = KPRes.AutoType + " - " + KPRes.Enabled; break; 684 case AceColumnType.AutoTypeSequences: 685 str = KPRes.AutoType + " - " + KPRes.Sequences; break; 686 default: Debug.Assert(false); break; 687 }; 688 689 return str; 690 } 691 SafeGetWidth(int nDefaultWidth)692 public int SafeGetWidth(int nDefaultWidth) 693 { 694 if(m_nWidth >= 0) return m_nWidth; 695 return nDefaultWidth; 696 } 697 GetTypeNameEx()698 internal string GetTypeNameEx() 699 { 700 try 701 { 702 string str = m_type.ToString(); 703 704 if(!string.IsNullOrEmpty(m_strCustomName)) 705 str += " - " + m_strCustomName; 706 707 return str; 708 } 709 catch(Exception) { Debug.Assert(false); } 710 711 return ((long)m_type).ToString(NumberFormatInfo.InvariantInfo); 712 } 713 714 #if DEBUG ToString()715 public override string ToString() 716 { 717 return (GetTypeNameEx() + ", Width: " + m_nWidth.ToString() + 718 ", Hide: " + m_bHide.ToString()); 719 } 720 #endif 721 IsTimeColumn(AceColumnType t)722 public static bool IsTimeColumn(AceColumnType t) 723 { 724 return ((t == AceColumnType.CreationTime) || 725 (t == AceColumnType.LastModificationTime) || 726 (t == AceColumnType.LastAccessTime) || 727 (t == AceColumnType.ExpiryTime) || 728 (t == AceColumnType.ExpiryTimeDateOnly) || 729 (t == AceColumnType.LastPasswordModTime)); 730 731 /* bool bTime = false; 732 switch(t) 733 { 734 case AceColumnType.CreationTime: 735 case AceColumnType.LastModificationTime: 736 case AceColumnType.LastAccessTime: 737 case AceColumnType.ExpiryTime: 738 case AceColumnType.ExpiryTimeDateOnly: 739 case AceColumnType.LastPasswordModTime: 740 bTime = true; 741 break; 742 default: 743 break; 744 } 745 746 return bTime; */ 747 } 748 GetTextAlign(AceColumnType t)749 public static HorizontalAlignment GetTextAlign(AceColumnType t) 750 { 751 if((t == AceColumnType.Size) || (t == AceColumnType.HistoryCount) || 752 (t == AceColumnType.AttachmentCount)) 753 return HorizontalAlignment.Right; 754 755 return HorizontalAlignment.Left; 756 } 757 } 758 } 759