Features Docs Installation Credits GitHub
v1.0.2 Documentation

Technical Documentation

Complete architecture reference, feature deep-dives, and API documentation for OrcaFile โ€” the fast, Nord-themed file organizer.

Architecture Overview

OrcaFile follows a layered architecture with clear separation of concerns using Python's mixin inheritance pattern. The codebase is organized into four distinct layers.

๐ŸŽจ

UI Layer

Presentation & styling โ€” ui/

main_window.py ยท styles.py ยท theme_manager.py
โš™๏ธ

Handler Layer

Business logic mixins โ€” handlers/

scan_handlers.py ยท filter_handlers.py ยท tree_handlers.py
๐Ÿ”„

Worker Layer

Background threads โ€” workers/

scan_worker.py (QThread)
๐Ÿ’พ

Scanner Layer

NTFS MFT engine โ€” ntfs_scanner/

NEW in v1.0.2

Mixin Composition Pattern

The main window uses multiple inheritance to keep handlers modular:

python
class FileOrganizerApp(ScanHandlersMixin, FilterHandlersMixin, TreeHandlersMixin, QMainWindow):
    """Main application window โ€” inherits from 3 handler mixins + QMainWindow."""

    # MRO: FileOrganizerApp โ†’ ScanHandlersMixin โ†’ FilterHandlersMixin
    #      โ†’ TreeHandlersMixin โ†’ QMainWindow โ†’ QWidget โ†’ QObject

Project Structure

orcafile_v1.0.2/
โ”œโ”€โ”€ orcafile_main.py              # Entry point
โ”œโ”€โ”€ orcafile_logo.ico             # App icon
โ”œโ”€โ”€ check.svg / dash.svg          # Checkbox SVG icons
โ”‚
โ”œโ”€โ”€ ui/                           # UI Layer
โ”‚   โ”œโ”€โ”€ main_window.py            # FileOrganizerApp (249 lines)
โ”‚   โ”œโ”€โ”€ styles.py                 # Dark & Light QSS (332 lines)
โ”‚   โ””โ”€โ”€ theme_manager.py          # QSettings persistence (19 lines)
โ”‚
โ”œโ”€โ”€ handlers/                     # Handler Layer
โ”‚   โ”œโ”€โ”€ scan_handlers.py          # Scan lifecycle (117 lines)
โ”‚   โ”œโ”€โ”€ filter_handlers.py        # Extension filtering (69 lines)
โ”‚   โ””โ”€โ”€ tree_handlers.py          # Tree view & deletion (275 lines)
โ”‚
โ”œโ”€โ”€ workers/                      # Worker Layer
โ”‚   โ””โ”€โ”€ scan_worker.py            # Background QThread (137 lines)
โ”‚
โ”œโ”€โ”€ ntfs_scanner/                 # Scanner Layer (NEW v1.0.2)
โ”‚   โ”œโ”€โ”€ volume.py                 # Raw NTFS volume handle (48 lines)
โ”‚   โ”œโ”€โ”€ mft.py                    # USN journal enumeration (108 lines)
โ”‚   โ”œโ”€โ”€ tree.py                   # In-memory FS tree (80 lines)
โ”‚   โ”œโ”€โ”€ navigator.py              # Path resolution (118 lines)
โ”‚   โ””โ”€โ”€ scanner.py                # Orchestrator (141 lines)
โ”‚
โ”œโ”€โ”€ setup/                        # Installer
โ”‚   โ””โ”€โ”€ inno_setup.iss            # Inno Setup script
โ”‚
โ””โ”€โ”€ docs/                         # Documentation assets

Core Features

โšก Feature 1 โ€” Drive/Folder Scanning & Extension Grouping

The user selects a folder or drive, and OrcaFile recursively scans the directory tree using a background QThread. In v1.0.2, scanning automatically attempts NTFS MFT reading first for ~10ร— faster indexing, falling back to os.walk() on non-NTFS or on failure.

python โ€” workers/scan_worker.py
def run(self):
    drive_part = os.path.splitdrive(self.target_dir)[0]
    drive_letter = drive_part[0] if drive_part else ""
    if drive_letter and is_ntfs(drive_letter):
        try:
            self._run_ntfs(drive_letter)  # Fast path
            return
        except Exception:
            pass  # fall through to os.walk fallback
    self._run_fallback()  # Standard os.walk

๐Ÿ“‚ Feature 2 โ€” Extension Filter Selection

After scanning, the sidebar shows all discovered extensions with file counts. A smart "accumulative search" lets users build up extension selections across multiple searches without losing previous selections.

๐Ÿ“ Feature 3 โ€” Open File Location (Double-Click)

Double-clicking any file opens its parent folder in the native file manager. Cross-platform: explorer /select, on Windows, open -R on macOS, xdg-open on Linux.

๐Ÿ” Feature 4 โ€” File Name Search

Real-time filtering by file name across all indexed files. Matching files stay visible, empty groups auto-hide. O(n) in-place filtering using QTreeWidgetItem.setHidden().

๐Ÿ—‘๏ธ Feature 5 โ€” Multi-Select & Bulk Delete

Tri-state checkboxes (unchecked / checked / partial) for groups and individual files. Selected files can be permanently deleted with confirmation. Internal data structures, filter counts, and tree view all update after deletion.

๐ŸŽจ Feature 6 โ€” Dark / Light Theme Toggle

Switch between Nord dark and Snow Storm light themes. Preference is persisted via QSettings (Windows Registry at HKCU\Software\OrcaFile\Preferences). Two complete QSS stylesheets (~160 lines each) define every widget.

NEW in v1.0.2

๐Ÿ“Š Feature 7 โ€” File Size Display & Sorting

Every file now shows its size in a dedicated third column. Extension groups display their total size. Click the "Size โ–ผ" button to toggle ascending/descending sort order. Both groups and files within groups are sorted by size.

python โ€” handlers/tree_handlers.py
def format_size(size_bytes: int) -> str:
    if size_bytes < 1024:
        return f"{size_bytes} B"
    elif size_bytes < 1024 ** 2:
        return f"{size_bytes / 1024:.1f} KB"
    elif size_bytes < 1024 ** 3:
        return f"{size_bytes / (1024 ** 2):.1f} MB"
    else:
        return f"{size_bytes / (1024 ** 3):.2f} GB"

def toggle_sort_order(self):
    self._sort_ascending = not self._sort_ascending
    self.sort_order_btn.setText("Size โ–ฒ" if self._sort_ascending else "Size โ–ผ")
    self.populate_tree_view()
NEW in v1.0.2

๐Ÿ’พ Feature 8 โ€” NTFS MFT Scanner

A custom NTFS scanner that reads the Master File Table directly via the Windows USN Change Journal API (FSCTL_ENUM_USN_DATA). This bypasses the filesystem layer entirely, achieving ~10ร— faster scanning on large NTFS volumes. Requires administrator privileges.

python โ€” ntfs_scanner/scanner.py
def scan_ntfs(drive_letter: str) -> ScanResult:
    handle = open_volume(drive_letter)
    try:
        records = enum_mft_records(handle)   # Generator of USN records
        nodes, children = build_tree(records) # Build in-memory tree
    finally:
        close_volume(handle)
    rollup_sizes(nodes, children)  # Compute recursive sizes
    return ScanResult(drive_letter, nodes, children, ...)

The scanner pipeline: Volume Handle โ†’ USN Enumeration โ†’ Tree Build โ†’ Size Rollup โ†’ Path Navigation โ†’ Extension Grouping

Technology Stack

ComponentTechnologyPurpose
LanguagePython 3.10+Core application logic
GUIPyQt6Widgets, event loop, threading
NTFS Scannerpywin32 (win32file)Raw volume I/O & USN journal v1.0.2
ThreadingQThreadNon-blocking file scanning
PersistenceQSettingsTheme preference (Windows Registry)
StylingQSS (Qt Style Sheets)CSS-like styling for all widgets
BuildPyInstallerPython โ†’ standalone .exe
InstallerInno SetupWindows installer wizard
LicenseGPLv3Open source license

Data Structures & State

Central Data Store: self.all_data

The entire application revolves around a single dictionary:

python
# Type: dict[str, list[tuple[str, str, int]]]
self.all_data = {
    ".pdf": [
        ("report.pdf", "C:\\Users\\docs\\report.pdf", 245760),
        ("invoice.pdf", "D:\\archive\\invoice.pdf", 102400),
    ],
    ".jpg": [
        ("photo.jpg", "E:\\images\\photo.jpg", 3145728),
    ],
    "no extension": [
        ("Makefile", "C:\\project\\Makefile", 1024),
    ],
}
# Tuple: (filename, full_absolute_path, size_in_bytes)

State Variables

python
# Core state
self.all_data = {}                      # Extension โ†’ file list
self.worker = None                      # Current ScanWorker thread
self._current_theme = "dark"            # Active theme

# Accumulative search state
self.first_search_done = False          # Has user ever searched?
self.solidified_selections = set()      # Saved extension selections
self._last_search_was_empty = True      # Was search bar empty?

# v1.0.2 additions
self._sort_ascending = False            # Size sort direction
self._block_tree_signals = False        # Prevents checkbox recursion

Scan Pipeline

Data Flow

text
User Input                  Main Thread                    Worker Thread
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
path_input.text() โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ start_scan()
                              โ”‚
                              โ”œโ”€โ”€ validate path
                              โ”œโ”€โ”€ reset UI
                              โ”œโ”€โ”€ create ScanWorker โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ .start()
                              โ”‚                              โ”‚
                              โ”‚                        [NTFS? โ†’ _run_ntfs()]
                              โ”‚                        [else  โ†’ _run_fallback()]
                              โ”‚                              โ”‚
                              โ”‚    status signal โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ "READING MFT..."
                              โ”‚    progress signal โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ (100, 5000)
                              โ”‚    finished signal โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ {ext: [(name, path, size)]}
                              โ”‚
                              โ”œโ”€โ”€ handle_scan_results()
                              โ”œโ”€โ”€ populate filter_list
                              โ””โ”€โ”€ populate_tree_view()

Thread safety: All UI updates happen on the main thread via Qt's signal-slot mechanism. pyqtSignal instances serialize data across thread boundaries. The worker never directly touches any widget.

NTFS MFT Scanner NEW v1.0.2

Why MFT Scanning?

os.walk() traverses the directory tree via the filesystem layer, issuing thousands of syscalls. The NTFS MFT scanner reads the Master File Table directly using DeviceIoControl(FSCTL_ENUM_USN_DATA), fetching all records in bulk. This achieves ~10ร— faster scanning on large volumes (500K+ files).

๐Ÿ“€

volume.py

Opens raw NTFS volume handle via CreateFile("\\.\C:"). Detects NTFS via GetVolumeInformation().

๐Ÿ“‹

mft.py

Enumerates USN records via FSCTL_ENUM_USN_DATA. Parses USN_RECORD_V2 structs for FRN, parent, size, and name.

๐ŸŒณ

tree.py

Builds in-memory directory tree from MFT records. FsNode dataclass stores name, size, is_dir. Iterative post-order DFS for size rollup.

๐Ÿงญ

navigator.py

Resolves paths to FRNs, lists folder contents sorted by size. Pure in-memory โ€” no disk access after initial MFT read.

USN Record Parsing

python โ€” ntfs_scanner/mft.py
FSCTL_ENUM_USN_DATA = 0x900B3   # Control code for USN enumeration
FILE_ATTRIBUTE_DIRECTORY = 0x10 # Directory flag in file attributes
NTFS_ROOT_FRN = 5               # Root directory always has FRN 5
OUTPUT_BUFFER_SIZE = 65536      # 64KB per DeviceIoControl call

def _parse_usn_record(raw: bytes, offset: int) -> tuple:
    rec_len    = struct.unpack_from("I", raw, offset)[0]
    frn        = struct.unpack_from("Q", raw, offset + 8)[0]
    parent_frn = struct.unpack_from("Q", raw, offset + 16)[0]
    file_attrs = struct.unpack_from("I", raw, offset + 52)[0]
    file_size  = struct.unpack_from("Q", raw, offset + 56)[0]
    name_len   = struct.unpack_from("H", raw, offset + 60)[0]
    name_off   = struct.unpack_from("H", raw, offset + 62)[0]
    name       = raw[offset+name_off : offset+name_off+name_len].decode("utf-16-le")
    return rec_len, frn, parent_frn, file_size, file_attrs, name

Build & Distribution

Build Pipeline

text
Source Code                   PyInstaller                    Inno Setup
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
orcafile_main.py โ”€โ”
ui/*.py           โ”œโ”€โ”€โ–บ pyinstaller โ”€โ”€โ–บ dist/orcafile_main/ โ”€โ”€โ–บ inno_setup.iss
handlers/*.py     โ”‚      .spec            โ”œโ”€โ”€ orcafile_main.exe    โ”‚
workers/*.py      โ”‚                       โ”œโ”€โ”€ python310.dll        โ–ผ
ntfs_scanner/*.py โ”˜                       โ””โ”€โ”€ PyQt6/          orcafile_setup.exe
*.svg, *.ico                                                   (Windows installer)

pyinstaller --noconsole --icon=orcafile_logo.ico orcafile_main.py creates a Windows GUI app. Inno Setup (setup/inno_setup.iss) packages it into a professional installer with Start Menu and Desktop shortcuts.

Cross-Platform Support

ConcernImplementation
Taskbar iconWindows-only SetCurrentProcessExplicitAppUserModelID() via ctypes
File managerexplorer /select, ยท open -R ยท xdg-open
Theme persistenceQSettings: Windows Registry / ~/.config / ~/Library/Preferences
NTFS scannerWindows only (pywin32). Falls back to os.walk() on macOS/Linux
Path handlingos.path.join(), os.path.normpath() โ€” platform-aware
DependenciesPyQt6 (all platforms) + pywin32 (Windows only, optional)