import sys
from PyQt6 . QtWidgets import ( QApplication , QMainWindow , QWidget , QVBoxLayout , QHBoxLayout , QListWidget , QLineEdit ,
QLabel , QCheckBox , QPushButton , QFormLayout , QListWidgetItem , QSplitter , QTreeWidget ,
QTreeWidgetItem , QDialog , QDialogButtonBox , QComboBox , QMessageBox , QSpinBox , QMenu )
from PyQt6 . QtCore import Qt , QSize
from PyQt6 . QtGui import QPixmap , QFontMetrics , QColor , QAction
import sqlite3
import json
import os
# Add the parent directory to the Python path
sys . path . append ( os . path . dirname ( os . path . dirname ( os . path . abspath ( __file__ ) ) ) )
# Now try to import
from DataGatherers . update_location_information import process_pokemon_for_location_data
from DataGatherers . cache_manager import CacheManager
class EvolutionEditDialog ( QDialog ) :
def __init__ ( self , parent = None , from_pfic = None , to_pfic = None , method = None ) :
super ( ) . __init__ ( parent )
self . setWindowTitle ( " Edit Evolution " )
self . setModal ( True )
layout = QVBoxLayout ( self )
self . from_combo = QComboBox ( )
self . to_combo = QComboBox ( )
self . method_edit = QLineEdit ( method )
layout . addWidget ( QLabel ( " From Pokémon: " ) )
layout . addWidget ( self . from_combo )
layout . addWidget ( QLabel ( " To Pokémon: " ) )
layout . addWidget ( self . to_combo )
layout . addWidget ( QLabel ( " Evolution Method: " ) )
layout . addWidget ( self . method_edit )
self . button_box = QDialogButtonBox ( QDialogButtonBox . StandardButton . Ok | QDialogButtonBox . StandardButton . Cancel )
self . button_box . accepted . connect ( self . accept )
self . button_box . rejected . connect ( self . reject )
layout . addWidget ( self . button_box )
self . delete_button = QPushButton ( " Delete Evolution " )
self . delete_button . clicked . connect ( self . delete_evolution )
layout . addWidget ( self . delete_button )
self . populate_combos ( from_pfic , to_pfic )
def populate_combos ( self , from_pfic , to_pfic ) :
cursor = self . parent ( ) . cursor
cursor . execute ( ' SELECT PFIC, name, form_name FROM pokemon_forms ORDER BY name, form_name ' )
for pfic , name , form_name in cursor . fetchall ( ) :
display_name = f " { name } ( { form_name } ) " if form_name else name
self . from_combo . addItem ( display_name , pfic )
self . to_combo . addItem ( display_name , pfic )
if from_pfic :
self . from_combo . setCurrentIndex ( self . from_combo . findData ( from_pfic ) )
if to_pfic :
self . to_combo . setCurrentIndex ( self . to_combo . findData ( to_pfic ) )
def delete_evolution ( self ) :
self . done ( 2 ) # Use a custom return code for delete action
def parse_pfic ( pfic ) :
parts = pfic . split ( ' - ' )
return tuple ( int ( part ) if part . isdigit ( ) else part for part in parts )
class DBEditor ( QMainWindow ) :
def __init__ ( self ) :
super ( ) . __init__ ( )
self . setWindowTitle ( " Pokémon Database Editor " )
self . setGeometry ( 100 , 100 , 1000 , 600 )
self . conn = sqlite3 . connect ( ' :memory: ' ) # Use in-memory database for runtime
self . cursor = self . conn . cursor ( )
self . init_database ( )
self . patches = self . load_and_apply_patches ( )
self . encounter_cache = { } # Add this line
self . init_ui ( )
#self.load_pokemon_list() # Make sure this is called after init_ui
def init_database ( self ) :
# Create or open the file-based database
disk_conn = sqlite3 . connect ( ' pokemon_forms.db ' )
disk_cursor = disk_conn . cursor ( )
# Create tables in the file-based database
self . create_games_table ( disk_cursor )
self . create_pokemon_forms_table ( disk_cursor )
self . create_pokemon_storage_table ( disk_cursor )
self . create_evolution_chains_table ( disk_cursor )
self . create_exclusive_encounter_groups_table ( disk_cursor )
self . create_encounters_table ( disk_cursor )
self . create_mark_table ( disk_cursor )
# Commit changes to the file-based database
disk_conn . commit ( )
# Copy the file-based database to the in-memory database
disk_conn . backup ( self . conn )
# Close the file-based database connection
disk_conn . close ( )
# Create tables in the in-memory database (in case they weren't copied)
self . create_pokemon_forms_table ( self . cursor )
self . create_pokemon_storage_table ( self . cursor )
self . create_evolution_chains_table ( self . cursor )
self . create_exclusive_encounter_groups_table ( self . cursor )
self . create_encounters_table ( self . cursor )
# Commit changes to the in-memory database
self . conn . commit ( )
def create_pokemon_forms_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS pokemon_forms (
PFIC TEXT PRIMARY KEY ,
name TEXT NOT NULL ,
form_name TEXT ,
national_dex INTEGER NOT NULL ,
generation INTEGER NOT NULL ,
is_baby_form BOOLEAN
)
''' )
def create_pokemon_storage_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS pokemon_storage (
PFIC TEXT PRIMARY KEY ,
storable_in_home BOOLEAN NOT NULL ,
FOREIGN KEY ( PFIC ) REFERENCES pokemon_forms ( PFIC )
)
''' )
def create_evolution_chains_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS evolution_chains (
from_pfic TEXT ,
to_pfic TEXT ,
method TEXT ,
PRIMARY KEY ( from_pfic , to_pfic ) ,
FOREIGN KEY ( from_pfic ) REFERENCES pokemon_forms ( PFIC ) ,
FOREIGN KEY ( to_pfic ) REFERENCES pokemon_forms ( PFIC )
)
''' )
def create_exclusive_encounter_groups_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS exclusive_encounter_groups (
id INTEGER PRIMARY KEY AUTOINCREMENT ,
group_name TEXT NOT NULL ,
description TEXT
)
''' )
def create_encounters_table ( self , cursor ) :
# First, check if the table exists
cursor . execute ( " SELECT name FROM sqlite_master WHERE type= ' table ' AND name= ' encounters ' " )
table_exists = cursor . fetchone ( ) is not None
if not table_exists :
# If the table doesn't exist, create it with all columns
cursor . execute ( '''
CREATE TABLE encounters (
id INTEGER PRIMARY KEY AUTOINCREMENT ,
pfic TEXT ,
game TEXT ,
location TEXT ,
day TEXT ,
time TEXT ,
dual_slot TEXT ,
static_encounter BOOLEAN ,
static_encounter_count INTEGER ,
extra_text TEXT ,
stars TEXT ,
fishing BOOLEAN ,
rods TEXT ,
exclusive_group_id INTEGER ,
FOREIGN KEY ( pfic ) REFERENCES pokemon_forms ( PFIC ) ,
FOREIGN KEY ( exclusive_group_id ) REFERENCES exclusive_encounter_groups ( id )
)
''' )
else :
# If the table exists, check if the exclusive_group_id column exists
cursor . execute ( " PRAGMA table_info(encounters) " )
columns = [ column [ 1 ] for column in cursor . fetchall ( ) ]
if ' exclusive_group_id ' not in columns :
# If the column doesn't exist, add it
cursor . execute ( '''
ALTER TABLE encounters
ADD COLUMN exclusive_group_id INTEGER
REFERENCES exclusive_encounter_groups ( id )
''' )
if ' starter ' not in columns :
# If the column doesn't exist, add it
cursor . execute ( '''
ALTER TABLE encounters
ADD COLUMN starter BOOLEAN
''' )
def create_mark_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS marks (
id INTEGER PRIMARY KEY ,
name TEXT NOT NULL ,
icon_path TEXT NOT NULL
)
''' )
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS mark_game_associations (
mark_id INTEGER ,
game_id INTEGER ,
FOREIGN KEY ( mark_id ) REFERENCES marks ( id ) ,
FOREIGN KEY ( game_id ) REFERENCES games ( id ) ,
PRIMARY KEY ( mark_id , game_id )
)
''' )
marks = [
( " Game Boy " , " images/marks/GB_icon_HOME.png " , [ " Red " , " Blue " , " Yellow " , " Gold " , " Silver " , " Crystal " , " Ruby " , " Sapphire " , " Emerald " , " FireRed " , " LeafGreen " ] ) ,
( " Kalos " , " images/marks/Blue_pentagon_HOME.png " , [ " X " , " Y " , " Omega Ruby " , " Alpha Sapphire " ] ) ,
( " Alola " , " images/marks/Black_clover_HOME.png " , [ " Sun " , " Moon " , " Ultra Sun " , " Ultra Moon " ] ) ,
( " Let ' s Go " , " images/marks/Let ' s_Go_icon_HOME.png " , [ " Let ' s Go Pikachu " , " Let ' s Go Eevee " ] ) ,
( " Galar " , " images/marks/Galar_symbol_HOME.png " , [ " Sword " , " Shield " ] ) ,
( " Sinnoh " , " images/marks/BDSP_icon_HOME.png " , [ " Brilliant Diamond " , " Shining Pearl " ] ) ,
( " Hisui " , " images/marks/Arceus_mark_HOME.png " , [ " Legends Arceus " ] ) ,
( " Paldea " , " images/marks/Paldea_icon_HOME.png " , [ " Scarlet " , " Violet " ] ) ,
]
for mark in marks :
cursor . execute ( '''
INSERT OR IGNORE INTO marks ( name , icon_path )
VALUES ( ? , ? )
''' , (mark[0], mark[1]))
mark_id = cursor . lastrowid
for game_name in mark [ 2 ] :
cursor . execute ( '''
INSERT OR IGNORE INTO mark_game_associations ( mark_id , game_id )
SELECT ? , id FROM games WHERE name = ?
''' , (mark_id, game_name))
def create_games_table ( self , cursor ) :
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS games (
id INTEGER PRIMARY KEY ,
name TEXT NOT NULL ,
generation INTEGER NOT NULL
)
''' )
cursor . execute ( '''
CREATE TABLE IF NOT EXISTS alternate_game_names (
id INTEGER PRIMARY KEY ,
game_id INTEGER NOT NULL ,
alternate_name TEXT NOT NULL ,
FOREIGN KEY ( game_id ) REFERENCES games ( id ) ,
UNIQUE ( alternate_name COLLATE NOCASE )
)
''' )
games = [
( " Red " , 1 , [ " Red Version " ] ) ,
( " Blue " , 1 , [ " Blue Version " ] ) ,
( " Yellow " , 1 , [ " Yellow Version " ] ) ,
( " Gold " , 2 , [ " Gold Version " ] ) ,
( " Silver " , 2 , [ " Silver Version " ] ) ,
( " Crystal " , 2 , [ " Crystal Version " ] ) ,
( " Ruby " , 3 , [ " Ruby Version " ] ) ,
( " Sapphire " , 3 , [ " Sapphire Version " ] ) ,
( " Emerald " , 3 , [ " Emerald Version " ] ) ,
( " FireRed " , 3 , [ " Fire Red " , " Fire-Red " ] ) ,
( " LeafGreen " , 3 , [ " Leaf Green " , " Leaf-Green " ] ) ,
( " Diamond " , 4 , [ " Diamond Version " ] ) ,
( " Pearl " , 4 , [ " Pearl Version " ] ) ,
( " Platinum " , 4 , [ " Platinum Version " ] ) ,
( " HeartGold " , 4 , [ " Heart Gold " , " Heart-Gold " ] ) ,
( " SoulSilver " , 4 , [ " Soul Silver " , " Soul-Silver " ] ) ,
( " Black " , 5 , [ " Black Version " ] ) ,
( " White " , 5 , [ " White Version " ] ) ,
( " Black 2 " , 5 , [ " Black Version 2 " , " Black-2 " ] ) ,
( " White 2 " , 5 , [ " White Version 2 " , " White-2 " ] ) ,
( " X " , 6 , [ " X Version " ] ) ,
( " Y " , 6 , [ " Y Version " ] ) ,
( " Omega Ruby " , 6 , [ " Omega Ruby Version " , " Omega-Ruby " ] ) ,
( " Alpha Sapphire " , 6 , [ " Alpha Sapphire Version " , " Alpha-Sapphire " ] ) ,
( " Sun " , 7 , [ " Sun Version " ] ) ,
( " Moon " , 7 , [ " Moon Version " ] ) ,
( " Ultra Sun " , 7 , [ " Ultra Sun Version " , " Ultra-Sun " ] ) ,
( " Ultra Moon " , 7 , [ " Ultra Moon Version " , " Ultra-Moon " ] ) ,
( " Let ' s Go Pikachu " , 7 , [ " Let ' s Go, Pikachu! " , " Lets Go Pikachu " ] ) ,
( " Let ' s Go Eevee " , 7 , [ " Let ' s Go, Eevee! " , " Lets Go Eevee " ] ) ,
( " Sword " , 8 , [ " Sword Version " ] ) ,
( " Shield " , 8 , [ " Shield Version " ] ) ,
( " Expansion Pass " , 8 , [ " Expansion Pass (Sword) " , " Expansion Pass (Shield) " ] ) ,
( " Brilliant Diamond " , 8 , [ " Brilliant Diamond Version " , " Brilliant-Diamond " ] ) ,
( " Shining Pearl " , 8 , [ " Shining Pearl Version " , " Shining-Pearl " ] ) ,
( " Legends Arceus " , 8 , [ " Legends: Arceus " , " Legends-Arceus " ] ) ,
( " Scarlet " , 9 , [ " Scarlet Version " ] ) ,
( " Violet " , 9 , [ " Violet Version " ] ) ,
( " The Teal Mask " , 9 , [ " The Teal Mask Version " , " The Teal Mask (Scarlet) " , " The Teal Mask (Violet) " ] ) ,
( " The Hidden Treasure of Area Zero " , 9 , [ " The Hidden Treasure of Area Zero Version " , " The Hidden Treasure of Area Zero (Scarlet) " , " The Hidden Treasure of Area Zero (Violet) " ] ) ,
( " Pokémon Home " , 98 , [ " Pokémon HOME " ] ) ,
( " Pokémon Go " , 99 , [ " Pokémon GO " ] ) ,
]
for game in games :
cursor . execute ( '''
INSERT OR IGNORE INTO games ( name , generation )
VALUES ( ? , ? )
''' , (game[0], game[1]))
game_id = cursor . lastrowid
# Insert alternate names
for alt_name in game [ 2 ] :
cursor . execute ( '''
INSERT OR IGNORE INTO alternate_game_names ( game_id , alternate_name )
VALUES ( ? , ? )
''' , (game_id, alt_name))
def load_and_apply_patches ( self ) :
try :
with open ( ' patches.json ' , ' r ' ) as f :
patches = json . load ( f )
except FileNotFoundError :
patches = { }
# Apply patches to the in-memory database
for patch_key , patch in patches . items ( ) :
if patch_key . startswith ( ' evolution_ ' ) :
from_pfic , to_pfic = patch_key . split ( ' _ ' ) [ 1 : ]
if patch [ ' action ' ] == ' delete ' :
self . cursor . execute ( '''
DELETE FROM evolution_chains
WHERE from_pfic = ? AND to_pfic = ?
''' , (from_pfic, to_pfic))
elif patch [ ' action ' ] == ' update ' :
self . cursor . execute ( '''
UPDATE evolution_chains
SET from_pfic = ? , to_pfic = ? , method = ?
WHERE from_pfic = ? AND to_pfic = ?
''' , (patch[ ' new_from_pfic ' ], patch[ ' new_to_pfic ' ], patch[ ' new_method ' ], from_pfic, to_pfic))
elif patch [ ' action ' ] == ' add ' :
self . cursor . execute ( '''
INSERT OR REPLACE INTO evolution_chains ( from_pfic , to_pfic , method )
VALUES ( ? , ? , ? )
''' , (patch[ ' from_pfic ' ], patch[ ' to_pfic ' ], patch[ ' method ' ]))
else : # pokemon_storage patches
self . cursor . execute ( '''
UPDATE pokemon_storage
SET storable_in_home = ?
WHERE PFIC = ?
''' , (patch[ ' storable_in_home ' ], patch_key))
self . conn . commit ( )
return patches
def save_patches ( self ) :
with open ( ' patches.json ' , ' w ' ) as f :
json . dump ( self . patches , f )
def init_ui ( self ) :
central_widget = QWidget ( )
self . setCentralWidget ( central_widget )
main_layout = QHBoxLayout ( central_widget )
# Left side: Search and List
left_layout = QVBoxLayout ( )
search_layout = QHBoxLayout ( )
self . search_bar = QLineEdit ( )
self . search_bar . setPlaceholderText ( " Search Pokémon... " )
self . search_bar . textChanged . connect ( self . filter_pokemon_list )
search_layout . addWidget ( self . search_bar )
left_layout . addLayout ( search_layout )
self . pokemon_list = QListWidget ( )
self . pokemon_list . setContextMenuPolicy ( Qt . ContextMenuPolicy . CustomContextMenu )
self . pokemon_list . customContextMenuRequested . connect ( self . show_pokemon_context_menu )
self . pokemon_list . currentItemChanged . connect ( self . load_pokemon_details )
left_layout . addWidget ( self . pokemon_list )
# Move the checkbox here, after the pokemon_list
self . highlight_no_encounters = QCheckBox ( " Highlight Pokémon without encounters " )
self . highlight_no_encounters . stateChanged . connect ( self . toggle_highlight_mode )
left_layout . addWidget ( self . highlight_no_encounters )
# Add the new checkbox for filtering Home-storable Pokémon
self . filter_home_storable = QCheckBox ( " Show only Home-storable Pokémon " )
self . filter_home_storable . stateChanged . connect ( self . filter_pokemon_list )
left_layout . addWidget ( self . filter_home_storable )
# Right side: Edit panel
right_layout = QHBoxLayout ( )
# Left side of right panel: Text information
text_layout = QVBoxLayout ( )
self . edit_form = QFormLayout ( )
self . name_label = QLabel ( )
self . form_name_label = QLabel ( )
self . national_dex_label = QLabel ( )
self . generation_label = QLabel ( )
self . home_checkbox = QCheckBox ( " Available in Home " )
self . is_baby_form_checkbox = QCheckBox ( " Is Baby Form " )
self . edit_form . addRow ( " Name: " , self . name_label )
self . edit_form . addRow ( " Form: " , self . form_name_label )
self . edit_form . addRow ( " National Dex: " , self . national_dex_label )
self . edit_form . addRow ( " Generation: " , self . generation_label )
self . edit_form . addRow ( self . home_checkbox )
self . edit_form . addRow ( self . is_baby_form_checkbox )
text_layout . addLayout ( self . edit_form )
# Evolution chain tree
self . evolution_tree = QTreeWidget ( )
self . evolution_tree . setHeaderLabels ( [ " Pokémon " , " Evolution Method " ] )
self . evolution_tree . setColumnWidth ( 0 , 200 )
text_layout . addWidget ( self . evolution_tree )
# Add Locations tree
self . locations_tree = QTreeWidget ( )
self . locations_tree . setHeaderLabels ( [ " Game/Location " , " Details " ] )
self . locations_tree . setColumnWidth ( 0 , 200 )
self . locations_tree . itemDoubleClicked . connect ( self . edit_encounter )
text_layout . addWidget ( QLabel ( " Locations: " ) )
text_layout . addWidget ( self . locations_tree )
# Add New Encounter button
self . add_encounter_button = QPushButton ( " Add New Encounter " )
self . add_encounter_button . clicked . connect ( self . add_new_encounter )
text_layout . addWidget ( self . add_encounter_button )
# Move buttons to the bottom
text_layout . addStretch ( 1 )
self . save_button = QPushButton ( " Save Changes " )
self . save_button . clicked . connect ( self . save_changes )
text_layout . addWidget ( self . save_button )
self . export_button = QPushButton ( " Export Database " )
self . export_button . clicked . connect ( self . export_database )
text_layout . addWidget ( self . export_button )
# Add New Evolution button
self . add_evolution_button = QPushButton ( " Add New Evolution " )
self . add_evolution_button . clicked . connect ( self . add_new_evolution )
text_layout . addWidget ( self . add_evolution_button )
# Right side of right panel: Image
image_layout = QVBoxLayout ( )
self . image_label = QLabel ( )
self . image_label . setAlignment ( Qt . AlignmentFlag . AlignCenter )
self . image_label . setFixedSize ( 200 , 200 )
image_layout . addWidget ( self . image_label )
image_layout . addStretch ( 1 )
right_layout . addLayout ( text_layout )
right_layout . addLayout ( image_layout )
main_layout . addLayout ( left_layout , 1 )
main_layout . addLayout ( right_layout , 1 )
self . load_pokemon_list ( )
def adjust_list_width ( self ) :
max_width = 0
font_metrics = QFontMetrics ( self . pokemon_list . font ( ) )
for i in range ( self . pokemon_list . count ( ) ) :
item_width = font_metrics . horizontalAdvance ( self . pokemon_list . item ( i ) . text ( ) )
max_width = max ( max_width , item_width )
# Add some padding to the width
list_width = max_width + 50
self . pokemon_list . setFixedWidth ( list_width )
self . search_bar . setFixedWidth ( list_width )
def load_pokemon_list ( self ) :
self . pokemon_list . clear ( )
self . cursor . execute ( '''
SELECT pf . PFIC , pf . name , pf . form_name , pf . national_dex
FROM pokemon_forms pf
''' )
pokemon_data = self . cursor . fetchall ( )
# Sort the pokemon_data based on PFIC
pokemon_data . sort ( key = lambda x : parse_pfic ( x [ 0 ] ) )
for pfic , name , form_name , national_dex in pokemon_data :
display_name = f " { national_dex : 04d } - { name } "
if form_name :
display_name + = f " ( { form_name } ) "
item = QListWidgetItem ( display_name )
item . setData ( Qt . ItemDataRole . UserRole , pfic )
self . pokemon_list . addItem ( item )
self . update_encounter_cache ( )
self . update_pokemon_list_highlights ( )
self . adjust_list_width ( )
self . filter_pokemon_list ( )
def filter_pokemon_list ( self ) :
search_text = self . search_bar . text ( ) . lower ( )
show_only_home_storable = self . filter_home_storable . isChecked ( )
for i in range ( self . pokemon_list . count ( ) ) :
item = self . pokemon_list . item ( i )
pfic = item . data ( Qt . ItemDataRole . UserRole )
# Check if the item matches the search text
text_match = search_text in item . text ( ) . lower ( )
# Check if the item is storable in Home (if the filter is active)
home_storable = True
if show_only_home_storable :
self . cursor . execute ( ' SELECT storable_in_home FROM pokemon_storage WHERE PFIC = ? ' , ( pfic , ) )
result = self . cursor . fetchone ( )
home_storable = result [ 0 ] if result else False
# Show the item only if it matches both filters
item . setHidden ( not ( text_match and home_storable ) )
self . update_pokemon_list_highlights ( )
def load_pokemon_details ( self , current , previous ) :
if not current :
return
pfic = current . data ( Qt . ItemDataRole . UserRole )
self . cursor . execute ( '''
SELECT pf . name , pf . form_name , pf . national_dex , pf . generation , ps . storable_in_home , pf . is_baby_form
FROM pokemon_forms pf
LEFT JOIN pokemon_storage ps ON pf . PFIC = ps . PFIC
WHERE pf . PFIC = ?
''' , (pfic,))
pokemon_data = self . cursor . fetchone ( )
if pokemon_data :
name , form_name , national_dex , generation , storable_in_home , is_baby_form = pokemon_data
self . name_label . setText ( name )
self . form_name_label . setText ( form_name if form_name else " " )
self . national_dex_label . setText ( str ( national_dex ) )
self . generation_label . setText ( str ( generation ) )
self . home_checkbox . setChecked ( bool ( storable_in_home ) )
self . is_baby_form_checkbox . setChecked ( bool ( is_baby_form ) )
self . home_checkbox . stateChanged . connect ( self . update_home_storable )
# Load and display the image
image_path = f " images-new/ { pfic } .png "
if os . path . exists ( image_path ) :
pixmap = QPixmap ( image_path )
self . image_label . setPixmap ( pixmap . scaled ( 200 , 200 , Qt . AspectRatioMode . KeepAspectRatio , Qt . TransformationMode . SmoothTransformation ) )
else :
self . image_label . setText ( " Image not found " )
# Load and display evolution chain
self . load_evolution_chain ( pfic )
# Load and display encounter locations
self . load_encounter_locations ( pfic )
self . current_pfic = pfic
self . add_evolution_button . setEnabled ( True ) # Enable the button when a Pokémon is selected
def update_home_storable ( self ) :
if hasattr ( self , ' current_pfic ' ) :
storable_in_home = self . home_checkbox . isChecked ( )
self . cursor . execute ( ' UPDATE pokemon_storage SET storable_in_home = ? WHERE PFIC = ? ' , ( storable_in_home , self . current_pfic ) )
self . conn . commit ( )
self . filter_pokemon_list ( ) # Reapply the filter
def edit_evolution ( self , item , column ) :
parent = item . parent ( )
if not parent :
return # Don't edit the root item
from_pfic = parent . data ( 0 , Qt . ItemDataRole . UserRole )
to_pfic = item . data ( 0 , Qt . ItemDataRole . UserRole )
method = item . text ( 1 )
dialog = EvolutionEditDialog ( self , from_pfic , to_pfic , method )
result = dialog . exec ( )
if result == QDialog . DialogCode . Accepted :
new_from_pfic = dialog . from_combo . currentData ( )
new_to_pfic = dialog . to_combo . currentData ( )
new_method = dialog . method_edit . text ( )
# Update the in-memory database
self . cursor . execute ( '''
UPDATE evolution_chains
SET from_pfic = ? , to_pfic = ? , method = ?
WHERE from_pfic = ? AND to_pfic = ?
''' , (new_from_pfic, new_to_pfic, new_method, from_pfic, to_pfic))
# Create or update the patch
patch_key = f " evolution_ { from_pfic } _ { to_pfic } "
self . patches [ patch_key ] = {
' action ' : ' update ' ,
' new_from_pfic ' : new_from_pfic ,
' new_to_pfic ' : new_to_pfic ,
' new_method ' : new_method
}
self . save_patches ( )
# Refresh the evolution chain display
self . load_evolution_chain ( self . current_pfic )
elif result == 2 : # Delete action
confirm = QMessageBox . question ( self , " Confirm Deletion " , " Are you sure you want to delete this evolution? " ,
QMessageBox . StandardButton . Yes | QMessageBox . StandardButton . No )
if confirm == QMessageBox . StandardButton . Yes :
# Delete from the in-memory database
self . cursor . execute ( '''
DELETE FROM evolution_chains
WHERE from_pfic = ? AND to_pfic = ?
''' , (from_pfic, to_pfic))
# Create a delete patch
patch_key = f " evolution_ { from_pfic } _ { to_pfic } "
self . patches [ patch_key ] = { ' action ' : ' delete ' }
self . save_patches ( )
# Refresh the evolution chain display
self . load_evolution_chain ( self . current_pfic )
def get_evolution_chain ( self , pfic ) :
def follow_chain ( start_pfic , visited = None ) :
if visited is None :
visited = set ( )
chain = [ ]
stack = [ ( start_pfic , None ) ]
while stack :
current_pfic , method = stack . pop ( )
if current_pfic in visited :
continue
visited . add ( current_pfic )
self . cursor . execute ( ' SELECT name, form_name FROM pokemon_forms WHERE PFIC = ? ' , ( current_pfic , ) )
name , form_name = self . cursor . fetchone ( )
chain . append ( ( current_pfic , name , form_name , method ) )
# Get previous evolutions
self . cursor . execute ( ' SELECT from_pfic, method FROM evolution_chains WHERE to_pfic = ? ' , ( current_pfic , ) )
prev_evolutions = self . cursor . fetchall ( )
for prev_pfic , prev_method in prev_evolutions :
if prev_pfic not in visited :
stack . append ( ( prev_pfic , prev_method ) )
# Get next evolutions
self . cursor . execute ( ' SELECT to_pfic, method FROM evolution_chains WHERE from_pfic = ? ' , ( current_pfic , ) )
next_evolutions = self . cursor . fetchall ( )
for next_pfic , next_method in next_evolutions :
if next_pfic not in visited :
stack . append ( ( next_pfic , next_method ) )
return chain
return follow_chain ( pfic )
def load_evolution_chain ( self , pfic ) :
self . evolution_tree . clear ( )
evolution_chain = self . get_evolution_chain ( pfic )
# Create a dictionary to store tree items
tree_items = { }
# First pass: create all tree items
for current_pfic , name , form_name , method in evolution_chain :
display_name = f " { name } ( { form_name } ) " if form_name else name
item = QTreeWidgetItem ( [ display_name , method if method else " " ] )
item . setData ( 0 , Qt . ItemDataRole . UserRole , current_pfic )
tree_items [ current_pfic ] = item
if current_pfic == pfic :
item . setBackground ( 0 , QColor ( 255 , 255 , 0 , 100 ) ) # Highlight selected Pokémon
# Second pass: build the tree structure
root = None
for current_pfic , name , form_name , method in evolution_chain :
item = tree_items [ current_pfic ]
# Find the parent of this item
self . cursor . execute ( ' SELECT from_pfic FROM evolution_chains WHERE to_pfic = ? ' , ( current_pfic , ) )
parent_pfic = self . cursor . fetchone ( )
if parent_pfic :
parent_item = tree_items . get ( parent_pfic [ 0 ] )
if parent_item :
parent_item . addChild ( item )
elif not root :
root = item
self . evolution_tree . addTopLevelItem ( root )
# Expand the entire tree
self . evolution_tree . expandAll ( )
# Scroll to and select the current Pokémon
current_item = tree_items [ pfic ]
self . evolution_tree . scrollToItem ( current_item )
self . evolution_tree . setCurrentItem ( current_item )
# Connect double-click signal
self . evolution_tree . itemDoubleClicked . connect ( self . edit_evolution )
def save_changes ( self ) :
if hasattr ( self , ' current_pfic ' ) :
storable_in_home = self . home_checkbox . isChecked ( )
self . patches [ self . current_pfic ] = { ' storable_in_home ' : storable_in_home }
with open ( ' patches.json ' , ' w ' ) as f :
json . dump ( self . patches , f )
def export_database ( self ) :
export_conn = sqlite3 . connect ( ' pokemon_forms_production.db ' )
self . conn . backup ( export_conn )
export_conn . close ( )
def closeEvent ( self , event ) :
self . conn . close ( )
event . accept ( )
def add_new_evolution ( self ) :
if not hasattr ( self , ' current_pfic ' ) :
return
dialog = EvolutionEditDialog ( self , self . current_pfic , None , " " )
result = dialog . exec ( )
if result == QDialog . DialogCode . Accepted :
new_from_pfic = dialog . from_combo . currentData ( )
new_to_pfic = dialog . to_combo . currentData ( )
new_method = dialog . method_edit . text ( )
# Update the in-memory database
self . cursor . execute ( '''
INSERT INTO evolution_chains ( from_pfic , to_pfic , method )
VALUES ( ? , ? , ? )
''' , (new_from_pfic, new_to_pfic, new_method))
# Create a new patch
patch_key = f " evolution_ { new_from_pfic } _ { new_to_pfic } "
self . patches [ patch_key ] = {
' action ' : ' add ' ,
' from_pfic ' : new_from_pfic ,
' to_pfic ' : new_to_pfic ,
' method ' : new_method
}
self . save_patches ( )
# Refresh the evolution chain display
self . load_evolution_chain ( self . current_pfic )
def load_encounter_locations ( self , pfic ) :
self . locations_tree . clear ( )
self . cursor . execute ( '''
SELECT game , location , day , time , dual_slot , static_encounter_count , static_encounter , extra_text , stars , rods , fishing
FROM encounters
WHERE pfic = ?
ORDER BY game , location
''' , (pfic,))
encounters = self . cursor . fetchall ( )
game_items = { }
for encounter in encounters :
game , location , day , time , dual_slot , static_encounter_count , static_encounter , extra_text , stars , rods , fishing = encounter
if game not in game_items :
game_item = QTreeWidgetItem ( [ game ] )
game_items [ game ] = game_item
# Use generation for sorting, default to 0 if not found
game_item . setData ( 0 , Qt . ItemDataRole . UserRole , self . game_generations . get ( game , 0 ) )
location_item = QTreeWidgetItem ( [ location ] )
details = [ ]
if day :
details . append ( f " Day: { day } " )
if time :
details . append ( f " Time: { time } " )
if dual_slot :
details . append ( f " Dual Slot: { dual_slot } " )
if static_encounter :
details . append ( f " Static Encounter (Count: { static_encounter_count } ) " )
if extra_text :
details . append ( f " Extra: { extra_text } " )
if stars :
details . append ( f " Stars: { stars } " )
if fishing :
details . append ( f " Fishing " )
if rods :
details . append ( f " Rods: { rods } " )
location_item . setText ( 1 , " , " . join ( details ) )
game_items [ game ] . addChild ( location_item )
# Sort game items by generation and add them to the tree
sorted_game_items = sorted ( game_items . values ( ) , key = lambda x : x . data ( 0 , Qt . ItemDataRole . UserRole ) )
self . locations_tree . addTopLevelItems ( sorted_game_items )
self . locations_tree . expandAll ( )
# Update the cache for this Pokémon
self . encounter_cache [ pfic ] = len ( encounters ) > 0
# After updating the locations tree
self . update_pokemon_list_highlights ( )
def edit_encounter ( self , item , column ) :
if item . parent ( ) is None : # This is a game item, not a location item
return
game = item . parent ( ) . text ( 0 )
location = item . text ( 0 )
dialog = QDialog ( self )
dialog . setWindowTitle ( " Edit Encounter " )
layout = QFormLayout ( dialog )
game_edit = QLineEdit ( game )
location_edit = QLineEdit ( location )
day_edit = QLineEdit ( )
time_edit = QLineEdit ( )
dual_slot_edit = QLineEdit ( )
static_encounter_check = QCheckBox ( " Static Encounter " )
static_encounter_count_edit = QSpinBox ( )
extra_text_edit = QLineEdit ( )
stars_edit = QLineEdit ( )
fishing_check = QCheckBox ( " Fishing " )
rods_edit = QLineEdit ( )
layout . addRow ( " Game: " , game_edit )
layout . addRow ( " Location: " , location_edit )
layout . addRow ( " Day: " , day_edit )
layout . addRow ( " Time: " , time_edit )
layout . addRow ( " Dual Slot: " , dual_slot_edit )
layout . addRow ( " Static Encounter: " , static_encounter_check )
layout . addRow ( " Static Encounter Count: " , static_encounter_count_edit )
layout . addRow ( " Extra Text: " , extra_text_edit )
layout . addRow ( " Stars: " , stars_edit )
layout . addRow ( " Fishing: " , fishing_check )
layout . addRow ( " Rods: " , rods_edit )
exclusive_group_combo = QComboBox ( )
exclusive_group_combo . addItem ( " None " , None )
self . cursor . execute ( ' SELECT id, group_name FROM exclusive_encounter_groups ' )
for group_id , group_name in self . cursor . fetchall ( ) :
exclusive_group_combo . addItem ( group_name , group_id )
layout . addRow ( " Exclusive Group: " , exclusive_group_combo )
# Fetch current values
self . cursor . execute ( '''
SELECT day , time , dual_slot , static_encounter_count , static_encounter , extra_text , stars , fishing , rods , exclusive_group_id
FROM encounters
WHERE pfic = ? AND game = ? AND location = ?
''' , (self.current_pfic, game, location))
current_values = self . cursor . fetchone ( )
if current_values :
day , time , dual_slot , static_encounter_count , static_encounter , extra_text , stars , fishing , rods , exclusive_group_id = current_values
day_edit . setText ( day or " " )
time_edit . setText ( time or " " )
dual_slot_edit . setText ( dual_slot or " " )
static_encounter_check . setChecked ( bool ( static_encounter ) )
static_encounter_count_edit . setValue ( static_encounter_count or 0 )
extra_text_edit . setText ( extra_text or " " )
stars_edit . setText ( stars or " " )
fishing_check . setChecked ( bool ( fishing ) )
rods_edit . setText ( rods or " " )
index = exclusive_group_combo . findData ( exclusive_group_id )
if index > = 0 :
exclusive_group_combo . setCurrentIndex ( index )
buttons = QDialogButtonBox (
QDialogButtonBox . StandardButton . Ok | QDialogButtonBox . StandardButton . Cancel ,
Qt . Orientation . Horizontal , dialog )
buttons . accepted . connect ( dialog . accept )
buttons . rejected . connect ( dialog . reject )
layout . addRow ( buttons )
if dialog . exec ( ) == QDialog . DialogCode . Accepted :
new_game = game_edit . text ( )
new_location = location_edit . text ( )
new_day = day_edit . text ( ) or None
new_time = time_edit . text ( ) or None
new_dual_slot = dual_slot_edit . text ( ) or None
new_static_encounter = static_encounter_check . isChecked ( )
new_static_encounter_count = static_encounter_count_edit . value ( )
new_extra_text = extra_text_edit . text ( ) or None
new_stars = stars_edit . text ( ) or None
new_fishing = fishing_check . isChecked ( )
new_rods = rods_edit . text ( ) or None
new_exclusive_group_id = exclusive_group_combo . currentData ( )
# Update the database
self . cursor . execute ( '''
UPDATE encounters
SET game = ? , location = ? , day = ? , time = ? , dual_slot = ? ,
static_encounter = ? , static_encounter_count = ? , extra_text = ? ,
stars = ? , fishing = ? , rods = ? , exclusive_group_id = ?
WHERE pfic = ? AND game = ? AND location = ?
''' , (new_game, new_location, new_day, new_time, new_dual_slot,
new_static_encounter , new_static_encounter_count , new_extra_text ,
new_stars , new_fishing , new_rods , new_exclusive_group_id ,
self . current_pfic , game , location ) )
self . conn . commit ( )
# Update the cache if all encounters for this Pokémon were deleted
if not self . check_pokemon_has_encounters ( self . current_pfic ) :
self . encounter_cache [ self . current_pfic ] = False
# Refresh the locations tree
self . load_encounter_locations ( self . current_pfic )
def add_new_encounter ( self ) :
dialog = QDialog ( self )
dialog . setWindowTitle ( " Add New Encounter " )
layout = QFormLayout ( dialog )
game_edit = QLineEdit ( )
location_edit = QLineEdit ( )
day_edit = QLineEdit ( )
time_edit = QLineEdit ( )
dual_slot_edit = QLineEdit ( )
static_encounter_check = QCheckBox ( " Static Encounter " )
static_encounter_count_edit = QSpinBox ( )
extra_text_edit = QLineEdit ( )
stars_edit = QLineEdit ( )
fishing_check = QCheckBox ( " Fishing " )
rods_edit = QLineEdit ( )
layout . addRow ( " Game: " , game_edit )
layout . addRow ( " Location: " , location_edit )
layout . addRow ( " Day: " , day_edit )
layout . addRow ( " Time: " , time_edit )
layout . addRow ( " Dual Slot: " , dual_slot_edit )
layout . addRow ( " Static Encounter: " , static_encounter_check )
layout . addRow ( " Static Encounter Count: " , static_encounter_count_edit )
layout . addRow ( " Extra Text: " , extra_text_edit )
layout . addRow ( " Stars: " , stars_edit )
layout . addRow ( " Fishing: " , fishing_check )
layout . addRow ( " Rods: " , rods_edit )
exclusive_group_combo = QComboBox ( )
exclusive_group_combo . addItem ( " None " , None )
self . cursor . execute ( ' SELECT id, group_name FROM exclusive_encounter_groups ' )
for group_id , group_name in self . cursor . fetchall ( ) :
exclusive_group_combo . addItem ( group_name , group_id )
layout . addRow ( " Exclusive Group: " , exclusive_group_combo )
buttons = QDialogButtonBox (
QDialogButtonBox . StandardButton . Ok | QDialogButtonBox . StandardButton . Cancel ,
Qt . Orientation . Horizontal , dialog )
buttons . accepted . connect ( dialog . accept )
buttons . rejected . connect ( dialog . reject )
layout . addRow ( buttons )
if dialog . exec ( ) == QDialog . DialogCode . Accepted :
game = game_edit . text ( )
location = location_edit . text ( )
day = day_edit . text ( ) or None
time = time_edit . text ( ) or None
dual_slot = dual_slot_edit . text ( ) or None
static_encounter = static_encounter_check . isChecked ( )
static_encounter_count = static_encounter_count_edit . value ( )
extra_text = extra_text_edit . text ( ) or None
stars = stars_edit . text ( ) or None
fishing = fishing_check . isChecked ( )
rods = rods_edit . text ( ) or None
exclusive_group_id = exclusive_group_combo . currentData ( )
# Insert new encounter into the database
self . cursor . execute ( '''
INSERT INTO encounters
( pfic , game , location , day , time , dual_slot , static_encounter , static_encounter_count , extra_text , stars , fishing , rods , exclusive_group_id )
VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )
''' , (self.current_pfic, game, location, day, time, dual_slot, static_encounter, static_encounter_count, extra_text, stars, fishing, rods, exclusive_group_id))
self . conn . commit ( )
# Update the cache
self . encounter_cache [ self . current_pfic ] = True
# Refresh the locations tree
self . load_encounter_locations ( self . current_pfic )
# Add this as a class attribute in the DBEditor class
game_generations = {
" Red " : 1 , " Blue " : 1 , " Yellow " : 1 ,
" Gold " : 2 , " Silver " : 2 , " Crystal " : 2 ,
" Ruby " : 3 , " Sapphire " : 3 , " Emerald " : 3 , " FireRed " : 3 , " LeafGreen " : 3 ,
" Diamond " : 4 , " Pearl " : 4 , " Platinum " : 4 , " HeartGold " : 4 , " SoulSilver " : 4 ,
" Black " : 5 , " White " : 5 , " Black 2 " : 5 , " White 2 " : 5 ,
" X " : 6 , " Y " : 6 , " Omega Ruby " : 6 , " Alpha Sapphire " : 6 ,
" Sun " : 7 , " Moon " : 7 , " Ultra Sun " : 7 , " Ultra Moon " : 7 ,
" Sword " : 8 , " Shield " : 8 , " Brilliant Diamond " : 8 , " Shining Pearl " : 8 , " Expansion Pass " : 8 ,
" Legends: Arceus " : 8 ,
" Scarlet " : 9 , " Violet " : 9 , " The Teal Mask " : 9 , " The Hidden Treasure of Area Zero " : 9 , " The Hidden Treasure of Area Zero (Scarlet) " : 9 , " The Hidden Treasure of Area Zero (Violet) " : 9 , " The Teal Mask (Scarlet) " : 9 , " The Teal Mask (Violet) " : 9 ,
" Pokémon Go " : 0 , " Pokémon Home " : 0
}
def toggle_highlight_mode ( self ) :
self . update_pokemon_list_highlights ( )
def update_pokemon_list_highlights ( self ) :
highlight_mode = self . highlight_no_encounters . isChecked ( )
for i in range ( self . pokemon_list . count ( ) ) :
item = self . pokemon_list . item ( i )
pfic = item . data ( Qt . ItemDataRole . UserRole )
if highlight_mode :
has_encounters = self . encounter_cache . get ( pfic , False )
if not has_encounters :
item . setData ( Qt . ItemDataRole . BackgroundRole , QColor ( 255 , 200 , 200 ) ) # Light red background
else :
item . setData ( Qt . ItemDataRole . BackgroundRole , None ) # White background
else :
item . setData ( Qt . ItemDataRole . BackgroundRole , None ) # White background
def update_encounter_cache ( self ) :
self . cursor . execute ( '''
SELECT DISTINCT pfic
FROM encounters
''' )
pokemon_with_encounters = set ( row [ 0 ] for row in self . cursor . fetchall ( ) )
for i in range ( self . pokemon_list . count ( ) ) :
item = self . pokemon_list . item ( i )
pfic = item . data ( Qt . ItemDataRole . UserRole )
self . encounter_cache [ pfic ] = pfic in pokemon_with_encounters
def check_pokemon_has_encounters ( self , pfic ) :
return self . encounter_cache . get ( pfic , False )
def manage_exclusive_groups ( self ) :
dialog = QDialog ( self )
dialog . setWindowTitle ( " Manage Exclusive Encounter Groups " )
layout = QVBoxLayout ( dialog )
group_list = QListWidget ( )
self . cursor . execute ( ' SELECT id, group_name, description FROM exclusive_encounter_groups ' )
for group_id , group_name , description in self . cursor . fetchall ( ) :
item = QListWidgetItem ( f " { group_name } - { description } " )
item . setData ( Qt . ItemDataRole . UserRole , group_id )
group_list . addItem ( item )
layout . addWidget ( group_list )
add_button = QPushButton ( " Add Group " )
edit_button = QPushButton ( " Edit Group " )
delete_button = QPushButton ( " Delete Group " )
button_layout = QHBoxLayout ( )
button_layout . addWidget ( add_button )
button_layout . addWidget ( edit_button )
button_layout . addWidget ( delete_button )
layout . addLayout ( button_layout )
add_button . clicked . connect ( lambda : self . add_edit_exclusive_group ( dialog , group_list ) )
edit_button . clicked . connect ( lambda : self . add_edit_exclusive_group ( dialog , group_list , group_list . currentItem ( ) ) )
delete_button . clicked . connect ( lambda : self . delete_exclusive_group ( dialog , group_list , group_list . currentItem ( ) ) )
dialog . exec ( )
def add_edit_exclusive_group ( self , parent_dialog , group_list , item = None ) :
dialog = QDialog ( parent_dialog )
dialog . setWindowTitle ( " Add/Edit Exclusive Group " )
layout = QFormLayout ( dialog )
name_edit = QLineEdit ( )
description_edit = QLineEdit ( )
layout . addRow ( " Group Name: " , name_edit )
layout . addRow ( " Description: " , description_edit )
if item :
group_id = item . data ( Qt . ItemDataRole . UserRole )
self . cursor . execute ( ' SELECT group_name, description FROM exclusive_encounter_groups WHERE id = ? ' , ( group_id , ) )
group_name , description = self . cursor . fetchone ( )
name_edit . setText ( group_name )
description_edit . setText ( description )
buttons = QDialogButtonBox ( QDialogButtonBox . StandardButton . Ok | QDialogButtonBox . StandardButton . Cancel )
buttons . accepted . connect ( dialog . accept )
buttons . rejected . connect ( dialog . reject )
layout . addRow ( buttons )
if dialog . exec ( ) == QDialog . DialogCode . Accepted :
name = name_edit . text ( )
description = description_edit . text ( )
if item :
self . cursor . execute ( ' UPDATE exclusive_encounter_groups SET group_name = ?, description = ? WHERE id = ? ' , ( name , description , group_id ) )
item . setText ( f " { name } - { description } " )
else :
self . cursor . execute ( ' INSERT INTO exclusive_encounter_groups (group_name, description) VALUES (?, ?) ' , ( name , description ) )
group_id = self . cursor . lastrowid
new_item = QListWidgetItem ( f " { name } - { description } " )
new_item . setData ( Qt . ItemDataRole . UserRole , group_id )
group_list . addItem ( new_item )
self . conn . commit ( )
def delete_exclusive_group ( self , parent_dialog , group_list , item ) :
if item :
group_id = item . data ( Qt . ItemDataRole . UserRole )
reply = QMessageBox . question ( parent_dialog , ' Delete Group ' , ' Are you sure you want to delete this group? ' , QMessageBox . StandardButton . Yes | QMessageBox . StandardButton . No , QMessageBox . StandardButton . No )
if reply == QMessageBox . StandardButton . Yes :
self . cursor . execute ( ' DELETE FROM exclusive_encounter_groups WHERE id = ? ' , ( group_id , ) )
self . cursor . execute ( ' UPDATE encounters SET exclusive_group_id = NULL WHERE exclusive_group_id = ? ' , ( group_id , ) )
self . conn . commit ( )
group_list . takeItem ( group_list . row ( item ) )
def show_pokemon_context_menu ( self , position ) :
item = self . pokemon_list . itemAt ( position )
if item is not None :
context_menu = QMenu ( self )
refresh_action = QAction ( " Refresh Encounters " , self )
refresh_action . triggered . connect ( lambda : self . refresh_pokemon_encounters ( item ) )
context_menu . addAction ( refresh_action )
context_menu . exec ( self . pokemon_list . viewport ( ) . mapToGlobal ( position ) )
def refresh_pokemon_encounters ( self , item ) :
pfic = item . data ( Qt . ItemDataRole . UserRole )
self . cursor . execute ( '''
SELECT name , form_name , national_dex
FROM pokemon_forms
WHERE PFIC = ?
''' , (pfic,))
pokemon_data = self . cursor . fetchone ( )
if pokemon_data :
name , form , national_dex = pokemon_data
# Import the necessary function and classes
#from DataGatherers.update_location_information import process_pokemon_for_location_data
import json
# Create a temporary connection for this operation
temp_conn = sqlite3 . connect ( ' pokemon_forms.db ' )
# Load default forms
try :
with open ( ' ./DataGatherers/DefaultForms.json ' , ' r ' ) as f :
default_forms = json . load ( f )
except FileNotFoundError :
default_forms = [ ]
# Create a cache manager instance
cache = CacheManager ( )
# Delete existing encounters for this Pokémon
self . cursor . execute ( ' DELETE FROM encounters WHERE pfic = ? ' , ( pfic , ) )
self . conn . commit ( )
# Process the Pokémon data
process_pokemon_for_location_data ( pfic , name , form , national_dex , default_forms , cache , temp_conn )
temp_conn . backup ( self . conn )
# Close the temporary connection
temp_conn . close ( )
# Refresh the encounter locations in the UI
self . load_encounter_locations ( pfic )
# Update the encounter cache and highlights
self . update_encounter_cache ( )
self . update_pokemon_list_highlights ( )
print ( f " Refreshed encounters for { name } { form if form else ' ' } " )
if __name__ == ' __main__ ' :
app = QApplication ( sys . argv )
editor = DBEditor ( )
editor . show ( )
sys . exit ( app . exec ( ) )