Introduction to Filedini Python Scripting
This document is a tutorial for learning how to use the application’s scripting features. Starting with basic operations, you will gradually learn to create advanced dialogs.
Introduction: Basic Script Structure and Dev Environment Tips
All scripts interact with the application through a global object named host. When defining a function that uses the host object’s features, you must always accept (host: HostAPI) as an argument.
# Example: A simple function that logs a message
def my_script_function(host: HostAPI):
host.log("Script was executed!")Leveraging Type Hints and Autocompletion
By adding the following “Type Checking Block” to the top of your script file, you can enable powerful autocompletion (IntelliSense) for the host object’s methods and properties in Integrated Development Environments (IDEs) like VS Code. This can greatly improve your development efficiency.
from __future__ import annotations
from typing import TYPE_CHECKING
# =============================================================================
# Type Checking Block - Enables autocompletion in IDEs
# =============================================================================
# This block is used only by code editors (like VS Code) to provide
# intelligent code completion. It does not run during actual script execution.
if TYPE_CHECKING:
try:
# Import the type definition for 'HostAPI' from 'host_stubs'.
# This is a virtual module that doesn't exist at runtime.
from host_stubs import HostAPI
except ImportError:
pass
# This allows you to write 'host: HostAPI' in your function definitions,
# enabling autocompletion for the host object's methods.Chapter 1: Basic Operations
As a first step in scripting, let’s learn how to get the application’s state and display simple messages. The content of this chapter is mainly based on command_sample.py.
1.1 Logging Messages
To check your script’s behavior, you can output messages to the application’s log. This is very useful for debugging.
Use the host.log() method.
def log_example(host: HostAPI):
# Outputs a message to the application log
host.log("Hello, World!")1.2 Getting Application State
You can use the host.state module to get the path of the currently open folder or information about selected items.
host.state.get_current_folder_path(): Gets the current folder path.host.state.get_cursor_path(): Gets the path of the item under the cursor.host.state.get_selected_paths(): Gets a list of paths for all selected items.
Example: Calculate the total size of selected items
import os
# Helper function (assumed to be defined in the file)
def get_directory_size(folder_path: str) -> int:
total_size = 0
if not os.path.exists(folder_path) or not os.path.isdir(folder_path):
return 0
for dirpath, dirnames, filenames in os.walk(folder_path):
for f in filenames:
fp = os.path.join(dirpath, f)
if not os.path.islink(fp):
try:
total_size += os.path.getsize(fp)
except OSError:
pass
return total_size
def get_readable_size(total_bytes: int) -> str:
# ... logic for formatting size ...
if total_bytes < 1024:
return f"{total_bytes} Bytes"
elif total_bytes < (1024**2):
return f"{total_bytes / 1024:.2f} KB"
elif total_bytes < (1024**3):
return f"{total_bytes / (1024**2):.2f} MB"
else:
return f"{total_bytes / (1024**3):.2f} GB"
def calculate_selected_size(host: HostAPI):
# 1. Get the paths of all selected items
selected_paths = host.state.get_selected_paths()
if not selected_paths:
host.ui.ok_dialog("Selected Size", "No items are selected.")
return
total_bytes = 0
# 2. Sum the size of each item
for path in selected_paths:
if os.path.isdir(path):
total_bytes += get_directory_size(path)
elif os.path.isfile(path):
total_bytes += os.path.getsize(path)
# 3. Display the result in a dialog
host.ui.ok_dialog(
"Selected Items Size",
f"Items: {len(selected_paths)}\nTotal Size: {get_readable_size(total_bytes)}"
)1.3 Displaying Simple Dialogs
To inform the user of a script’s result, you can display simple dialog boxes. The host.ui module provides several predefined dialogs.
host.ui.ok_dialog(title, message): A dialog with only an [OK] button.host.ui.ok_cancel_dialog(title, message): A dialog with [OK] and [Cancel] buttons.host.ui.input_text_dialog(title, message, initial_text): A dialog with a text input field. It returns anInputTextDialogResponseobject.host.ui.yes_no_dialog(title, message): A dialog with [Yes] and [No] buttons. It returnsDialogResult.YESorDialogResult.NOdepending on the user’s choice.
Example: Displaying an [OK] Dialog
def show_simple_ok_dialog(host: HostAPI):
host.ui.ok_dialog("Folder Size", "The total size is 123 MB.")Using the Text Input Dialog
The host.ui.input_text_dialog is used to get text input from the user. This function returns an InputTextDialogResponse object, which contains the dialog’s result (.result) and the text the user entered (.text).
Example: Asking the user for their name
def ask_for_name(host: HostAPI):
# Show the text input dialog and receive the response
response = host.ui.input_text_dialog("User Info", "Please enter your name:", "Anonymous")
# Check the result to branch the logic
if response.result == host.ui.DialogResult.OK:
# If OK was pressed, get the entered text
name = response.text
host.log(f"User entered name: {name}")
host.ui.ok_dialog("Hello", f"Hello, {name}!")
else:
# If Cancel was pressed
host.log("User cancelled name entry.")
host.ui.ok_dialog("Cancelled", "Name entry was cancelled.")Branching Logic with Return Values
Dialogs with multiple buttons, like ok_cancel_dialog and yes_no_dialog, return a value depending on which button was pressed. By checking this return value (host.ui.DialogResult), you can change your script’s behavior based on the user’s choice.
Example: Confirming an action with the user
def confirm_action(host: HostAPI):
# Display an OK/Cancel dialog and get the user's choice
result = host.ui.ok_cancel_dialog("Confirm", "Do you want to proceed?")
# Check the return value to branch the logic
if result == host.ui.DialogResult.OK:
# Action for when OK is pressed
host.log("User chose to proceed.")
host.ui.ok_dialog("Proceeding", "The action will be performed.")
else:
# Action for when Cancel is pressed or the dialog is closed
host.log("User cancelled the action.")
host.ui.ok_dialog("Cancelled", "The action was cancelled.")1.4 Using Python Libraries
In your scripts, you can freely import and use Python’s standard libraries (such as os, sys, datetime, etc.). This allows you to easily perform complex tasks like file operations and date calculations.
Installing and Using External Libraries
Furthermore, by using the host.install() method, you can install and use external libraries published on PyPI (e.g., numpy, requests, pandas) during script execution.
host.install() will only perform the installation if the library is not already installed. If it’s already available, it does nothing.
Example: Installing and using the numpy library
def use_numpy_example(host: HostAPI):
# 1. Request the installation of the 'numpy' package.
# This ensures the library is available before importing.
if host.install("numpy"):
# 2. Import the library.
import numpy as np
# 3. Use the library's features.
arr = np.array([1, 2, 3])
# 4. Display the result in a dialog.
host.ui.ok_dialog(
"NumPy Example",
f"NumPy version {np.__version__} is available.\nCreated array: {arr}"
)
else:
host.ui.ok_dialog(
"NumPy Example",
"Failed to install NumPy."
)Chapter 2: Creating Custom Dialogs
The host.ui feature allows you to create custom dialogs with freely arranged text inputs and buttons. This chapter is based on custom_dialog_sample.py.
2.1 Basic Dialog Structure
- Start the dialog builder with
host.ui.dialog(title). - Add controls (text boxes, buttons, etc.) to the builder.
- Display the dialog modally with
dlg.show_modal()and wait for the user to close it. - Use the return value of
show_modal()to determine which button was pressed.
2.2 Adding Controls and Handling Events
- Text Input:
dlg.text(label, initial_text) - Button:
dlg.button(text)
The action for a button click is defined by adding a lambda expression or a function to the .clicked event with +=.
To close the dialog, call dlg.close(result), where result can be host.ui.DialogResult.OK, host.ui.DialogResult.CANCEL, etc.
Example: A simple input dialog
def show_modal_dialog_example(host: HostAPI):
# 1. Create a dialog builder
dlg = host.ui.dialog("Modal Dialog Sample")
# 2. Add a text input control with the label "Enter your name"
name_input = dlg.text("Enter your name", "no-name")
# 3. Add a button and define its click event
# When the "Close" button is pressed, close the dialog with an OK result
close_button = dlg.button("Close")
close_button.clicked += lambda s, e: dlg.close(host.ui.DialogResult.OK)
# 4. Show the dialog and wait for the user\'s action
result = dlg.show_modal()
# 5. Process after the user presses the "Close" button
if result == host.ui.DialogResult.OK:
# Get the value from the text input and log it
host.log(f"Name entered: {name_input.text}")2.3 Grouping Controls
You can arrange controls horizontally or vertically using dlg.group(direction).
host.ui.LayoutDirection.HORIZONTAL: Arrange horizontallyhost.ui.LayoutDirection.VERTICAL: Arrange vertically (default)
Example: Arranging buttons horizontally
def show_horizontal_buttons(host: HostAPI):
dlg = host.ui.dialog("Confirmation")
# Create a horizontal group
buttons_group = dlg.group(host.ui.LayoutDirection.HORIZONTAL)
# Controls added to this group will be arranged side-by-side
buttons_group.button("Yes").clicked += lambda s, e: dlg.close(host.ui.DialogResult.YES)
buttons_group.button("No").clicked += lambda s, e: dlg.close(host.ui.DialogResult.NO)
dlg.show_modal()Chapter 3: Building Advanced UIs
Based on advanced_dialog_sample.py, let’s learn how to create dialogs with more complex layouts and a variety of controls.
3.1 Diverse Controls
In custom dialogs, you can use many controls besides text inputs and buttons.
- Checkbox:
dlg.bool(label, initial_value) - Integer Slider:
dlg.int(label, initial_value, min, max) - Float Slider:
dlg.float(label, initial_value, min, max) - Choice (Dropdown/Radio Button):
dlg.choice(label, items_list, initial_index, style) - Label:
dlg.label(text) - Separator:
dlg.separator()
You can access the current value of each control through its value property.
3.2 Advanced Layouts
To build complex UIs, you can nest groups and use tabs or group boxes.
- Group Box:
dlg.group_box(title, direction)- Surrounds controls with a titled border.
- Tab:
dlg.tab()- Add tab pages with
tab.page(title)and place controls on them.
- Add tab pages with
Example: A settings-like dialog
def show_settings_dialog(host: HostAPI):
dlg = host.ui.dialog("Settings")
# 1. Create a tab control
tab = dlg.tab()
# 2. Create a "General" tab page and add controls
general_page = tab.page("General")
general_page.bool("Auto-save", True)
general_page.int("Font size:", 12, 8, 24)
# 3. Create an "Appearance" tab page and add controls
appearance_page = tab.page("Appearance")
themes = ["Light", "Dark", "Auto"]
theme_choice = appearance_page.choice("Theme", themes, 0)
scale_slider = appearance_page.float("UI Scale:", 1.0, 0.5, 2.0)
# 4. Add OK/Cancel buttons
buttons = dlg.group(host.ui.LayoutDirection.HORIZONTAL)
buttons.button("Apply").clicked += lambda s, e: dlg.close(host.ui.DialogResult.OK)
buttons.button("Cancel").clicked += lambda s, e: dlg.close(host.ui.DialogResult.CANCEL)
# Show the dialog
result = dlg.show_modal()
# If OK, log the settings
if result == host.ui.DialogResult.OK:
host.log("Settings applied!")
host.log(f" Theme: {theme_choice.selected_item}")
host.log(f" UI Scale: {scale_slider.value}")3.3 Leveraging Events
Each control has events that fire when its value changes (e.g., text_changed, value_changed, selected_changed). Using these, you can create dynamic dialogs that react to user actions in real-time.
Example: Linking a checkbox and a slider
def show_linked_controls_dialog(host: HostAPI):
dlg = host.ui.dialog("Linked Controls")
left = dlg.group(host.ui.LayoutDirection.VERTICAL)
# "Enabled" checkbox
enabled_check = left.bool("Enabled", True)
# Integer slider
int_slider = left.int("Int", 10, -100, 100)
# Toggle the slider\'s enabled state when the checkbox value changes
def on_enabled_changed(s, e):
int_slider.enabled = enabled_check.value
enabled_check.value_changed += on_enabled_changed
dlg.group(host.ui.LayoutDirection.HORIZONTAL).button("Close").clicked += \
lambda s, e: dlg.close(host.ui.DialogResult.OK)
dlg.show_modal()In this tutorial, you’ve learned everything from the basics of scripting to more advanced topics. Try modifying these samples or consulting the API reference to create your own useful scripts.
The API is still under development and is not yet fully sufficient. Please feel free to share any requests you may have.