/// <summary> /// Imports data from a serialization object. /// </summary> /// <param name="serial"></param> private void Import(SerializableCCPCharacter serial) { Import((SerializableSettingsCharacter)serial); // Skill queue SkillQueue.Import(serial.SkillQueue); // Market orders MarketOrdersImport(serial.MarketOrders); // Contracts ContractsImport(serial.Contracts); // Industry jobs IndustryJobsImport(serial.IndustryJobs); // EVE mail messages IDs EVEMailMessages.Import(serial.EveMailMessagesIDs); // EVE notifications IDs EVENotifications.Import(serial.EveNotificationsIDs); // Kill Logs KillLog.ImportFromCacheFile(); // Fire the global event EveMonClient.OnCharacterUpdated(this); }
/// <summary> /// Initializes a new instance of the <see cref="KillReportWindow"/> class. /// Constructor used in WindowsFactory /// </summary> /// <param name="killLog">The kill log.</param> public KillReportWindow(KillLog killLog) : this() { RememberPositionKey = "KillReportWindow"; killReportVictim.KillLog = killLog; killReportInvolvedParties.KillLog = killLog; killReportFittingContent.KillLog = killLog; }
/// <summary> /// Copies the kill info to clipboard. /// </summary> public static void CopyKillInfoToClipboard(KillLog killLog) { try { string killLogInfoText = ExportKillLogInfo(killLog); if (String.IsNullOrEmpty(killLogInfoText)) { MessageBox.Show(@"No kill info was available. Nothing has been copied to the clipboard.", @"Copy", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Clipboard.SetText(killLogInfoText, TextDataFormat.Text); MessageBox.Show(@"The kill info have been copied to the clipboard.", @"Copy", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (ExternalException ex) { // Occurs when another process is using the clipboard ExceptionHandler.LogException(ex, true); MessageBox.Show(@"Couldn't complete the operation, the clipboard is being used by another process. " + @"Wait a few moments and try again."); } }
/// <summary> /// When user moves over the list we display a cursor indicating there is a context menu available. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param> private void lvKillLog_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) return; m_selectedKillLog = lvKillLog.GetItemAt(e.X, e.Y)?.Tag as KillLog; lvKillLog.Cursor = m_selectedKillLog != null ? CustomCursors.ContextMenu : Cursors.Default; }
/// <summary> /// Exports the kill log info. /// </summary> /// <returns></returns> private static string ExportKillLogInfo(KillLog killLog) { if (killLog == null) return String.Empty; StringBuilder sb = new StringBuilder(); sb .AppendLine(killLog.KillTime.DateTimeToDotFormattedString()) .AppendLine() .AppendLine($"Victim: {killLog.Victim.Name}") .AppendLine($"Corp: {killLog.Victim.CorporationName}") .AppendLine($"Alliance: {killLog.Victim.AllianceName}") .AppendLine($"Faction: {killLog.Victim.FactionName}") .AppendLine($"Destroyed: {killLog.Victim.ShipTypeName}") .AppendLine($"System: {killLog.SolarSystem?.Name}") .AppendLine(FormattableString.Invariant($"Security: {killLog.SolarSystem?.SecurityLevel:N1}")) .AppendLine(FormattableString.Invariant($"Damage Taken: {killLog.Victim.DamageTaken:N}")); sb.AppendLine(); sb.AppendLine("Involved parties:"); sb.AppendLine(); foreach (SerializableKillLogAttackersListItem attacker in killLog.Attackers.OrderByDescending(x => x.DamageDone)) { // Append info for NPC or player entities if (String.IsNullOrEmpty(attacker.Name)) sb.Append($"Name: {attacker.ShipTypeName} / {attacker.CorporationName}"); else sb.Append($"Name: {attacker.Name}"); if (attacker.FinalBlow) sb.Append(" (laid the final blow)"); sb.AppendLine(); // Append info only for player entities if (!String.IsNullOrEmpty(attacker.Name)) { sb .AppendLine(FormattableString.Invariant($"Security: {attacker.SecurityStatus:N1}")) .AppendLine($"Corp: {attacker.CorporationName}") .AppendLine( $"Alliance: {(attacker.AllianceName == EveMonConstants.UnknownText ? "None" : attacker.AllianceName)}") .AppendLine( $"Faction: {(attacker.FactionName == EveMonConstants.UnknownText ? "None" : attacker.FactionName)}") .AppendLine($"Ship: {attacker.ShipTypeName}") .AppendLine($"Weapon: {attacker.WeaponTypeName}"); } sb .AppendLine(FormattableString.Invariant($"Damage Done: {attacker.DamageDone:N}")) .AppendLine(); } if (killLog.Items.Any(x => x.QtyDestroyed != 0)) { sb.AppendLine("Destroyed items:"); sb.AppendLine(); AppendDestroyedItems(sb, killLog.Items.Where(x => x.QtyDestroyed != 0)); sb.AppendLine(); } if (killLog.Items.Any(x => x.QtyDropped != 0)) { sb.AppendLine("Dropped items:"); sb.AppendLine(); AppendDroppedItems(sb, killLog.Items.Where(x => x.QtyDropped != 0)); sb.AppendLine(); } sb.AppendLine("<-- Generated by EVEMon -->"); return sb.ToString(); }
/// <summary> /// Draws the text for a loss. /// </summary> /// <param name="killLog">The kill log.</param> /// <param name="e">The <see cref="System.Windows.Forms.DrawItemEventArgs"/> instance containing the event data.</param> private void DrawLossText(KillLog killLog, DrawItemEventArgs e) { Graphics g = e.Graphics; // Texts string killTimeSinceText = killLog.TimeSinceKill .ToDescriptiveText(DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText | DescriptiveTextOptions.FullText); string killTimeText = $"({killTimeSinceText} ago)"; string finalBlowAttackerCorpAndAllianceName = GetText(killLog.FinalBlowAttacker.CorporationName, killLog.FinalBlowAttacker.AllianceName); string finalBlowAttackerShipAndModuleName = GetText(killLog.FinalBlowAttacker.ShipTypeName, killLog.FinalBlowAttacker.WeaponTypeName); // Measure texts Size killShipNameTextSize = TextRenderer.MeasureText(g, killLog.Victim.ShipTypeName, m_killBoldFont, Size.Empty, Format); Size killTimeTextSize = TextRenderer.MeasureText(g, killTimeText, m_killFont, Size.Empty, Format); Size finalBlowAttackerCorpAndAllianceNameSize = TextRenderer.MeasureText(g, finalBlowAttackerCorpAndAllianceName, m_killFont, Size.Empty, Format); Size finalBlowAttackerShipAndModuleNameSize = TextRenderer.MeasureText(g, finalBlowAttackerShipAndModuleName, m_killFont, Size.Empty, Format); // Draw texts TextRenderer.DrawText(g, killLog.Victim.ShipTypeName, m_killBoldFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top, killShipNameTextSize.Width + PadLeft, killShipNameTextSize.Height), Color.Black); TextRenderer.DrawText(g, killTimeText, m_killFont, new Rectangle( e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight * 3 + killShipNameTextSize.Width, e.Bounds.Top, killTimeTextSize.Width + PadLeft, killTimeTextSize.Height), Color.Black); TextRenderer.DrawText(g, finalBlowAttackerCorpAndAllianceName, m_killFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top + killShipNameTextSize.Height, finalBlowAttackerCorpAndAllianceNameSize.Width + PadLeft, finalBlowAttackerCorpAndAllianceNameSize.Height), Color.Black); TextRenderer.DrawText(g, finalBlowAttackerShipAndModuleName, m_killFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top + killShipNameTextSize.Height + finalBlowAttackerCorpAndAllianceNameSize.Height, finalBlowAttackerShipAndModuleNameSize.Width + PadLeft, finalBlowAttackerShipAndModuleNameSize.Height), Color.Black); }
/// <summary> /// Handles the MouseMove event of the lbKillLog control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param> private void lbKillLog_MouseMove(object sender, MouseEventArgs e) { for (int i = 0; i < lbKillLog.Items.Count; i++) { // Skip until we find an item Rectangle rect = lbKillLog.GetItemRectangle(i); if (!rect.Contains(e.Location)) continue; // Skip if we are over the "copy kill info" image rect = GetCopyKillInfoRect(lbKillLog.GetItemRectangle(i)); if (rect.Contains(e.Location)) { lbKillLog.Cursor = Cursors.Default; DisplayTooltip(); return; } toolTip.Active = false; Object item = lbKillLog.Items[i]; m_selectedKillLog = item as KillLog; lbKillLog.Cursor = m_selectedKillLog != null ? CustomCursors.ContextMenu : Cursors.Default; return; } toolTip.Active = false; lbKillLog.Cursor = Cursors.Default; }
/// <summary> /// Draws the text for a kill. /// </summary> /// <param name="killLog">The kill log.</param> /// <param name="e">The <see cref="System.Windows.Forms.DrawItemEventArgs"/> instance containing the event data.</param> private void DrawKillText(KillLog killLog, DrawItemEventArgs e) { Graphics g = e.Graphics; // Texts string victimNameText = killLog.Victim.Name; string killTimeSinceText = killLog.TimeSinceKill .ToDescriptiveText(DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText | DescriptiveTextOptions.FullText); string killTimeText = $"({killTimeSinceText} ago)"; string victimNameCorpAndAllianceName = GetText(killLog.Victim.CorporationName, killLog.Victim.AllianceName); string whatAndWhereInfo = $"{killLog.Victim.ShipTypeName}, " + $"{killLog.SolarSystem?.Name}, " + $"{killLog.SolarSystem?.Constellation?.Region?.Name}, " + $"{killLog.SolarSystem?.SecurityLevel:N1}"; // Measure texts Size victimNameTextSize = TextRenderer.MeasureText(g, victimNameText, m_killBoldFont, Size.Empty, Format); Size killTimeTextSize = TextRenderer.MeasureText(g, killTimeText, m_killFont, Size.Empty, Format); Size victimNameCorpAndAllianceNameSize = TextRenderer.MeasureText(g, victimNameCorpAndAllianceName, m_killFont, Size.Empty, Format); Size whatAndWhereInfoSize = TextRenderer.MeasureText(g, whatAndWhereInfo, m_killFont, Size.Empty, Format); // Draw texts TextRenderer.DrawText(g, victimNameText, m_killBoldFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top, victimNameTextSize.Width + PadLeft, victimNameTextSize.Height), Color.Black); TextRenderer.DrawText(g, killTimeText, m_killFont, new Rectangle( e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight * 3 + victimNameTextSize.Width, e.Bounds.Top, killTimeTextSize.Width + PadLeft, killTimeTextSize.Height), Color.Black); TextRenderer.DrawText(g, victimNameCorpAndAllianceName, m_killFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top + victimNameTextSize.Height, victimNameCorpAndAllianceNameSize.Width + PadLeft, victimNameCorpAndAllianceNameSize.Height), Color.Black); TextRenderer.DrawText(g, whatAndWhereInfo, m_killFont, new Rectangle(e.Bounds.Left + killLog.VictimShipImage.Width + 4 + PadRight, e.Bounds.Top + victimNameTextSize.Height + victimNameCorpAndAllianceNameSize.Height, whatAndWhereInfoSize.Width + PadLeft, whatAndWhereInfoSize.Height), Color.Black); }
/// <summary> /// Draws the list item for the given kill /// </summary> /// <param name="killLog"></param> /// <param name="e"></param> private void DrawItem(KillLog killLog, DrawItemEventArgs e) { Graphics g = e.Graphics; // Draw background g.FillRectangle(e.Index % 2 == 0 ? Brushes.White : Brushes.LightGray, e.Bounds); // Draw text for a kill if (killLog.Group == KillGroup.Kills) DrawKillText(killLog, e); // Draw text for a loss if (killLog.Group == KillGroup.Losses) DrawLossText(killLog, e); // If 'Safe for work' draw 'copy' text if (Settings.UI.SafeForWork) { m_copyKillInfoTextSize = TextRenderer.MeasureText(g, CopyKillInfoText, m_killFont, Size.Empty, Format); m_copyPositionFromRight = m_copyKillInfoTextSize.Width + PadRight; TextRenderer.DrawText(g, CopyKillInfoText, m_killFont, new Rectangle(e.Bounds.Right - m_copyPositionFromRight, e.Bounds.Top + PadTop, m_copyKillInfoTextSize.Width + PadLeft, m_copyKillInfoTextSize.Height), Color.Black); } // Draw images if (Settings.UI.SafeForWork) return; // Draw the kill image g.DrawImage(killLog.VictimShipImage, new Rectangle(e.Bounds.Left + PadLeft / 2, KillDetailHeight / 2 - killLog.VictimShipImage.Height / 2 + e.Bounds.Top, killLog.VictimShipImage.Width, killLog.VictimShipImage.Height)); // Draw the copy image m_copyPositionFromRight = 24; g.DrawImage(Resources.Copy, new Rectangle(e.Bounds.Right - m_copyPositionFromRight, e.Bounds.Top + PadTop, Resources.Copy.Width, Resources.Copy.Height)); }
/// <summary> /// Updates the listview sub-item. /// </summary> /// <param name="kill"></param> /// <param name="item"></param> /// <param name="column"></param> private static void SetColumn(KillLog kill, ListViewItem.ListViewSubItem item, ColumnHeader column) { switch (column.Index) { case 0: item.Text = $"{kill.KillTime.ToLocalTime()}"; break; case 1: item.Text = kill.Victim.ShipTypeName; break; case 2: item.Text = kill.Victim.Name; break; case 3: item.Text = kill.Victim.CorporationName; break; case 4: item.Text = kill.Victim.AllianceName; break; case 5: item.Text = kill.Victim.FactionName; break; default: throw new NotImplementedException(); } }
/// <summary> /// Creates the list view sub items. /// </summary> /// <param name="kill">The kill report.</param> /// <param name="item">The item.</param> private ListViewItem CreateSubItems(KillLog kill, ListViewItem item) { // Add enough subitems to match the number of columns while (item.SubItems.Count < lvKillLog.Columns.Count + 1) { item.SubItems.Add(String.Empty); } // Creates the subitems for (int i = 0; i < lvKillLog.Columns.Count; i++) { SetColumn(kill, item.SubItems[i], lvKillLog.Columns[i]); } return item; }
/// <summary> /// Checks the given text matches the item. /// </summary> /// <param name="x">The x.</param> /// <param name="text">The text.</param> /// <returns> /// <c>true</c> if [is text matching] [the specified x]; otherwise, <c>false</c>. /// </returns> private static bool IsTextMatching(KillLog x, string text) => String.IsNullOrEmpty(text) || x.Victim.ShipTypeName.ToUpperInvariant().Contains(text, ignoreCase: true) || x.Victim.Name.ToUpperInvariant().Contains(text, ignoreCase: true) || x.Victim.CorporationName.ToUpperInvariant().Contains(text, ignoreCase: true) || x.Victim.AllianceName.ToUpperInvariant().Contains(text, ignoreCase: true) || x.Victim.FactionName.ToUpperInvariant().Contains(text, ignoreCase: true);