jdxi_editor.ui.editors.io.program

ProgramEditor Module

This module defines the ProgramEditor class, a PySide6-based GUI for managing and selecting MIDI programs.

It allows users to browse, filter, and load programs based on bank, genre, and program number.

The class also facilitates MIDI integration by sending Program Change (PC) and Bank Select (CC#0, CC#32) messages.

Key Features: - Graphical UI for selecting and managing MIDI programs. - Filtering options based on bank and genre. - MIDI integration for program selection and loading. - Image display for program categories. - Program list population based on predefined program data.

Classes:
ProgramEditor(QMainWindow)

A main window class for handling MIDI program selection and management.

Signals:
program_changed (int, str, int)

Emitted when a program selection changes. Parameters: - MIDI channel (int) - Preset name (str) - Program number (int)

Dependencies: - PySide6.QtWidgets - PySide6.QtCore - MIDIHelper for MIDI message handling - PresetHandler for managing program presets - JDXiProgramList.PROGRAM_LIST for predefined program data

Classes

MidiFileDelegate

Delegate for MIDI file selection with file dialog.

PlayButtonDelegate

Delegate for Play button in table.

ProgramEditor

Program Editor Window

Module Contents

class jdxi_editor.ui.editors.io.program.MidiFileDelegate(table_widget=None, parent=None)[source]

Bases: PySide6.QtWidgets.QStyledItemDelegate

Delegate for MIDI file selection with file dialog.

_dialog_open = False[source]
table_widget = None[source]
paint(painter, option, index)[source]

Paint the cell with a button-like appearance.

editorEvent(event, model, option, index)[source]

Handle mouse clicks to open file dialog.

sizeHint(option, index)[source]

Return appropriate size for the button.

class jdxi_editor.ui.editors.io.program.PlayButtonDelegate(parent=None, play_callback=None)[source]

Bases: PySide6.QtWidgets.QStyledItemDelegate

Delegate for Play button in table.

play_callback = None[source]
paint(painter, option, index)[source]

Draw a play button.

editorEvent(event, model, option, index)[source]

Handle button click.

sizeHint(option, index)[source]

Return button size.

class jdxi_editor.ui.editors.io.program.ProgramEditor(midi_helper: jdxi_editor.midi.io.helper.MidiIOHelper | None = None, parent: PySide6.QtWidgets.QWidget | None = None, preset_helper: jdxi_editor.jdxi.preset.helper.JDXiPresetHelper = None)[source]

Bases: jdxi_editor.ui.editors.synth.simple.BasicEditor

Program Editor Window

program_changed[source]
title_right_vlayout = None[source]
program_list = None[source]
file_label = None[source]

Initialize the ProgramEditor

Parameters:
  • midi_helper – Optional[MidiIOHelper]

  • parent – Optional[QWidget]

  • preset_helper – JDXIPresetHelper

midi_helper = None[source]
preset_helper = None[source]
channel[source]
midi_requests[source]
default_image = 'programs.png'[source]
instrument_icon_folder = 'programs'[source]
instrument_title_label[source]
layout = None[source]
midi_channel = 0[source]
genre_label = None[source]
program_number_combo_box = None[source]
program_name = ''[source]
bank_combo_box = None[source]
load_button = None[source]
save_button = None[source]
image_label = None[source]
title_label = None[source]
bank_label = None[source]
program_label = None[source]
genre_combo_box = None[source]
preset_type = None[source]
programs[source]
_current_playlist_row = None[source]
_playlist_midi_editor = None[source]
controls: Dict[picomidi.sysex.parameter.address.AddressParameter, PySide6.QtWidgets.QWidget][source]
setup_ui()[source]

set up ui elements

_create_preset_selection_widget() PySide6.QtWidgets.QWidget[source]

create_preset_selection_widget

Returns:

QWidget

load_preset_by_program_change(preset_index: int) None[source]

Load a preset by program change.

Parameters:

preset_index – int

on_category_changed(_: int) None[source]

Handle category selection change.

_create_transport_group() PySide6.QtWidgets.QGroupBox[source]

_create_transport_group

Returns:

QGroupBox

Transport controls area

_create_program_selection_box() PySide6.QtWidgets.QGroupBox[source]

create_program_selection_box

Returns:

QGroupBox

edit_program_name()[source]

edit_tone_name

Returns:

None

on_preset_type_changed(index: int) None[source]

on_preset_type_changed

Parameters:

index – int

Handle preset type selection change

set_channel_and_preset_lists(preset_type: str) None[source]

set_channel_and_preset_lists

Parameters:

preset_type

Returns:

None

update_category_combo_box_categories() None[source]

update_category_combo_box_categories

Returns:

None

Update the category combo box.

_populate_programs(search_text: str = '') None[source]

Populate the program list with available presets.

Parameters:

search_text – str

Returns:

None

_populate_presets(search_text: str = '') None[source]

Populate the program list with available presets.

Parameters:

search_text – str

Returns:

None

_init_synth_data(synth_type: jdxi_editor.jdxi.synth.type.JDXiSynth = JDXiSynth.DIGITAL_SYNTH_1, partial_number: int | None = 0) None[source]
Parameters:
  • synth_type – JDXiSynth

  • partial_number – int

Returns:

None

Initialize synth-specific data

_create_mixer_section() PySide6.QtWidgets.QWidget[source]

_create_mixer_section

Returns:

QWidget

Create general vocal effect controls section with scrolling

update_tone_name_for_synth(tone_name: str, synth_type: str) None[source]

Update the tone name.

Parameters:
  • tone_name – str

  • synth_type – str

set_current_program_name(program_name: str, synth_type: str = None) None[source]

Set the current program name in the file label

Parameters:
  • program_name – str

  • synth_type – str (optional), discarded for now

Returns:

None

start_playback()[source]

Start playback of the MIDI file.

stop_playback()[source]

Stop playback of the MIDI file.

populate_programs(search_text: str = '')[source]

Populate the program list with available presets. Uses SQLite database to ensure all user bank programs are loaded correctly.

add_user_banks(filtered_list: list, bank: str, search_text: str = None) None[source]

Add user banks to the program list. Only adds generic entries for programs that don’t exist in the database. Uses SQLite database for reliable lookups. :param search_text: :param filtered_list: list of programs already loaded from database :param bank: str

_create_user_programs_tab() PySide6.QtWidgets.QWidget[source]

Create the User Programs tab with a sortable, searchable table.

Returns:

QWidget containing the user programs table

_get_table_style() str[source]

Get custom styling for tables with rounded corners and charcoal embossed cells.

Returns:

str CSS style string

_populate_user_programs_table(search_text: str = '') None[source]

Populate the user programs table from SQLite database.

Parameters:

search_text – Optional search text to filter programs

_save_user_programs_changes() None[source]

Save changes made to the user programs table (e.g., genre edits) to the database.

_create_playlist_tab() PySide6.QtWidgets.QWidget[source]

Create the Playlist tab with a table showing all playlists.

Returns:

QWidget containing the playlist table

_populate_playlist_table() None[source]

Populate the playlist table from SQLite database.

_create_new_playlist() None[source]

Create a new playlist.

_refresh_playlists() None[source]

populate programs

_delete_selected_playlist() None[source]

Delete the selected playlist.

_on_playlist_item_changed(item: PySide6.QtWidgets.QTableWidgetItem) None[source]

Handle changes to playlist name or description.

Parameters:

item – The table item that was changed

_on_playlist_selected(item: PySide6.QtWidgets.QTableWidgetItem) None[source]

Handle double-click on a playlist. Could open playlist editor or show playlist programs.

Parameters:

item – The table item that was double-clicked

_create_playlist_editor_tab() PySide6.QtWidgets.QWidget[source]

Create the Playlist Editor tab for editing playlist contents.

Returns:

QWidget containing the playlist editor

_populate_playlist_editor_combo() None[source]

Populate the playlist selection combo box.

_on_playlist_programs_selection_changed() None[source]

Handle selection change in playlist programs table.

_on_playlist_editor_playlist_changed(index: int) None[source]

Handle playlist selection change in the editor.

_populate_playlist_programs_table(playlist_id: int) None[source]

Populate the playlist programs table with programs from the selected playlist.

Parameters:

playlist_id – Playlist ID

_on_cheat_preset_changed(row: int, cheat_preset_id: str | None) None[source]

Handle cheat preset selection change.

Parameters:
  • row – Table row index

  • cheat_preset_id – Selected cheat preset ID or None

_on_playlist_program_item_changed(item: PySide6.QtWidgets.QTableWidgetItem) None[source]

Handle changes to playlist program items (e.g., MIDI file path).

Parameters:

item – The table item that was changed

_add_program_to_playlist() None[source]

Add a program to the selected playlist.

_delete_program_from_playlist() None[source]

Delete selected program(s) from the playlist.

_play_playlist_program(index) None[source]

Play the MIDI file associated with a playlist program.

Parameters:

index – QModelIndex of the play button

_on_playlist_playback_finished()[source]

Called when MIDI playback finishes. Advances to the next playlist item.

_on_playlist_program_double_clicked(item: PySide6.QtWidgets.QTableWidgetItem) None[source]

Handle double-click on a playlist program item. If the Program Name column (column 2) is clicked, show the Program Editor.

Parameters:

item – The table item that was double-clicked

_load_program_from_table_for_playlist(row: int) None[source]

Load a program from the playlist programs table and send MIDI Program Change.

Parameters:

row – Row index in the table

_load_cheat_preset(preset_id: str) None[source]

Load a cheat preset (Digital Synth preset) on the Analog Synth channel (Ch3).

Parameters:

preset_id – Preset ID (e.g., “113”)

_on_user_program_selected(item: PySide6.QtWidgets.QTableWidgetItem) None[source]

Handle double-click on a program in the user programs table. Loads the program via MIDI Program Change.

Parameters:

item – The table item that was double-clicked

_on_user_program_selection_changed() None[source]

Handle selection change in the user programs table. Loads the program via MIDI Program Change when a row is selected.

_play_user_program(index) None[source]

Callback for Play button delegate - loads and plays the program.

Parameters:

index – QModelIndex from the delegate

_load_program_from_table(row: int) None[source]

Load a program from the table and send MIDI Program Change.

Parameters:

row – Row index in the table

on_bank_changed(_: int) None[source]

Handle bank selection change.

on_program_number_changed(index: int) None[source]

Handle program number selection change. :param index: int

load_program()[source]

Load the selected program based on bank and number.

update_current_synths(program_details: jdxi_editor.jdxi.program.program.JDXiProgram) None[source]

Update the current synth label. :param program_details: dict :return: None

load_preset(program_number: int) None[source]

load_preset

Parameters:

program_number – int

Returns:

None

Load preset data and update UI

_update_program_list() None[source]

Update the program list with available presets.

on_genre_changed(_: int) None[source]

Handle genre selection change.

Parameters:

_ – int

_dispatch_sysex_to_area(json_sysex_data: str) None[source]

Dispatch SysEx data to the appropriate area for processing.

Parameters:

json_sysex_data

Returns:

None

_update_common_controls(partial_number: int, sysex_data: Dict, successes: list = None, failures: list = None) None[source]

Update the UI components for tone common and modify parameters.

Parameters:
  • partial_number – int partial number

  • sysex_data – Dictionary containing SysEx data

  • successes – List of successful parameters

  • failures – List of failed parameters

Returns:

None

_update_slider(param: picomidi.sysex.parameter.address.AddressParameter, midi_value: int, successes: list = None, failures: list = None, slider: PySide6.QtWidgets.QWidget = None) None[source]

Update slider based on parameter and value.

Parameters:
  • param – AddressParameter

  • midi_value – int value

  • successes – list

  • failures – list

Returns:

None