jdxi_editor.ui.editors.program.editor

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 digital 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

ProgramEditorDimensions

ProgramEditor Dimensions

EditorSpec

Editor Spec

ProgramEditor

Program Editor Window

Module Contents

class jdxi_editor.ui.editors.program.editor.ProgramEditorDimensions[source]

Bases: jdxi_editor.ui.style.dimensions.Dimensions

ProgramEditor Dimensions

WIDTH = 400[source]
HEIGHT = 400[source]
class jdxi_editor.ui.editors.program.editor.EditorSpec[source]

Editor Spec

title: str = ''[source]
default_image: str = ''[source]
instrument_icon_folder: str = ''[source]
dimensions: jdxi_editor.ui.style.dimensions.Dimensions = None[source]
class jdxi_editor.ui.editors.program.editor.ProgramEditor(midi_helper: jdxi_editor.midi.io.helper.MidiIOHelper | None = None, parent: jdxi_editor.ui.common.QWidget | None = None, preset_helper: jdxi_editor.ui.preset.helper.JDXiPresetHelper = None)[source]

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

Program Editor Window

TEMPORARY_AREA_HANDLERS[source]
program_changed[source]
title_right_vlayout = None[source]
program_list = 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]
spec[source]
default_image = ''[source]
instrument_icon_folder = ''[source]
instrument_title_label[source]
layout = None[source]
midi_channel = 0[source]
genre_label = None[source]
program_name = ''[source]
bank_combo_box = None[source]
save_button = None[source]
title_label = None[source]
bank_label = None[source]
program_label = None[source]
genre_combo_box = None[source]
program_preset: jdxi_editor.ui.editors.preset.widget.PresetWidget | None = None[source]
preset_type = None[source]
programs[source]
_actual_preset_list[source]
controls: Dict[picomidi.sysex.parameter.address.AddressParameter, jdxi_editor.ui.common.QWidget][source]
mixer_widget: jdxi_editor.ui.editors.program.mixer.section.ProgramMixer | None = None[source]
program_group_widget: jdxi_editor.ui.editors.program.group.ProgramGroup | None = None[source]
user_programs_widget: jdxi_editor.ui.editors.program.user_programs_widget.UserProgramsWidget | None = None[source]
playlist_widget: jdxi_editor.ui.editors.playlist.table.PlaylistTable | None = None[source]
playlist_editor_widget: jdxi_editor.ui.editors.playlist.editor.PlaylistEditor | None = None[source]
setup_ui()[source]

set up ui elements

on_category_changed(_: int) None[source]

Handle category selection change - no longer needed, handled by SearchableFilterableComboBox.

on_preset_type_changed(index: int) None[source]

on_preset_type_changed

Parameters:

index – int

Handle preset type selection change Note: This delegates to PresetWidget’s on_preset_type_changed, but also updates ProgramEditor’s internal state.

set_channel_and_preset_lists(preset_type: str) None[source]

set_channel_and_preset_lists

Parameters:

preset_type

Returns:

None

_update_preset_combo_box() None[source]

Update the SearchableFilterableComboBox with current preset list. Called when preset type changes. Note: This method is now handled by PresetWidget._update_preset_combo_box(), but kept here for backward compatibility if needed.

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

Populate the program list with available presets. Now delegates to populate_programs() which uses _update_program_combo_box().

Parameters:

search_text – str

Returns:

None

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

Populate the program list with available presets. Now handled by SearchableFilterableComboBox, so this just updates the combo box.

Parameters:

search_text – str (ignored, handled by SearchableFilterableComboBox)

Returns:

None

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

  • partial_number – int

Returns:

None

Initialize synth-specific data

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.

_update_program_combo_box() None[source]

Update the SearchableFilterableComboBox with current program list. Handles both ROM banks (A-D) and user banks (E-H) with SQLite integration.

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

Populate the program list with available presets. Now handled by SearchableFilterableComboBox, so this just updates the combo box. 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

_add_program_to_database(program_id: str, program_name: str)[source]

add program to database

_get_table_style() str[source]

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

Returns:

str CSS style string

_on_user_program_loaded(program: jdxi_editor.midi.program.program.JDXiProgram) None[source]

Handle when a user program is loaded from the table.

Parameters:

program – JDXiProgram that was loaded

_on_playlist_changed() None[source]

Handle when a playlist is created, deleted, or updated. Refreshes the playlist editor combo if it exists.

_on_playlist_program_loaded(program: jdxi_editor.midi.program.program.JDXiProgram) None[source]

Handle when a program is loaded from the playlist editor. Updates UI to reflect the loaded program.

Parameters:

program – JDXiProgram that was loaded

_populate_playlist_editor_combo() None[source]

Populate the playlist editor combo (callback for playlist editor widget).

_get_parent_instrument() jdxi_editor.ui.common.QWidget | None[source]

Get the parent instrument widget for accessing MidiFileEditor.

Returns:

Optional[QWidget] parent instrument or None

on_bank_changed(_: int) None[source]

Handle bank selection change - no longer needed, handled by SearchableFilterableComboBox.

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. Delegates to ProgramGroupWidget’s load_program method.

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

Update the current synth labels in the mixer widget. :param program_details: JDXiProgram :return: None

load_preset(program_number: int) None[source]

Load preset by program change and refresh UI.

Parameters:

program_number – Preset ID (e.g., 1 for “001”)

Returns:

None

_update_program_list() None[source]

Update the program list with available presets.

on_genre_changed(_: int) None[source]

Handle genre selection change - no longer needed, handled by SearchableFilterableComboBox.

_normalize_program_common(sysex_data: dict) dict[source]

Normalize special Program Common address case.

_get_partial_map(temporary_area: str)[source]

get partial map

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

_handle_sliders(sysex_data: dict, temporary_area: str | None, successes: list[Any], failures: list[Any])[source]

Slider handling

get_mixer_slider_by_param(slider_param: picomidi.sysex.parameter.address.AddressParameter) jdxi_editor.ui.common.QWidget | None[source]

get mixer slider

get_mixer_slider(slider_name: str) jdxi_editor.ui.common.QWidget | None[source]

get mixer slider

_get_partial_tone_names() list[str][source]

get partial tone names

_update_common_controls(partial_number: int, sysex_data: Dict, successes: list = None, failures: list = None, temporary_area: str = 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

  • temporary_area – str TEMPORARY_PROGRAM, DIGITAL_SYNTH_1, etc.

Returns:

None

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

Update slider based on parameter and value.

Parameters:
  • param – AddressParameter

  • midi_value – int value

  • successes – list

  • failures – list

Returns:

None