Toolbox for analyzing and editing pkg application files for psp,ps3, ps4 and ps5, includes the most useful functions you might need.
| 1 | from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, |
| 2 | QPushButton, QTreeWidget, QTreeWidgetItem, QDialog, QMessageBox, QApplication) |
| 3 | from PyQt5.QtCore import Qt |
| 4 | from ..utils import FileUtils, ImageUtils |
| 5 | |
| 6 | class WallpaperViewer(QWidget): |
| 7 | def __init__(self, parent=None): |
| 8 | super().__init__(parent) |
| 9 | self.parent = parent |
| 10 | self.setup_ui() |
| 11 | |
| 12 | def setup_ui(self): |
| 13 | layout = QVBoxLayout(self) |
| 14 | |
| 15 | # Tree view for wallpapers |
| 16 | self.wallpaper_tree = QTreeWidget() |
| 17 | self.wallpaper_tree.setHeaderLabels(["Name", "Size"]) |
| 18 | self.wallpaper_tree.itemClicked.connect(self.display_selected_wallpaper) |
| 19 | layout.addWidget(self.wallpaper_tree) |
| 20 | |
| 21 | # Image viewer |
| 22 | self.wallpaper_viewer = QLabel() |
| 23 | self.wallpaper_viewer.setAlignment(Qt.AlignCenter) |
| 24 | self.wallpaper_viewer.setStyleSheet( |
| 25 | "background-color: white; border: 1px solid #3498db; border-radius: 5px;") |
| 26 | self.wallpaper_viewer.setMinimumSize(300, 300) |
| 27 | layout.addWidget(self.wallpaper_viewer) |
| 28 | |
| 29 | # Control buttons |
| 30 | button_layout = QHBoxLayout() |
| 31 | self.prev_button = QPushButton("Previous") |
| 32 | self.next_button = QPushButton("Next") |
| 33 | self.fullscreen_button = QPushButton("Fullscreen") |
| 34 | |
| 35 | for button in [self.prev_button, self.next_button, self.fullscreen_button]: |
| 36 | button.setStyleSheet(""" |
| 37 | QPushButton { |
| 38 | font-size: 14px; |
| 39 | padding: 8px 15px; |
| 40 | background-color: #3498db; |
| 41 | color: white; |
| 42 | border: none; |
| 43 | border-radius: 5px; |
| 44 | } |
| 45 | QPushButton:hover { |
| 46 | background-color: #2980b9; |
| 47 | } |
| 48 | """) |
| 49 | |
| 50 | self.prev_button.clicked.connect(self.show_previous_wallpaper) |
| 51 | self.next_button.clicked.connect(self.show_next_wallpaper) |
| 52 | self.fullscreen_button.clicked.connect(self.show_fullscreen_wallpaper) |
| 53 | |
| 54 | button_layout.addWidget(self.prev_button) |
| 55 | button_layout.addWidget(self.next_button) |
| 56 | button_layout.addWidget(self.fullscreen_button) |
| 57 | layout.addLayout(button_layout) |
| 58 | |
| 59 | def load_wallpapers(self, package): |
| 60 | """Load wallpapers from package""" |
| 61 | self.wallpaper_tree.clear() |
| 62 | |
| 63 | if not package: |
| 64 | return |
| 65 | |
| 66 | wallpaper_files = [ |
| 67 | f for f in package.files.values() |
| 68 | if isinstance(f.get("name"), str) and |
| 69 | f["name"].lower().endswith(('.png', '.jpg', '.jpeg')) |
| 70 | ] |
| 71 | |
| 72 | wallpaper_structure = {} |
| 73 | for file_info in wallpaper_files: |
| 74 | path_parts = file_info["name"].split('/') |
| 75 | current_dict = wallpaper_structure |
| 76 | |
| 77 | for part in path_parts[:-1]: |
| 78 | if part: |
| 79 | current_dict = current_dict.setdefault(part, {}) |
| 80 | |
| 81 | if path_parts[-1]: |
| 82 | current_dict[path_parts[-1]] = file_info |
| 83 | |
| 84 | def add_wallpaper_items(parent_item, structure): |
| 85 | for name, content in sorted(structure.items()): |
| 86 | if isinstance(content, dict): |
| 87 | if any(isinstance(v, dict) for v in content.values()): |
| 88 | folder_item = QTreeWidgetItem(parent_item) |
| 89 | folder_item.setText(0, name) |
| 90 | folder_item.setIcon(0, FileUtils.get_file_icon('Directory')) |
| 91 | add_wallpaper_items(folder_item, content) |
| 92 | else: |
| 93 | item = QTreeWidgetItem(parent_item) |
| 94 | item.setText(0, name) |
| 95 | item.setText(1, FileUtils.format_size(content['size'])) |
| 96 | item.setIcon(0, FileUtils.get_file_icon('Image')) |
| 97 | item.setData(0, Qt.UserRole, content) |
| 98 | |
| 99 | add_wallpaper_items(self.wallpaper_tree.invisibleRootItem(), wallpaper_structure) |
| 100 | self.wallpaper_tree.expandAll() |
| 101 | |
| 102 | def display_selected_wallpaper(self, item): |
| 103 | """Display selected wallpaper""" |
| 104 | try: |
| 105 | file_info = item.data(0, Qt.UserRole) |
| 106 | if not file_info: |
| 107 | return |
| 108 | |
| 109 | # Get image data from package |
| 110 | image_data = self.parent.package.read_file(file_info['id']) |
| 111 | |
| 112 | # Create thumbnail |
| 113 | pixmap = ImageUtils.create_thumbnail(image_data) |
| 114 | |
| 115 | # Display image |
| 116 | self.wallpaper_viewer.setPixmap(pixmap) |
| 117 | self.wallpaper_viewer.setAlignment(Qt.AlignCenter) |
| 118 | |
| 119 | except Exception as e: |
| 120 | self.wallpaper_viewer.clear() |
| 121 | QMessageBox.warning(self.parent, "Error", f"Error displaying wallpaper: {str(e)}") |
| 122 | |
| 123 | def show_previous_wallpaper(self): |
| 124 | """Show previous wallpaper in the list""" |
| 125 | current_item = self.wallpaper_tree.currentItem() |
| 126 | if current_item: |
| 127 | current_index = self.wallpaper_tree.indexOfTopLevelItem(current_item) |
| 128 | if current_index > 0: |
| 129 | previous_item = self.wallpaper_tree.topLevelItem(current_index - 1) |
| 130 | self.wallpaper_tree.setCurrentItem(previous_item) |
| 131 | self.display_selected_wallpaper(previous_item) |
| 132 | |
| 133 | def show_next_wallpaper(self): |
| 134 | """Show next wallpaper in the list""" |
| 135 | current_item = self.wallpaper_tree.currentItem() |
| 136 | if current_item: |
| 137 | current_index = self.wallpaper_tree.indexOfTopLevelItem(current_item) |
| 138 | if current_index < self.wallpaper_tree.topLevelItemCount() - 1: |
| 139 | next_item = self.wallpaper_tree.topLevelItem(current_index + 1) |
| 140 | self.wallpaper_tree.setCurrentItem(next_item) |
| 141 | self.display_selected_wallpaper(next_item) |
| 142 | |
| 143 | def show_fullscreen_wallpaper(self): |
| 144 | """Show wallpaper in fullscreen""" |
| 145 | try: |
| 146 | current_item = self.wallpaper_tree.currentItem() |
| 147 | if not current_item: |
| 148 | return |
| 149 | |
| 150 | file_info = current_item.data(0, Qt.UserRole) |
| 151 | if not file_info: |
| 152 | return |
| 153 | |
| 154 | # Get image data |
| 155 | image_data = self.parent.package.read_file(file_info['id']) |
| 156 | |
| 157 | # Create fullscreen dialog |
| 158 | dialog = QDialog(self.parent) |
| 159 | dialog.setWindowTitle("Fullscreen Wallpaper") |
| 160 | layout = QVBoxLayout(dialog) |
| 161 | |
| 162 | # Create label for image |
| 163 | fullscreen_label = QLabel() |
| 164 | fullscreen_label.setAlignment(Qt.AlignCenter) |
| 165 | |
| 166 | # Get screen size and scale image |
| 167 | screen_size = QApplication.primaryScreen().size() |
| 168 | image = ImageUtils.load_and_scale_image(image_data, max(screen_size.width(), screen_size.height())) |
| 169 | pixmap = ImageUtils.convert_to_qpixmap(image) |
| 170 | |
| 171 | # Set scaled pixmap |
| 172 | fullscreen_label.setPixmap(pixmap.scaled(screen_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)) |
| 173 | |
| 174 | layout.addWidget(fullscreen_label) |
| 175 | dialog.showFullScreen() |
| 176 | |
| 177 | except Exception as e: |
| 178 | QMessageBox.critical(self.parent, "Error", f"Error showing fullscreen: {str(e)}") |
| 179 | |
| 180 | def clear_viewer(self): |
| 181 | """Clear the wallpaper viewer""" |
| 182 | self.wallpaper_viewer.clear() |
| 183 | self.wallpaper_tree.clear() |
| 184 | |
| 185 | def get_current_wallpaper(self): |
| 186 | """Get current wallpaper info""" |
| 187 | current_item = self.wallpaper_tree.currentItem() |
| 188 | if current_item: |
| 189 | return current_item.data(0, Qt.UserRole) |
| 190 | return None |
| 191 | |
| 192 | def set_enabled(self, enabled): |
| 193 | """Enable/disable the viewer""" |
| 194 | self.setEnabled(enabled) |
| 195 | self.wallpaper_tree.setEnabled(enabled) |
| 196 | self.wallpaper_viewer.setEnabled(enabled) |
| 197 | self.prev_button.setEnabled(enabled) |
| 198 | self.next_button.setEnabled(enabled) |
| 199 | self.fullscreen_button.setEnabled(enabled) |