From 3a5a9c6e094ec99d0e490a7a8807003b38e9b6eb Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sun, 4 Jan 2026 16:02:45 +0100 Subject: [PATCH] Implement "import from clipboard" for skills --- gui/characterSelection.py | 103 ++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 10 deletions(-) diff --git a/gui/characterSelection.py b/gui/characterSelection.py index f6bbca494..51c79f737 100644 --- a/gui/characterSelection.py +++ b/gui/characterSelection.py @@ -29,7 +29,7 @@ import config import gui.globalEvents as GE import gui.mainFrame from gui.bitmap_loader import BitmapLoader -from gui.utils.clipboard import toClipboard +from gui.utils.clipboard import toClipboard, fromClipboard from service.character import Character from service.fit import Fit @@ -96,7 +96,7 @@ class CharacterSelection(wx.Panel): sFit = Fit.getInstance() fit = sFit.getFit(self.mainFrame.getActiveFit()) - if not fit or not self.needsSkills: + if not fit: return pos = wx.GetMousePosition() @@ -104,17 +104,23 @@ class CharacterSelection(wx.Panel): menu = wx.Menu() - grantItem = menu.Append(wx.ID_ANY, _t("Grant Missing Skills")) - self.Bind(wx.EVT_MENU, self.grantMissingSkills, grantItem) + if self.needsSkills: + grantItem = menu.Append(wx.ID_ANY, _t("Grant Missing Skills")) + self.Bind(wx.EVT_MENU, self.grantMissingSkills, grantItem) - exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills")) - self.Bind(wx.EVT_MENU, self.exportSkills, exportItem) + exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills")) + self.Bind(wx.EVT_MENU, self.exportSkills, exportItem) - exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (condensed)")) - self.Bind(wx.EVT_MENU, self.exportSkillsCondensed, exportItem) + exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (condensed)")) + self.Bind(wx.EVT_MENU, self.exportSkillsCondensed, exportItem) - exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (EVEMon)")) - self.Bind(wx.EVT_MENU, self.exportSkillsEveMon, exportItem) + exportItem = menu.Append(wx.ID_ANY, _t("Copy Missing Skills (EVEMon)")) + self.Bind(wx.EVT_MENU, self.exportSkillsEveMon, exportItem) + + menu.AppendSeparator() + + importItem = menu.Append(wx.ID_ANY, _t("Import Skills from Clipboard")) + self.Bind(wx.EVT_MENU, self.importSkillsFromClipboard, importItem) self.PopupMenu(menu, pos) @@ -326,6 +332,83 @@ class CharacterSelection(wx.Panel): toClipboard(list) + def importSkillsFromClipboard(self, evt): + charID = self.getActiveCharacter() + if charID is None: + return + + sChar = Character.getInstance() + char = sChar.getCharacter(charID) + + text = fromClipboard() + if not text: + with wx.MessageDialog(self, _t("Clipboard is empty"), _t("Error"), wx.OK | wx.ICON_ERROR) as dlg: + dlg.ShowModal() + return + + try: + lines = text.strip().splitlines() + imported = 0 + errors = [] + + for line in lines: + line = line.strip() + if not line: + continue + + try: + parts = line.rsplit(None, 1) + if len(parts) != 2: + errors.append(_t("Invalid format: {}").format(line)) + continue + + skillName = parts[0] + levelStr = parts[1] + + try: + level = int(levelStr) + except ValueError: + try: + level = roman.fromRoman(levelStr.upper()) + except (roman.InvalidRomanNumeralError, ValueError): + errors.append(_t("Invalid level format: {}").format(line)) + continue + + if level < 0 or level > 5: + errors.append(_t("Level must be between 0 and 5: {}").format(line)) + continue + + skill = char.getSkill(skillName) + sChar.changeLevel(charID, skill.item.ID, level) + imported += 1 + + except KeyError as e: + errors.append(_t("Skill not found: {}").format(skillName)) + pyfalog.error("Skill not found: '{}'", skillName) + except Exception as e: + errors.append(_t("Error processing line '{}': {}").format(line, str(e))) + pyfalog.error("Error importing skill from line '{}': {}", line, e) + + if imported > 0: + self.refreshCharacterList() + wx.PostEvent(self.mainFrame, GE.CharListUpdated()) + fitID = self.mainFrame.getActiveFit() + if fitID is not None: + wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=(fitID,))) + + if errors: + errorMsg = _t("Imported {} skill(s). Errors:\n{}").format(imported, "\n".join(errors)) + with wx.MessageDialog(self, errorMsg, _t("Import Skills"), wx.OK | wx.ICON_WARNING) as dlg: + dlg.ShowModal() + elif imported > 0: + with wx.MessageDialog(self, _t("Successfully imported {} skill(s)").format(imported), _t("Import Skills"), wx.OK) as dlg: + dlg.ShowModal() + + except Exception as e: + pyfalog.error("Error importing skills from clipboard: {}", e) + with wx.MessageDialog(self, _t("Error importing skills. Please check the log file."), _t("Error"), wx.OK | wx.ICON_ERROR) as dlg: + dlg.ShowModal() + def _buildSkillsTooltip(self, reqs, currItem="", tabulationLevel=0): tip = "" sCharacter = Character.getInstance()