diff --git a/tagstudio/resources/qt/images/file_icons/adobe_illustrator.png b/tagstudio/resources/qt/images/file_icons/adobe_illustrator.png new file mode 100644 index 00000000..141ae620 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/adobe_illustrator.png differ diff --git a/tagstudio/resources/qt/images/file_icons/adobe_photoshop.png b/tagstudio/resources/qt/images/file_icons/adobe_photoshop.png new file mode 100644 index 00000000..44a2c167 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/adobe_photoshop.png differ diff --git a/tagstudio/resources/qt/images/file_icons/affinity_photo.png b/tagstudio/resources/qt/images/file_icons/affinity_photo.png new file mode 100644 index 00000000..f4305fb8 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/affinity_photo.png differ diff --git a/tagstudio/resources/qt/images/file_icons/document.png b/tagstudio/resources/qt/images/file_icons/document.png new file mode 100644 index 00000000..dddf93b0 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/document.png differ diff --git a/tagstudio/resources/qt/images/file_icons/generic.png b/tagstudio/resources/qt/images/file_icons/file_generic.png similarity index 100% rename from tagstudio/resources/qt/images/file_icons/generic.png rename to tagstudio/resources/qt/images/file_icons/file_generic.png diff --git a/tagstudio/resources/qt/images/file_icons/font.png b/tagstudio/resources/qt/images/file_icons/font.png new file mode 100644 index 00000000..174750db Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/font.png differ diff --git a/tagstudio/resources/qt/images/file_icons/image.png b/tagstudio/resources/qt/images/file_icons/image.png new file mode 100644 index 00000000..94264aec Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/image.png differ diff --git a/tagstudio/resources/qt/images/file_icons/material.png b/tagstudio/resources/qt/images/file_icons/material.png new file mode 100644 index 00000000..0c0c10af Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/material.png differ diff --git a/tagstudio/resources/qt/images/file_icons/model.png b/tagstudio/resources/qt/images/file_icons/model.png new file mode 100644 index 00000000..631db6e9 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/model.png differ diff --git a/tagstudio/resources/qt/images/file_icons/text.png b/tagstudio/resources/qt/images/file_icons/text.png new file mode 100644 index 00000000..79d7d91b Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/text.png differ diff --git a/tagstudio/resources/qt/images/file_icons/video.png b/tagstudio/resources/qt/images/file_icons/video.png new file mode 100644 index 00000000..5dae57a6 Binary files /dev/null and b/tagstudio/resources/qt/images/file_icons/video.png differ diff --git a/tagstudio/src/core/media_types.py b/tagstudio/src/core/media_types.py index d1974343..47b9721b 100644 --- a/tagstudio/src/core/media_types.py +++ b/tagstudio/src/core/media_types.py @@ -13,7 +13,10 @@ logging.basicConfig(format="%(message)s", level=logging.INFO) class MediaType(str, Enum): """Names of media types.""" + ADOBE_PHOTOSHOP: str = "adobe_photoshop" + AFFINITY_PHOTO: str = "affinity_photo" ARCHIVE: str = "archive" + AUDIO_MIDI: str = "audio_midi" AUDIO: str = "audio" BLENDER: str = "blender" DATABASE: str = "database" @@ -27,7 +30,6 @@ class MediaType(str, Enum): MATERIAL: str = "material" MODEL: str = "model" PACKAGE: str = "package" - PHOTOSHOP: str = "photoshop" PLAINTEXT: str = "plaintext" PRESENTATION: str = "presentation" PROGRAM: str = "program" @@ -67,6 +69,12 @@ class MediaCategories: # These sets are used either individually or together to form the final sets # for the MediaCategory(s). # These sets may be combined and are NOT 1:1 with the final categories. + _ADOBE_PHOTOSHOP_SET: set[str] = { + ".pdd", + ".psb", + ".psd", + } + _AFFINITY_PHOTO_SET: set[str] = {".afphoto"} _ARCHIVE_SET: set[str] = { ".7z", ".gz", @@ -76,6 +84,10 @@ class MediaCategories: ".tgz", ".zip", } + _AUDIO_MIDI_SET: set[str] = { + ".mid", + ".midi", + } _AUDIO_SET: set[str] = { ".aac", ".aif", @@ -182,6 +194,7 @@ class MediaCategories: ".jpg_large", ".jpg", ".jpg2", + ".jxl", ".png", ".psb", ".psd", @@ -193,11 +206,6 @@ class MediaCategories: _MATERIAL_SET: set[str] = {".mtl"} _MODEL_SET: set[str] = {".3ds", ".fbx", ".obj", ".stl"} _PACKAGE_SET: set[str] = {".pkg"} - _PHOTOSHOP_SET: set[str] = { - ".pdd", - ".psb", - ".psd", - } _PLAINTEXT_SET: set[str] = { ".bat", ".css", @@ -247,14 +255,29 @@ class MediaCategories: ".wmv", } + ADOBE_PHOTOSHOP_TYPES: MediaCategory = MediaCategory( + media_type=MediaType.ADOBE_PHOTOSHOP, + extensions=_ADOBE_PHOTOSHOP_SET, + is_iana=False, + ) + AFFINITY_PHOTO_TYPES: MediaCategory = MediaCategory( + media_type=MediaType.AFFINITY_PHOTO, + extensions=_AFFINITY_PHOTO_SET, + is_iana=False, + ) ARCHIVE_TYPES: MediaCategory = MediaCategory( media_type=MediaType.ARCHIVE, extensions=_ARCHIVE_SET, is_iana=False, ) + AUDIO_MIDI_TYPES: MediaCategory = MediaCategory( + media_type=MediaType.AUDIO_MIDI, + extensions=_AUDIO_MIDI_SET, + is_iana=False, + ) AUDIO_TYPES: MediaCategory = MediaCategory( media_type=MediaType.AUDIO, - extensions=_AUDIO_SET, + extensions=_AUDIO_SET | _AUDIO_MIDI_SET, is_iana=True, ) BLENDER_TYPES: MediaCategory = MediaCategory( @@ -317,11 +340,6 @@ class MediaCategories: extensions=_PACKAGE_SET, is_iana=False, ) - PHOTOSHOP_TYPES: MediaCategory = MediaCategory( - media_type=MediaType.PHOTOSHOP, - extensions=_PHOTOSHOP_SET, - is_iana=False, - ) PLAINTEXT_TYPES: MediaCategory = MediaCategory( media_type=MediaType.PLAINTEXT, extensions=_PLAINTEXT_SET, @@ -359,7 +377,10 @@ class MediaCategories: ) ALL_CATEGORIES: list[MediaCategory] = [ + ADOBE_PHOTOSHOP_TYPES, + AFFINITY_PHOTO_TYPES, ARCHIVE_TYPES, + AUDIO_MIDI_TYPES, AUDIO_TYPES, BLENDER_TYPES, DATABASE_TYPES, @@ -373,7 +394,6 @@ class MediaCategories: MATERIAL_TYPES, MODEL_TYPES, PACKAGE_TYPES, - PHOTOSHOP_TYPES, PLAINTEXT_TYPES, PRESENTATION_TYPES, PROGRAM_TYPES, diff --git a/tagstudio/src/qt/resources.json b/tagstudio/src/qt/resources.json index 9f3d3e49..b27b7e36 100644 --- a/tagstudio/src/qt/resources.json +++ b/tagstudio/src/qt/resources.json @@ -19,8 +19,48 @@ "path": "qt/images/broken_link_icon.png", "mode": "pil" }, + "adobe_illustrator": { + "path": "qt/images/file_icons/adobe_illustrator.png", + "mode": "pil" + }, + "adobe_photoshop": { + "path": "qt/images/file_icons/adobe_photoshop.png", + "mode": "pil" + }, + "affinity_photo": { + "path": "qt/images/file_icons/affinity_photo.png", + "mode": "pil" + }, + "document": { + "path": "qt/images/file_icons/document.png", + "mode": "pil" + }, "file_generic": { - "path": "qt/images/file_icons/generic.png", + "path": "qt/images/file_icons/file_generic.png", + "mode": "pil" + }, + "font": { + "path": "qt/images/file_icons/font.png", + "mode": "pil" + }, + "image": { + "path": "qt/images/file_icons/image.png", + "mode": "pil" + }, + "material": { + "path": "qt/images/file_icons/material.png", + "mode": "pil" + }, + "model": { + "path": "qt/images/file_icons/model.png", + "mode": "pil" + }, + "text": { + "path": "qt/images/file_icons/text.png", + "mode": "pil" + }, + "video": { + "path": "qt/images/file_icons/video.png", "mode": "pil" } } diff --git a/tagstudio/src/qt/widgets/item_thumb.py b/tagstudio/src/qt/widgets/item_thumb.py index a03c1ae5..5cd1ea23 100644 --- a/tagstudio/src/qt/widgets/item_thumb.py +++ b/tagstudio/src/qt/widgets/item_thumb.py @@ -363,12 +363,15 @@ class ItemThumb(FlowWidget): and (MediaType.IMAGE not in MediaCategories.get_types(ext)) or (MediaType.IMAGE_RAW in MediaCategories.get_types(ext)) or (MediaType.IMAGE_VECTOR in MediaCategories.get_types(ext)) - or (MediaType.PHOTOSHOP in MediaCategories.get_types(ext)) + or (MediaType.ADOBE_PHOTOSHOP in MediaCategories.get_types(ext)) or ext in [ ".apng", + ".avif", ".exr", ".gif", + ".jxl", + ".webp", ] ): self.ext_badge.setHidden(False) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index c08f0291..bb352c5a 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -205,6 +205,10 @@ class ThumbRenderer(QObject): # Get icon by name icon: Image.Image = ThumbRenderer.rm.get(name) + if not icon: + icon = ThumbRenderer.rm.get("file_generic") + if not icon: + icon = Image.new(mode="RGBA", size=(32, 32), color="magenta") # Resize icon to fit icon_ratio icon = icon.resize( @@ -268,8 +272,29 @@ class ThumbRenderer(QObject): return bg @staticmethod - def get_mime_icon_resource(ext: str = "") -> str: - pass + def get_icon_resource(url: Path) -> str: + """Return the name of the icon resource to use for a file type. + + Args: + url (Path): The file url to assess. + """ + ext = url.suffix.lower() + types: set[MediaType] = MediaCategories.get_types(ext, True) + + # Loop though the specific (non-IANA) categories and return the string + # name of the first matching category found. + for cat in MediaCategories.ALL_CATEGORIES: + if not cat.is_iana: + if cat.media_type in types: + return cat.media_type.value + + # If the type is broader (IANA registered) then search those types. + for cat in MediaCategories.ALL_CATEGORIES: + if cat.is_iana: + if cat.media_type in types: + return cat.media_type.value + + return "file_generic" def render( self, @@ -541,8 +566,8 @@ class ThumbRenderer(QObject): if update_on_ratio_change: self.updated_ratio.emit(1) final = ThumbRenderer._get_icon( - # name=ThumbRenderer.get_mime_icon_resource(_filepath.suffix.lower()), - name="file_generic", + name=ThumbRenderer.get_icon_resource(_filepath), + # name="file_generic", color="", size=(adj_size, adj_size), pixel_ratio=pixel_ratio,