class_docstr: Display a dialog for configuring readers
  
  The dialog handles fetching current defaults and setting the
  defaults when the user hits OK.
class_docstr_tok: ["Display","a","dialog","for","configuring","readers","The","dialog","handles","fetching","current","defaults","and","setting","the","defaults","when","the","user","hits","OK","."]
code: def __init__(
      self,
      parent=None,
      ID=-1,
      title="CellProfiler Image Readers",
      size=wx.DefaultSize,
      pos=wx.DefaultPosition,
      style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
      name=wx.DialogNameStr,
  ):
      wx.Dialog.__init__(
          self, parent, ID, title, pos, size, style, name
      )
      self.changed_settings = {}
      self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY)
      main_sizer = wx.BoxSizer(wx.VERTICAL)
      main_sizer.SetMinSize((800, 600))
      self.SetSizer(main_sizer)
      h_splitter = wx.BoxSizer(wx.HORIZONTAL)
      main_sizer.Add(h_splitter, 1, wx.EXPAND)
      v_splitter = wx.BoxSizer(wx.VERTICAL)
      self.active_readers = wx.ListBox(self)
      self.inactive_readers = wx.ListBox(self)
      active_header = wx.StaticText(self, label="Active Readers")
      inactive_header = wx.StaticText(self, label="Inactive Readers")
      self.header_font = active_header.GetFont().MakeBold()
      active_header.SetFont(self.header_font)
      inactive_header.SetFont(self.header_font)
      v_splitter.Add(active_header)
      v_splitter.Add(self.active_readers, 1, wx.EXPAND)
      v_splitter.AddSpacer(10)
      v_splitter.Add(inactive_header)
      v_splitter.Add(self.inactive_readers, 1, wx.EXPAND)
  
      self.control_panel = wx.lib.scrolledpanel.ScrolledPanel(self)
      self.control_panel.SetupScrolling(scroll_x=False)
  
      self.control_sizer = wx.BoxSizer(wx.VERTICAL)
      self.control_panel.SetSizer(self.control_sizer)
      h_splitter.Add(
          v_splitter, proportion=1, flag=wx.EXPAND | wx.ALL, border=10
      )
      h_splitter.Add(
          self.control_panel,
          proportion=3,
          flag=wx.EXPAND | wx.ALL,
          border=10,
      )
  
      control_frame_header = wx.StaticText(
          self.control_panel, label="Reader Properties"
      )
      control_frame_header.SetFont(self.header_font)
      self.control_sizer.Add(control_frame_header, flag=wx.ALL)
  
      default_text = wx.StaticText(
          self.control_panel, label="Select a reader to configure"
      )
      self.control_sizer.AddSpacer(20)
      self.control_sizer.Add(default_text, 0, wx.EXPAND)
  
      self.active_readers.Bind(wx.EVT_LISTBOX, self.on_select_reader)
      self.inactive_readers.Bind(wx.EVT_LISTBOX, self.on_select_reader)
  
      btnsizer = wx.StdDialogButtonSizer()
      btnSave = wx.Button(self, wx.ID_SAVE)
      btnCancel = wx.Button(self, wx.ID_CANCEL)
      btnsizer.SetAffirmativeButton(btnSave)
      btnsizer.SetCancelButton(btnCancel)
      self.Bind(wx.EVT_BUTTON, self.save_reader_config, id=wx.ID_SAVE)
      btnsizer.Realize()
      main_sizer.Add(
          btnsizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5
      )
      self.populate_readers()
      self.Fit()
  
file_path: CellProfiler/src/frontend/cellprofiler/gui/readers_dialog/_readers_dialog.py
imports: import logging
  import textwrap
  import wx
  import wx.lib.scrolledpanel
  from wx.lib.agw.infobar import AutoWrapStaticText
  from cellprofiler_core.preferences import config_write_typed, config_read_typed
  from cellprofiler_core.reader import activate_readers
  from cellprofiler_core.constants.reader import ALL_READERS, BAD_READERS, AVAILABLE_READERS
  from ..html.utils import rst_to_html_fragment
  from ..htmldialog import HTMLDialog
label_desc: Use image node_id 1 to create a new ReadersDialog object from inherited base classes: wx with example: obj = ReadersDialog(parent, ID, title, size, pos, style, name)