unit UnitFrmConfig;
{
    Purpose:
        This form configures the hotkey as well as receives messages
        when the hotkey is pressed.

        This form also reads the current configuration and passes those
        option onto the responsible form (mainly FrmMainPopup)

    Updates:
        New panel for Popup "Config -> Popup - Keystrokes"
        Updated for option to show popup on double-click
        Removed Items now saved << no longer needed with cached removed items


        --------------
        New Form Mode show option
        Fixed logic for "Show Permanent Items" and selecting a
        display method.
        ------------
        New "SHIFT+INSERT" pasting options

        Moved the popup "show" options to their own panel
        New "Show Options" subitem under Popup
        New user definable function key for copy & permanent
        popup keystrokes.


        New Clipboard option - "Disable clipboard Monitoring when Scroll Lock is on"

        New look
        New way to do hotkeys

        Used ini.ReadInteger where appropriate
        Using UnitClipQueue
}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, ImgList, UnitHotKey, UnitFrmPermanentNew, UnitFrmHotkey,
  Buttons, UnitFrmTriggerWindow, UnitFrameMySlide, Vcl.Menus,
  Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnPopup, Vcl.CheckLst;


type FormatOrder = (FO_UNICODE, FO_HTML, FO_RICHTEXT);
type TMenuOrderType =
(
    MOT_MENU,
    MOT_OTHER, //not used
    MOT_CANCEL,
    MOT_LAST,  //not used
    MOT_CURRENT,
    MOT_REMOVED, // not used
    MOT_PROGRAM,
    MOT_SYSTEM,
    MOT_PASTEUTILS,
    MOT_PERMANENT,
    MOT_SWITCH,
    MOT_FULL,
    MOT_ALLPERMANENT,
    MOT_SELECTED, // not used
    MOT_CLICKED, // not used
    MOT_SEARCH,
    MOT_BREAK
);
Type TClickAction = (
    CA_Run = 0,
    CA_RemoveUndelete = 1,
    CA_Destroy_Clip = 2,
    CA_Edit_Clip = 3,
    CA_Edit_Clip_as_file = 4,
    //CA_Preview_Clip = 5,
    CA_Paste_using_Mimic_Typing = 5,
    CA_Paste_on_Clipboard_only = 6,
    CA_Paste_using_ShiftInsert = 7,
    CA_Paste_using_CtrlV = 8,
    CA_Make_Permanent_Clip = 9,
    CA_Make_Permanent_Clip_as_Plain_Text = 10,
    CA_Show_RightClick_Menu = 11,
    CA_Paste_and_Keep_Popup_Open = 12,
    CA_Paste_as_Plaintext_only = 13,
    CA_Pin_Unpin_Clip = 14,
    CA_Paste_as_Formatted_only = 15,
    CA_Show_Titlebar_Shortcut_Keys = 16
);
TWheelAction =
(
    WA_CLIPSET = 0,
    WA_HIGHLIGHT = 1
);

TCBXIconType = (
    CBXICONTYPE_PROGRAM = 0,
    CBXICONTYPE_CLIPTYPE = 1,
    CBXICONTYPE_NONE = 2
);
TCBXRepeatIcons = (
    CBXREPEATICONS_DIMMED = 0,
    CBXREPEATICONS_NORMAL = 1,
    CBXREPEATICONS_HIDDEN = 2
);
TCBXIconClickAction = (
    CBXICONCLICKACTION_EDIT =0,
    CBXICONCLICKACTION_PIN =1,
    CBXICONCLICKACTION_DELETE=2,
    CBXICONCLICKACTION_DESTROY=3,
    CBXICONCLICKACTION_CLIPBOARD=4,
    CBXICONCLICKACTION_MIMIC=5,
    CBXICONCLICKACTION_SHIFTINSERT=6,
    CBXICONCLICKACTION_CTRLV=7
);

type
  TFrmConfig = class(TForm)
    {$REGION 'Default'}
    btnSave: TButton;
    btnCancel: TButton;
    ImageList1: TImageList;
    FontDialog: TFontDialog;
    Panel10: TPanel;
    tvOptions: TTreeView;
    pcPanels: TPageControl;
    tsHotkey: TTabSheet;
    tsClipboard: TTabSheet;
    tsText: TTabSheet;
    tsNonText: TTabSheet;
    tsPopup: TTabSheet;
    tsMenuOrder: TTabSheet;
    tsShowOptions: TTabSheet;
    tsKeystrokes: TTabSheet;
    tsTooltipHint: TTabSheet;
    tsMisc: TTabSheet;
    tsTriggerWindow: TTabSheet;
    tsHotkeyAlternatives: TTabSheet;
    tsProgramOptions: TTabSheet;
    tsClipboardBar: TTabSheet;
    tsHistory: TTabSheet;
    Label73: TLabel;
    odSound: TOpenDialog;
    timUpdatePreview: TTimer;
    ColorDialog1: TColorDialog;
    tsClipSets: TTabSheet;
    //pmExampleColors: TPopupMenu;
//    DefaultScheme1: TMenuItem;
//    SuperDark1: TMenuItem;
//    JoeJoeSpecial1: TMenuItem;
//    Greyscale1: TMenuItem;
//    MetroGreen1: TMenuItem;
//    MetroSteelBlue1: TMenuItem;
//    Woodgrain1: TMenuItem;


    tsJumplist: TTabSheet;
    pmPermClips: TPopupActionBar;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    tsColorScheme: TTabSheet;
    tsLocation: TTabSheet;
    cpgClipboardBar: TCategoryPanelGroup;

    GroupBox2: TGroupBox;
    Label13: TLabel;
    udNormalOpacity: TMySlide;
    GroupBox24: TGroupBox;
    cbBarSnapToScreen: TCheckBox;
    cbClipboardBarVirtualDesktop: TCheckBox;

    GroupBox7: TGroupBox;
    Label70: TLabel;
    cbEnableClipboardBar: TCheckBox;

    GroupBox8: TGroupBox;
    Label87: TLabel;
    cbShowPopupWhenClicked: TCheckBox;
    cbShowTooltipOnHover: TCheckBox;
    cpgTiggerWindow: TCategoryPanelGroup;


    GroupBox20: TGroupBox;
    Label19: TLabel;
    cbTriggerWindow: TCheckBox;
    Label41: TLabel;
    tbDelay: TTrackBar;
    Label44: TLabel;
    Label45: TLabel;
    GroupBox1: TGroupBox;
    sbbottomleft: TSpeedButton;
    sbLeft: TSpeedButton;
    sbtopleft: TSpeedButton;
    sbTop: TSpeedButton;
    sbBottom: TSpeedButton;
    sbtopright: TSpeedButton;
    sbRight: TSpeedButton;
    sbbottomright: TSpeedButton;
    cbUseVirtualDesktop: TCheckBox;
    cpgClipSets: TCategoryPanelGroup;


    rbClipSetsAlways: TRadioButton;
    rbClipSetsSelective: TRadioButton;
    GroupBox21: TGroupBox;
    cbEnableClipSets: TCheckBox;
    cbEnableClipsSetsWhenTall: TCheckBox;
    Label80: TLabel;
    udClipsPerSet: TMySlide;
    GroupBox22: TGroupBox;
    Label37: TLabel;
    Label42: TLabel;
    Label43: TLabel;
    Label34: TLabel;
    cbxFilterEnter: TComboBox;
    cbxFilterESC: TComboBox;
    cbxFilterTab: TComboBox;
    cbFilterAlways: TCheckBox;
    Label79: TLabel;
    cbFilterSimplified: TCheckBox;
    cpgKeystrokes: TCategoryPanelGroup;
    pnl4: TPanel;
    Shape2: TShape;
    btnBarTopLeft: TSpeedButton;
    btnBarLeft: TSpeedButton;
    btnBarBottomLeft: TSpeedButton;
    btnBarBottom: TSpeedButton;
    btnBarTop: TSpeedButton;
    btnBarTopRight: TSpeedButton;
    btnBarRight: TSpeedButton;
    btnBarBottomRight: TSpeedButton;
    cpgBehavior: TCategoryPanelGroup;


    GroupBox12: TGroupBox;
    rbPaste: TRadioButton;
    rbPasteSI: TRadioButton;
    rbClipboardOnly: TRadioButton;
    rbTyping: TRadioButton;
    GroupBox5: TGroupBox;
    Label36: TLabel;
    rbPlainAndFormatted: TRadioButton;
    rbFormattedOnly: TRadioButton;
    rbPlainOnly: TRadioButton;
    Label94: TLabel;

    GroupBox19: TGroupBox;
    cbAutoCollapse: TCheckBox;
    cbAutoExpand: TCheckBox;
    GroupBox26: TGroupBox;
    Label21: TLabel;
    rbLocationAutomatic: TRadioButton;
    rbLocationMouseCursor: TRadioButton;
    Label31: TLabel;
    rbLocationProgramCorner: TRadioButton;
    Label33: TLabel;
    Label26: TLabel;
    cpgHotkeyAlt: TCategoryPanelGroup;


    GroupBox23: TGroupBox;
    Label20: TLabel;
    Label66: TLabel;
    cbRightTriggerEnable: TCheckBox;
    cbxMouseButton: TComboBox;
    tbHoldDelay: TTrackBar;
    GroupBox15: TGroupBox;
    cbPopupDoubleclick: TCheckBox;
    cbPopupSingleclick: TCheckBox;
    cbPopupDoubleclickTray: TCheckBox;
    cbPopupSingleclickTray: TCheckBox;

    Label17: TLabel;
    lblClipboardBar: TLabel;
    lblTriggerWindow: TLabel;
    lblJumpList: TLabel;
    Label60: TLabel;
    Label61: TLabel;
    Shape3: TShape;
    cpgProgramOptions: TCategoryPanelGroup;


    Label90: TLabel;
    Label92: TLabel;
    Label88: TLabel;
    Label84: TLabel;
    Label96: TLabel;
    Label97: TLabel;
    Label98: TLabel;
    Label99: TLabel;
    Label65: TLabel;
    pnl7: TPanel;
    pnl6: TPanel;
    btnAddName: TButton;
    lvPrograms: TListView;
    cpgHistory: TCategoryPanelGroup;
    pnl10: TPanel;
    Label18: TLabel;
    Label2: TLabel;
    Label53: TLabel;
    Label1: TLabel;
    Label55: TLabel;
    lblClipSet: TLabel;
    Label58: TLabel;
    udRemovedSize: TJJSlide;
    udQueueSize: TJJSlide;
    btnEditPopupClips: TSpeedButton;
    Label29: TLabel;
    Label59: TLabel;
    cpgJumplist: TCategoryPanelGroup;

    Label82: TLabel;
    Label83: TLabel;
    cbxClickedAction: TComboBox;
    cpgColor: TCategoryPanelGroup;

    GroupBox29: TGroupBox;
    cbClickedColor: TCheckBox;
    pnlClickedColor: TPanel;
    cbHighlightColor: TCheckBox;
    pnlHighlightColor: TPanel;
    cbBackgroundColor: TCheckBox;
    pnlBackgroundColor: TPanel;
    cbFontColor: TCheckBox;
    pnlFontColor: TPanel;
    btnColorExamples: TSpeedButton;
    pnl1: TPanel;
    imgPreview: TImage;
    pmExampleColors: TPopupActionBar;
    DefaultScheme1: TMenuItem;
    SuperDark1: TMenuItem;
    JoeJoeSpecial1: TMenuItem;
    Greyscale1: TMenuItem;
    MetroGreen1: TMenuItem;
    MetroSteelBlue1: TMenuItem;
    Woodgrain1: TMenuItem;
    Label102: TLabel;
    Label103: TLabel;
    Label106: TLabel;
    cbxMode: TComboBox;
    cpgHotkeys: TCategoryPanelGroup;

    Label54: TLabel;
    GroupBox32: TGroupBox;
    btnSystemClips: TSpeedButton;
    Label67: TLabel;
    Label95: TLabel;
    lvHotkeys: TListView;

    pnl11: TPanel;
    Shape1: TShape;
    lblKeyname: TLabel;
    Label5: TLabel;
    Label69: TLabel;
    bEditPopupHotkey: TButton;
    pnl12: TPanel;
    Shape4: TShape;
    Label23: TLabel;
    lblPlaintext: TLabel;
    btnEditPlaintextHotkey: TButton;
    cpgClipboard: TCategoryPanelGroup;

    Label38: TLabel;
    Label78: TLabel;
    cbDisableChainNotification: TCheckBox;
    cbEnableExtendedChainChecking: TCheckBox;
    cbDisableWatcher: TCheckBox;
    btnShowDebug: TButton;

    pnl8: TPanel;
    Label48: TLabel;
    cbDisableSystemTrayIconNotification: TCheckBox;
    cbDisableWhenScrollLock: TCheckBox;
    pnl9: TPanel;
    btnTest: TSpeedButton;
    cbEnableSound: TCheckBox;
    btnSoundBrowse: TButton;

    Label100: TLabel;
    Label101: TLabel;
    cbDisable: TCheckBox;
    cbRemember: TCheckBox;
    cpgDisplayOptions: TCategoryPanelGroup;

    Label3: TLabel;
    GroupBox25: TGroupBox;
    btnPreview: TSpeedButton;
    cbFullMode: TCheckBox;
    cpgMenu: TCategoryPanelGroup;

    Label56: TLabel;
    sbEditPermanentClips: TSpeedButton;
    GroupBox27: TGroupBox;
    Label27: TLabel;
    cbShowAllItems: TRadioButton;
    cbShowAllAsSubmenus: TRadioButton;
    GroupBox28: TGroupBox;
    Label57: TLabel;
    cbPermanentItemsSubmenu: TRadioButton;
    cbShowPermanentItemGroups: TRadioButton;

    GroupBox13: TGroupBox;
    SpeedButton1: TSpeedButton;
    Label4: TLabel;
    Label7: TLabel;
    udMinHeight: TJJSlide;
    UDWidth: TJJSlide;
    pnl2: TPanel;
    lblFontName: TLabel;
    GroupBox14: TGroupBox;
    cbDoubleHeight: TCheckBox;
    cbNoThumbnails: TCheckBox;

    Label25: TLabel;
    Label30: TLabel;
    lvOrder: TListView;
    pnl3: TPanel;
    btnMenuUp: TSpeedButton;
    btnMenuDown: TSpeedButton;
    btnToggle: TButton;
    cpgMisc: TCategoryPanelGroup;

    GroupBox30: TGroupBox;
    Label50: TLabel;
    Label51: TLabel;
    Label52: TLabel;
    Label39: TLabel;
    Label22: TLabel;
    Label28: TLabel;
    cpgNonText: TCategoryPanelGroup;

    Label35: TLabel;
    cbAlwaysPicture: TCheckBox;
    GroupBox18: TGroupBox;
    Label9: TLabel;
    cbMonitorFilenames: TCheckBox;
    cbOtherItems: TCheckBox;
    cbDontCopy: TCheckBox;
    txtOtherSizeLimitKB: TEdit;
    cpgPopup: TCategoryPanelGroup;

    Label85: TLabel;
    cbEditClipWindow: TCheckBox;
    pnl13: TPanel;
    Label8: TLabel;
    lblHotkey: TLabel;
    Label72: TLabel;
    cpgText: TCategoryPanelGroup;

    GroupBox17: TGroupBox;
    Label16: TLabel;
    cbRemoveFormat: TCheckBox;
    cbAutofixURLs: TCheckBox;
    GroupBox16: TGroupBox;
    Label12: TLabel;
    cbCaseSensitive: TCheckBox;
    cbIgnoreSmallText: TCheckBox;
    cbDontCopyLargeText: TCheckBox;
    txtTextSizeLimitKB: TEdit;

    Label24: TLabel;
    Label91: TLabel;
    pnl5: TPanel;
    btnFormatUp: TSpeedButton;
    btnFormatDown: TSpeedButton;
    lvFormats: TListView;
    cpgTooltip: TCategoryPanelGroup;

    cpClipboardBarDisplay: TCategoryPanel;
    cpClipboardBarMouse: TCategoryPanel;
    cpClipboardBarMain: TCategoryPanel;
    Main: TCategoryPanel;
    cpdefault: TCategoryPanel;
    CategoryPanel1: TCategoryPanel;
    CategoryPanel2: TCategoryPanel;
    CategoryPanel3: TCategoryPanel;
    CategoryPanel4: TCategoryPanel;
    CategoryPanel5: TCategoryPanel;
    CategoryPanel6: TCategoryPanel;
    CategoryPanel7: TCategoryPanel;
    CategoryPanel8: TCategoryPanel;
    CategoryPanel9: TCategoryPanel;
    CategoryPanel10: TCategoryPanel;
    CategoryPanel11: TCategoryPanel;
    CategoryPanel12: TCategoryPanel;
    CategoryPanel13: TCategoryPanel;
    CategoryPanel14: TCategoryPanel;
    CategoryPanel15: TCategoryPanel;
    CategoryPanel16: TCategoryPanel;
    CategoryPanel17: TCategoryPanel;
    CategoryPanel18: TCategoryPanel;
    CategoryPanel19: TCategoryPanel;
    CategoryPanel20: TCategoryPanel;
    CategoryPanel21: TCategoryPanel;
    CategoryPanel22: TCategoryPanel;
    CategoryPanel24: TCategoryPanel;
    CategoryPanel25: TCategoryPanel;
    CategoryPanel26: TCategoryPanel;
    CategoryPanel27: TCategoryPanel;
    CategoryPanel28: TCategoryPanel;
    CategoryPanel29: TCategoryPanel;
    CategoryPanel30: TCategoryPanel;
    CategoryPanel31: TCategoryPanel;
    CategoryPanel32: TCategoryPanel;
    CategoryPanel33: TCategoryPanel;

    GroupBox4: TGroupBox;
    Label6: TLabel;
    Label32: TLabel;
    UDToolWidth: TJJSlide;
    UDToolHeight: TJJSlide;
    GroupBox6: TGroupBox;
    Label89: TLabel;
    cbSystemTrayTooltip: TCheckBox;
    cbTooltipRichText: TCheckBox;
    cbShowHeaderFooter: TCheckBox;

    Label63: TLabel;
    GroupBox3: TGroupBox;
    Label75: TLabel;
    Label77: TLabel;
    tbTooltipDelay: TTrackBar;
    tvBasic: TTreeView;
    cbMoveFirst: TCheckBox;
    Label107: TLabel;
    CategoryPanel23: TCategoryPanel;
    cbxIconType: TComboBox;
    Label108: TLabel;
    Label109: TLabel;
    cbxRepeatIcons: TComboBox;
    Label110: TLabel;
    cbxIconClickAction: TComboBox;
    cbHotkeyTooltip: TCheckBox;
    tsClipMenu: TTabSheet;
    cpgClipMenu: TCategoryPanelGroup;
    CategoryPanel34: TCategoryPanel;
    Label111: TLabel;
    GroupBox34: TGroupBox;
    cbClipMenuPin: TCheckBox;
    cbClipMenuEdit: TCheckBox;
    cbClipMenuDelete: TCheckBox;
    cbClipMenuDestroy: TCheckBox;
    cbClipMenuPasteUsing: TCheckBox;
    cbClipMenuPasteAs: TCheckBox;
    cbClipMenuPermanent: TCheckBox;
    CategoryPanel35: TCategoryPanel;
    GroupBox33: TGroupBox;
    btnCustomMenu1: TButton;
    Label112: TLabel;
    Label113: TLabel;
    Label114: TLabel;
    Label115: TLabel;
    Label118: TLabel;
    clbCustomMenus: TCheckListBox;
    btnNewCustomMenu: TButton;
    pnlProgramOptions: TPanel;
    Label64: TLabel;
    rbProgramPaste: TRadioButton;
    cbxPasteMethod: TComboBox;
    btnProgramCustomScript: TButton;
    rbProgramMacro: TRadioButton;
    cbDisableMonitoring: TCheckBox;
    cbDisableTrigger: TCheckBox;
    cbExplorerCompat: TCheckBox;
    SpeedButton2: TSpeedButton;
    btnNewMacroPopup: TSpeedButton;
    pmMacros: TPopupActionBar;
    AppendClipboard1: TMenuItem;
    miGoogle1: TMenuItem;
    miPasteandEnter1: TMenuItem;
    miPasteandTAB1: TMenuItem;
    miPasteStayOpen1: TMenuItem;
    btnPin: TButton;
    Label121: TLabel;
    CategoryPanel36: TCategoryPanel;
    btnClearPlaintext: TButton;
    pnl14: TPanel;
    cbGlobalClipboard: TCheckBox;
    Label40: TLabel;
    tbTriggerThickness: TTrackBar;
    Label124: TLabel;
    cbClipMenuConfigure: TCheckBox;
    tsArsClipIni: TTabSheet;
    cpgArsClipIni: TCategoryPanelGroup;
    CategoryPanel37: TCategoryPanel;
    tsConfigurationHelp: TTabSheet;
    cpgConfigHelp: TCategoryPanelGroup;
    CategoryPanel38: TCategoryPanel;
    GroupBox35: TGroupBox;
    Label125: TLabel;
    Label127: TLabel;
    Label128: TLabel;
    Label129: TLabel;
    Label130: TLabel;
    Label131: TLabel;
    Label132: TLabel;
    GroupBox36: TGroupBox;
    Label133: TLabel;
    Label134: TLabel;
    Label135: TLabel;
    CategoryPanel39: TCategoryPanel;
    CategoryPanel40: TCategoryPanel;
    Label126: TLabel;
    txtCommands: TRichEdit;
    txtOther: TRichEdit;
    pnlTitleColor: TPanel;
    cbTitleColor: TCheckBox;
    Label49: TLabel;
    Label119: TLabel;
    CategoryPanel41: TCategoryPanel;
    GroupBox31: TGroupBox;
    Label62: TLabel;
    Label68: TLabel;
    Label71: TLabel;
    Label74: TLabel;
    Label76: TLabel;
    Label81: TLabel;
    Label86: TLabel;
    Label93: TLabel;
    Label144: TLabel;
    Label145: TLabel;
    Label146: TLabel;
    Label147: TLabel;
    Label148: TLabel;
    Label149: TLabel;
    Label150: TLabel;
    Label151: TLabel;
    Label104: TLabel;
    Label105: TLabel;
    Label116: TLabel;
    Label117: TLabel;
    GroupBox10: TGroupBox;
    cbPinnedShortcuts: TCheckBox;
    cbPopupCharLimit: TCheckBox;
    cbUseKeyboard: TCheckBox;
    udPopupKeysLimit: TMySlide;
    GroupBox9: TGroupBox;
    Label10: TLabel;
    Label11: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label46: TLabel;
    cbxMiddleClickAction: TComboBox;
    cbxCtrlClickAction: TComboBox;
    cbxShiftClickAction: TComboBox;
    cbxAltClickAction: TComboBox;
    cbxTabKey: TComboBox;
    GroupBox11: TGroupBox;
    Label47: TLabel;
    cbxMouseWheelAction: TComboBox;
    cbMoveDuplicate: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure cbUseKeyboardClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure txtPopupClipQueueSizeKeyPress(Sender: TObject; var Key: Char);
    procedure udQueueSizeXClick(Sender: TObject; Button: TUDBtnType);
    procedure cbDisableClick(Sender: TObject);
    procedure btnEditPermanentItemsClick(Sender: TObject);
    procedure rbTypingClick(Sender: TObject);
    procedure rbPasteClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
    procedure cbMonitorFilenamesClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure rbClipboardOnlyClick(Sender: TObject);
    procedure cbMoveFirstClick(Sender: TObject);
    procedure cbRememberClick(Sender: TObject);
    procedure cbCopyIconsxClick(Sender: TObject);
    procedure cbMoveDuplicateClick(Sender: TObject);
    procedure txtOldHistorySizeKeyPress(Sender: TObject; var Key: Char);
    procedure udRemovedSizeXClick(Sender: TObject; Button: TUDBtnType);
    procedure txtOtherSizeKeyPress(Sender: TObject; var Key: Char);
    procedure txtOtherSizeLimitKBChange(Sender: TObject);
    procedure tvOptionsClick(Sender: TObject);
    procedure tvOptionsCollapsing(Sender: TObject; Node: TTreeNode;
      var AllowCollapse: Boolean);
    procedure bEditPopupHotkeyClick(Sender: TObject);
    procedure cbDisableWhenScrollLockClick(Sender: TObject);
    procedure cbShowEditHistoryClick(Sender: TObject);
    procedure rbPasteSIClick(Sender: TObject);
    procedure tvOptionsChange(Sender: TObject; Node: TTreeNode);
//    procedure bEditToolTipHotkeyxClick(Sender: TObject);
//    procedure bEditPreviousToolTipHotkeyxClick(Sender: TObject);
    procedure cbPopupDoubleclickClick(Sender: TObject);
    procedure cbPopupDoubleclickTrayClick(Sender: TObject);
    procedure bntSetFontClick(Sender: TObject);
    procedure XcbShowAllItemsClick(Sender: TObject);
    procedure XcbShowAllAsSubmenusClick(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnEditPlaintextHotkeyClick(Sender: TObject);
    procedure btnFormatUpClick(Sender: TObject);
    procedure btnFormatDownClick(Sender: TObject);
    procedure cbDisableWatcherClick(Sender: TObject);
    procedure btnMenuUpClick(Sender: TObject);
    procedure btnMenuDownClick(Sender: TObject);
    procedure btnToggleClick(Sender: TObject);
    procedure lvOrderInfoTip(Sender: TObject; Item: TListItem;
      var InfoTip: string);
    procedure Panel8Click(Sender: TObject);
    procedure cbEnableSoundClick(Sender: TObject);
    procedure cbRightTriggerEnableClick(Sender: TObject);
    procedure cbTriggerWindowClick(Sender: TObject);
    procedure sbTopClick(Sender: TObject);
    procedure sbBottomClick(Sender: TObject);
    procedure sbLeftClick(Sender: TObject);
    procedure sbbottomleftClick(Sender: TObject);
    procedure sbtopleftClick(Sender: TObject);
    procedure sbtoprightClick(Sender: TObject);
    procedure sbbottomrightClick(Sender: TObject);
    procedure sbRightClick(Sender: TObject);
    procedure sbEditPermanentClipsClick(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure lblShowOptionsClick(Sender: TObject);
    procedure lbMenuOrderClick(Sender: TObject);
    procedure tsProgramOptionsShow(Sender: TObject);
    procedure cbxPasteMethodChange(Sender: TObject);
    procedure cbDisableTriggerMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure cbDisableMonitoringMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure lvProgramsClick(Sender: TObject);
    procedure cbUseVirtualDesktopMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure tsClipboardBarShow(Sender: TObject);
    procedure cbEnableClipboardBarMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btnRemovedClipsClick(Sender: TObject);
    procedure pcPanelsChange(Sender: TObject);
    procedure lblTriggerWindowClick(Sender: TObject);
    procedure btnEditPopupClipsClick(Sender: TObject);
    procedure btnTestClick(Sender: TObject);
    procedure btnSoundBrowseClick(Sender: TObject);
    procedure cbDontCopyClick(Sender: TObject);
    procedure lblHotkeyClick(Sender: TObject);
    procedure tvOptionsExpanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    procedure tvOptionsCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
      State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure btnPreviewClick(Sender: TObject);
    procedure timUpdatePreviewTimer(Sender: TObject);
    procedure lvOrderChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure FormHide(Sender: TObject);
    procedure lvOrderClick(Sender: TObject);
    procedure cbFullModeClick(Sender: TObject);
    procedure btnAddNameClick(Sender: TObject);

    procedure UpdatePreview(Sender : TObject=nil);
    procedure pnlColorClick(Sender: TObject);
    procedure btnColorExamplesClick(Sender: TObject);
    procedure DefaultScheme1Click(Sender: TObject);
    procedure SuperDark1Click(Sender: TObject);
    procedure JoeJoeSpecial1Click(Sender: TObject);
    procedure Greyscale1Click(Sender: TObject);
    procedure MetroGreen1Click(Sender: TObject);
    procedure MetroSteelBlue1Click(Sender: TObject);
    procedure Woodgrain1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure lblJumpListClick(Sender: TObject);
    procedure lblHotkeyAlternativesClick(Sender: TObject);
    procedure lblClipboardBarClick(Sender: TObject);
    procedure btnPermClipsClick(Sender: TObject);
    procedure pmPermClipsPopup(Sender: TObject);
    procedure lvFormatsClick(Sender: TObject);
    procedure tvOptionsChanging(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
    procedure lblClipSetClick(Sender: TObject);
    procedure btnShowDebugClick(Sender: TObject);
    procedure cbExplorerCompatClick(Sender: TObject);
    procedure cbExplorerCompatMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btnSystemClipsClick(Sender: TObject);
    procedure btnBarTopLeftClick(Sender: TObject);
    procedure btnBarLeftClick(Sender: TObject);
    procedure btnBarBottomLeftClick(Sender: TObject);
    procedure btnBarBottomClick(Sender: TObject);
    procedure btnBarBottomRightClick(Sender: TObject);
    procedure btnBarRightClick(Sender: TObject);
    procedure btnBarTopRightClick(Sender: TObject);
    procedure btnBarTopClick(Sender: TObject);
    procedure cbBarSnapToScreenClick(Sender: TObject);
    procedure cbClipboardBarVirtualDesktopClick(Sender: TObject);
    procedure cbxModeChange(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure cbxIconTypeClick(Sender: TObject);
    procedure btnCustomMenu1Click(Sender: TObject);
    procedure clbCustomMenusClick(Sender: TObject);
    procedure btnNewCustomMenuClick(Sender: TObject);
    procedure clbCustomMenusExit(Sender: TObject);
    procedure clbCustomMenusDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure clbCustomMenusDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure clbCustomMenusMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btnCustomPasteEditClick(Sender: TObject);
    procedure btnProgramCustomScriptClick(Sender: TObject);
    procedure rbProgramMacroClick(Sender: TObject);
    procedure btnNewMacroPopupClick(Sender: TObject);
    procedure miAppendClipboard1Click(Sender: TObject);
    procedure miGoogle1Click(Sender: TObject);
    procedure miPasteandEnter1Click(Sender: TObject);
    procedure miPasteandTAB1Click(Sender: TObject);
    procedure miPastewithTime1Click(Sender: TObject);
    procedure miPasteStayOpen1Click(Sender: TObject);
    procedure btnPinClick(Sender: TObject);
    procedure btnClearPlaintextClick(Sender: TObject);
    {$ENDREGION}
  private
    { Private declarations }
    HotKeyPopup : TACHotKey;
    TTHotKeyPopup : TACHotKey;
    PTTHotKeyPopup : TACHotKey;
    PlainTextHotKey : TACHotKey;
    PlainTextData : THotkeyData;
    //LastShownPanel : TPanel;

    Hotkey_Ctrl : boolean;
    Hotkey_Alt : boolean;
    Hotkey_Winkey : boolean;
    Hotkey_Shift : boolean;
    Hotkey_Key :  word;

    TTHotkey_Ctrl : boolean;
    TTHotkey_Alt : boolean;
    TTHotkey_Winkey : boolean;
    TTHotkey_Shift : boolean;
    TTHotkey_Key :  word;

    PTTHotkey_Ctrl : boolean;
    PTTHotkey_Alt : boolean;
    PTTHotkey_Winkey : boolean;
    PTTHotkey_Shift : boolean;
    PTTHotkey_Key :  word;

    PreCaptureDelayMS : integer;
    RightClickDelay : integer;
    OldTrayPopup : boolean;
    CopySelected : boolean;

    RightclickTriggerWarned : boolean;
    PasteDelay : integer;
    ClipboardBarVisible : boolean;
    Sound_NewClip : string;

    DefaultMenuOrder : array[TMenuOrderType] of integer;
    ignorecollapse : boolean;
    dontcollapse : boolean;
    ignoreexpand : boolean;
    ignorepanelclick : boolean;
    nocollapse : boolean;
    CurrentCPG : TCategoryPanelGroup;
    tempFont : TFont;
    symbolkeys : string;
    alphanumerickeys : string;
    MimicDelayMS : integer;
    MimicDelayMSEnabled : boolean;

    fTXTProgram : string;
    fBMPProgram : string;

    isLoading : boolean;
    defaultNodes : TTreeNodes;
    basicNodes : TTreeNodes;

    CustomMenuData : TStringList;
    CustomMenuPoint : TPoint;

    SelectProgramOnce : string;

    FirstRun : boolean;
    minClipLength : integer;
    showClipCues : boolean;

    // hidden variables
    iconRetryCount : integer;
    extractIconForPopup : boolean;
    sharedUpdateTimeMS : integer;
    searchRemovedOn : boolean;
    alwaysClearFilter : boolean;
    returnPopupFocusWhenPinned : boolean;

    procedure HotkeySave;
    procedure HotkeyLoad;
    function GetINIFileName: string;
    {function HotKeyAssign(
            Ctrl: boolean; Alt: boolean; Shift: boolean; WinKey: boolean;
            Keystroke: word; FunctionKey : boolean): boolean;
    //function HotKeyRelease(): boolean;
    }
    function GetHumanReadableTTHotkey : string;
    function GetHumanReadablePTTHotkey : string;
    function GetHumanReadablePlaintextHotkey : string;

    procedure UpdateColorExample;

    procedure PermClipClick(Sender : TObject);
    {function SetHotKey : boolean;}

    procedure UpdateFontLabel(f : TFOnt);
    procedure ResetClipboardBarButtons;

    procedure AutoCollapse(cpg : TCategoryPanelGroup);
    procedure PanelCollapseHandler(Sender: TObject);
    procedure PanelMouseWheelHandler(Sender: TObject; Shift: TShiftState;
        WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);

    procedure NewMacro(Caption, Clip : string);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    function GetHumanReadableHotkey: string;

    function GetRightclickTriggerWarned : boolean;
    function GetPasteDelay : integer;
    procedure SetRightclickTriggerWarned;
    function GetPreCaptureDelayMS : integer;
    function GetRightClickDelay : integer;
    function GetHotKeyID: integer;
//    function GetTTHotKeyID: integer;
//    function GetPTTHotKeyID: integer;
    function GetPlaintextHokeyID : integer;
    function GetOldTrayPopup : boolean;
    procedure ForceOldTrayPopup; 
    procedure SaveLastPermPath;

    function FormatCount : integer;
    function MenuOrderText(m : TMenuOrderType; description:boolean) : string;
    function GetFormat(index : integer) : FormatOrder;

    function CopySelectedForPopup : boolean;

    function ClipboardBarSetVisible : boolean;

    procedure SaveClipboardBarState(visibleOnly : boolean=false);
    procedure SaveClipboardBarPosition;
    procedure LoadClipboardBarState;

    function GetShiftClickAction : TClickAction;
    function GetCtrlClickAction : TClickAction;
    function GetMiddleClickAction : TClickAction;
    function GetAltClickAction : TClickAction;
    function GetTabClickAction : TClickAction;

    function GetMouseWheelAction : TWheelAction;
    function GetNewClipWav : string;

    function GetFont : TFont;

    procedure MoveItem(x, before : TMenuOrderType);
    function GetAccelSymbols : string;
    function GetAccelAlphaNumeric : string;
    function GetMimicDelayMS : integer;

    function GetTXTProgram : string;
    function GetBMPProgram : string;

    procedure ReportTXTProgram(s : string);
    procedure ReportBMPProgram(s : string);

    function GetIconType : TCBXIconType;
    function GetRepeatIcons : TCBXRepeatIcons;
    function GetIconClickAction : TCBXIconClickAction;

    function GetCustomCount : integer;
    function GetCustomCaption(index:integer) : string;
    function GetCustomData(index:integer) : string;
    function GetCustomChecked(index:integer) : boolean;

    function GetPasteMacro : string;

    procedure SetSelectedProgram(name : string);

    procedure showPage(ts : TTabSheet);

    function getMinClipLength : integer;
    function getShowClipCues : boolean;
    function getIconRetryCount : Integer;
    function getExtractIconForPopup : boolean;
    function getSharedUpdateTimeMS : integer;
    function getSearchRemovedOn : boolean;
    function getalwaysClearFilter : boolean;
    function getReturnPopupFocusWhenPinned : boolean;
    { Public declarations }
  end;

var
  FrmConfig: TFrmConfig;

implementation


uses
    INIFiles,Math,

    UnitFrmMainPopup, UnitClipQueue, UnitOtherQueue,
  UnitFrmSysTrayMenu,  UnitPaste,
  UnitMisc, UnitFrmClipboardManager,
  UnitFrmChainWatcher
  , UnitPopupGenerate, UnitSound, UnitFrmDummyClipboardBar, {UnitFrmScratchpad,} Registry,
   UnitFramePopup, StrUtils, GraphUtil, UnitFrmPreviewPopup, CommCtrl,
  UnitFrmPermanentEdit, UnitFrmDebug, UnitDummyShellForm, UnitClipDatabase,
  UnitFrmEditHistory, UnitToken;




{$R *.dfm}

CONST LVORDER_ID = '2';
const PASTE_MACRO = 'ARSCLIP_PASTEMACRO';

function TFrmConfig.getReturnPopupFocusWhenPinned;
begin
    result := returnPopupFocusWhenPinned;
end;
function TFrmConfig.getSharedUpdateTimeMS : integer;
begin
    result := sharedUpdateTimeMS;
end;
function TFrmConfig.getExtractIconForPopup : boolean;
begin
    result := extractIconForPopup;
end;
function TFrmConfig.getIconRetryCount : Integer;
begin
    result := self.iconRetryCount;
end;
function TFrmConfig.getShowClipCues : boolean;
begin
    result := self.showClipCues;
end;
function TFrmConfig.getMinClipLength : integer;
begin
    result := self.minClipLength;
end;
function TFrmConfig.getSearchRemovedOn : boolean;
begin
    result := searchRemovedON;
end;
function TFrmConfig.getalwaysClearFilter : boolean;
begin
    result := alwaysClearFilter;
end;
procedure TFrmConfig.showPage(ts : TTabSheet);
begin
    pcPanels.ActivePageIndex := ts.PageIndex;
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;


function TFrmConfig.GetCustomCount : integer;
begin
    result := clbCustomMenus.Count;
end;
function TFrmConfig.GetCustomCaption(index:integer) : string;
begin
    result := clbCustomMenus.Items[index];
end;
function TFrmConfig.GetCustomData(index:integer) : string;
begin
    result := CustomMenuData[index];
end;
function TFrmConfig.GetCustomChecked(index:integer) : boolean;
begin
    result := clbCustomMenus.checked[index];
end;

function TFrmConfig.GetPasteMacro : string;
begin
    result := frmSysTrayMenu.GetProgramMacro(PASTE_MACRO);
end;
procedure MoveListViewItem(lv: TListView; old, new : integer);
var lisource, lidest: TListItem;
begin
    if old < new then begin
        MoveListViewItem(lv, new, old);
        EXIT;
    end;
    lv.Items.BeginUpdate;
    try
        lisource := lv.Items[old];
        lidest := lv.Items.Insert(new);
        lidest.Assign(lisource);
        lisource.Free;
    finally
        lv.Items.EndUpdate;
    end;
end;
procedure MoveListViewItem2(lv: TListView; old, new : integer);
var lisource, lidest: TListItem;
begin
    lv.Items.BeginUpdate;
    try
        lisource := lv.Items[old];
        lidest := lv.Items.Insert(new);
        lidest.Assign(lisource);
        lisource.Free;
    finally
        lv.Items.EndUpdate;
    end;
end;

procedure TFrmConfig.SetSelectedProgram(name : string);
begin
    self.SelectProgramOnce := name;
end;

{Configuration Mode Routines}

procedure TFrmConfig.AutoCollapse(cpg : TCategoryPanelGroup);
var i : integer;
begin

    for i := 0 to cpg.ControlCount-1 do begin
        TCategoryPanel(cpg.Controls[i]).OnExpand := self.PanelCollapseHandler;
        if TCategoryPanel(cpg.Controls[i]).TabOrder <> 0 then begin
            TCategoryPanel(cpg.Controls[i]).Collapsed := true;
            TCategoryPanel(cpg.Controls[i]).TabStop := true;
        end;
    end;
    cpg.VertScrollBar.Position := 0;
    cpg.VertScrollBar.Visible := false;
    cpg.HeaderStyle := hsGradient;
    cpg.GradientDirection := gdHorizontal;
    cpg.GradientBaseColor := blend(clBtnFace, clInactiveCaption, 70);
    cpg.GradientColor :=  blend(clBtnFace, clInactiveCaption, 40);
    cpg.OnMouseWheel := self.PanelMouseWheelHandler;
//    cpg.OnCanResize := self.cpgCanResize;

end;
procedure TFrmConfig.PanelCollapseHandler(Sender: TObject);
var i : integer;
    cpg : TCategoryPanelGroup;
begin
    if ignorepanelclick then EXIT;

    cpg := TCategoryPanelGroup(TCategoryPanel(Sender).Parent);

    for i := 0 to cpg.ControlCount-1 do begin
        if cpg.Controls[i] <> sender then TCategoryPanel(cpg.Controls[i]).collapsed := true;
    end;
end;
procedure TFrmConfig.PanelMouseWheelHandler(Sender: TObject; Shift: TShiftState;
        WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
    if (self.ActiveControl is TComboBox) and (TComboBox(self.ActiveControl).DroppedDown) or
        (self.ActiveControl = txtCommands) or
        (self.ActiveControl = txtOther) then begin
        Handled := false;
        EXIT;
    end;
    Handled := true;


    with TCategoryPanelGroup(sender).VertScrollBar do begin
        Position := Position - trunc(WheelDelta/120) *
        (TCategoryPanelGroup(sender).VertScrollBar.Range div 10);
    end;


end;
procedure TFrmConfig.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
    cpg : TCategoryPanelGroup;
    c : TCOntrol;
begin
    CurrentCPG.OnMouseWheel(CurrentCPG,shift,WheelDelta,mousepos,handled);
end;


procedure TFrmConfig.cbxModeChange(Sender: TObject);
var selected : TTreeNode;
    procedure SetVisible(cpg : TCategoryPanelGroup; visible : boolean);
    var
        i : integer;
        cp : TCategoryPanel;
    begin
        for i := 0 to cpg.Panels.Count-1 do begin
            cp := cpg.Panels[i];
            if cp.TabOrder <> 0 then begin
                cp.Visible := visible;
            end;
        end;
    end;
    procedure SetExpandAll(cpg : TCategoryPanelGroup; expanded : boolean);
    var
        i : integer;
        cp : TCategoryPanel;
        ht, defaultheight : integer;
    begin
        ht := 0;
        defaultheight := 0;
        cpg.VertScrollBar.Visible := expanded;
        for i := 0 to cpg.Panels.Count-1 do begin
            cp := cpg.Panels[i];

            if expanded then begin
                cp.Collapsed := false;
                inc(ht,cp.Height);
            end else begin
                cp.Collapsed := cp.TabOrder <> 0;
                inc(defaultheight, cp.Height);
            end;
        end;
        cpg.VertScrollBar.Visible := expanded;
        cpg.VertScrollBar.Position := 0;
        if expanded then begin
            cpg.VertScrollBar.Range := ht;
        end else begin
            if defaultheight > cpg.ClientHeight then begin
                cpg.VertScrollBar.Visible := expanded;
                cpg.VertScrollBar.Position := 0;
                cpg.VertScrollBar.Range := ht;
            end;
        end;

    end;
    procedure SetAllVisible;
    begin
        SetVisible(self.cpgClipboardBar,true);
        SetVisible(self.cpgTiggerWindow,true);
        SetVisible(self.cpgClipSets,true);
        SetVisible(self.cpgText,true);
        SetVisible(self.cpgKeystrokes,true);
        SetVisible(self.cpgTooltip,true);
        SetVisible(self.cpgMenu,true);
        SetVisible(self.cpgBehavior,true);
        SetVisible(self.cpgHotkeyAlt,true);
        SetVisible(self.cpgProgramOptions,true);
        SetVisible(self.cpgClipboard,true);
        SetVisible(self.cpgHistory,true);
        SetVisible(self.cpgHotkeys,true);
        SetVisible(self.cpgNonText,true);
        SetVisible(self.cpgPopup,true);
        SetVisible(self.cpgJumplist,true);
        SetVisible(self.cpgMisc,true);
        SetVisible(self.cpgColor,true);
        SetVisible(self.cpgDisplayOptions,true);
        SetVisible(self.cpgClipMenu, true);
        SetVisible(self.cpgArsClipIni, true);
        SetVisible(self.cpgConfigHelp, true);
    end;
    procedure DefaultExpanded;
    var tn : TTreeNode;
    begin
        SetExpandAll(self.cpgClipboardBar,false);
        SetExpandAll(self.cpgTiggerWindow,false);
        SetExpandAll(self.cpgClipSets,false);
        SetExpandAll(self.cpgText,false);
        SetExpandAll(self.cpgKeystrokes,false);
        SetExpandAll(self.cpgTooltip,false);
        SetExpandAll(self.cpgMenu,false);
        SetExpandAll(self.cpgBehavior,false);
        SetExpandAll(self.cpgHotkeyAlt,false);
        SetExpandAll(self.cpgProgramOptions,false);
        SetExpandAll(self.cpgClipboard,false);
        SetExpandAll(self.cpgHistory,false);
        SetExpandAll(self.cpgHotkeys,false);
        SetExpandAll(self.cpgNonText,false);
        SetExpandAll(self.cpgPopup,false);
        SetExpandAll(self.cpgJumplist,false);
        SetExpandAll(self.cpgMisc,false);
        SetExpandAll(self.cpgColor,false);
        SetExpandAll(self.cpgDisplayOptions,false);
        SetExpandAll(self.cpgClipMenu,false);
        SetExpandAll(self.cpgArsClipIni, false);
        SetExpandAll(self.cpgConfigHelp, false);

        if selected=nil then EXIT;
        tvOptions.Selected := selected;
        selected.Expanded := true;
    end;
    procedure ExpandAll;
    begin
        SetExpandAll(self.cpgHotkeyAlt,true);
        SetExpandAll(self.cpgClipboardBar,true);
        SetExpandAll(self.cpgTiggerWindow,true);
        SetExpandAll(self.cpgClipSets,true);
        SetExpandAll(self.cpgText,true);
        SetExpandAll(self.cpgKeystrokes,true);
        SetExpandAll(self.cpgTooltip,true);
        SetExpandAll(self.cpgMenu,true);
        SetExpandAll(self.cpgBehavior,true);
        SetExpandAll(self.cpgProgramOptions,true);
        SetExpandAll(self.cpgClipboard,true);
        SetExpandAll(self.cpgHistory,true);
        SetExpandAll(self.cpgHotkeys,true);
        SetExpandAll(self.cpgNonText,true);
        SetExpandAll(self.cpgPopup,true);
        SetExpandAll(self.cpgJumplist,true);
        SetExpandAll(self.cpgMisc,true);
        SetExpandAll(self.cpgColor,true);
        SetExpandAll(self.cpgDisplayOptions,true);
        SetExpandAll(self.cpgClipMenu,true);
        SetExpandAll(self.cpgArsClipIni, true);
        SetExpandAll(self.cpgConfigHelp, true);
    end;
    procedure HideAdvanced;
    begin
        SetVisible(self.cpgClipboardBar,false);
        SetVisible(self.cpgTiggerWindow,false);
        SetVisible(self.cpgClipSets,false);
        SetVisible(self.cpgText,false);
        SetVisible(self.cpgKeystrokes,false);
        SetVisible(self.cpgTooltip,false);
        SetVisible(self.cpgMenu,false);
        SetVisible(self.cpgBehavior,false);
        SetVisible(self.cpgHotkeyAlt,false);
        SetVisible(self.cpgProgramOptions,false);
        SetVisible(self.cpgClipboard,false);
        SetVisible(self.cpgHistory,false);
        SetVisible(self.cpgHotkeys,false);
        SetVisible(self.cpgNonText,false);
        SetVisible(self.cpgPopup,false);
        SetVisible(self.cpgJumplist,false);
        SetVisible(self.cpgMisc,false);
        SetVisible(self.cpgColor,false);
        SetVisible(self.cpgDisplayOptions,false);
        SetVisible(self.cpgClipMenu,false);
        SetVisible(self.cpgArsClipIni, false);
        SetVisible(self.cpgConfigHelp, false);
    end;

    procedure BasicMode;
        procedure HandleTreeNodes;
        var i : integer;

            procedure FindAndDeleete(text : string);
            var n : TTreeNode;
                i : integer;
            begin
                text := lowercase(text);
                for i := 0 to basicNodes.Count-1 do begin
                    n := basicNodes.Item[i];
                    if lowercase(trim(n.Text)) = text then begin
                        basicNodes.Delete(n);
                        EXIT;
                    end;
                end;
            end;
            procedure TraverseIt(parent, node : TTreeNode);
            var n2 : TTreeNode;
            begin
                while node <> nil do begin
                    n2 := basicNodes.AddChild(parent, '');
                    n2.Assign(node);

                    TraverseIt(n2, node.getFirstChild);
                    node := node.getNextSibling;
                end;
            end;
        var n, n2, parent : TTreeNode;
        begin
            EXIT; // not working
            if basicNodes = nil then begin
                basicNodes := tvBasic.Items;

                basicnodes.BeginUpdate;
                TraverseIt(nil, tvOptions.Items.GetFirstNode);
                basicNodes.EndUpdate;

                for i := 0 to basicNodes.Count-1 do begin
                    basicnodes.Item[i].Data := pointer(basicnodes.Item[i].AbsoluteIndex);
                end;

                FindAndDeleete('Alternatives');
                FindAndDeleete('Text Clips');
                FindAndDeleete('Media Clips (Non-Text)');
                FindAndDeleete('Per-Program Options');
                FindAndDeleete('Tooltip Hint');
                FindAndDeleete('Clip Sets');
                FindANdDeleete('Jump List');

                Selected := tvOptions.Items.Item[0];
            end;

            // this destroys the original nodelist - unwanted
            if tvOptions.items.Count <> basicNodes.Count then
                tvOptions.Items := basicNodes;

        end;
    begin
        self.ignorecollapse := true;
        self.ignoreexpand := true;

        HandleTreeNodes;
        tvOptions.FullCollapse;
        HideAdvanced;
        DefaultExpanded;
        self.ignoreexpand := false;
        self.ignorecollapse := false;
    end;
    procedure StandardMode;
    begin
        self.ignoreexpand := true;
        self.ignorecollapse := true;

        if tvOptions.items.Count <> defaultNodes.Count then
            tvOptions.Items := defaultNodes;

        tvOptions.FullCollapse;
        SetAllVisible;
        DefaultExpanded;
        self.ignoreexpand := false;
        self.ignorecollapse := false;
    end;
    procedure ExpandAllMode;
    begin
        self.ignoreexpand := true;
        self.ignorecollapse := true;
        ignorepanelclick := true;

        if tvOptions.items.Count <> defaultNodes.Count then
            tvOptions.Items := defaultNodes;

        tvOptions.FullExpand;


        SetAllVisible;
        ExpandAll;
        nocollapse := true;
        //self.ignorecollapse := false;
        //self.ignoreexpand := false;
    end;
begin
    self.ignorepanelclick := false;
    nocollapse := false;
    selected := tvOptions.Selected;
    case cbxMode.ItemIndex of
    0: BasicMode;
    1: StandardMode;
    2: ExpandAllMode;
    end;
end;



procedure TFrmConfig.CreateParams(var Params: TCreateParams);
begin
    inherited CreateParams(Params);
    // allow context taskbar context menu and
    // show me on the taskbar - independant of main form
    with Params do begin
        ExStyle := ExStyle or WS_EX_APPWINDOW;
        WndParent := GetDesktopwindow;
    end;
end;
procedure TFrmConfig.FormCreate(Sender: TObject);
var tn : TTreeNode;
    i : integer;
    li : TListItem;


    procedure FormatTheHelpText(re : TRichEdit);
    var
        s : string;
        line : string;
    begin
        s := re.Text;
        re.Text := '';
        re.Lines.Clear;
        UnitToken.TokenString(s, '{', false);

        while s <> '' do begin
            line := UnitToken.TokenString(s,'}', false);
            with re do begin
                SelStart := length(re.Text);
                SelAttributes.Style := [fsBold];
                Lines.Add(line);
                SelAttributes.Style := [];
                line := UnitToken.TokenString(s, '{', false);
                lines.Add(line);
            end;
        end;
    end;

    function NewOrderItem(mo : TMenuOrderType; line : boolean; checked : boolean = true) : TListItem;
    begin
        result := lvOrder.items.add;
        result.Caption := MenuOrderText(mo, false);

        if line then
            result.SubItems.Add('Yes')
        else
            result.SubItems.Add('no');

        result.Data := Pointer(mo);
        result.checked := checked;
        if mo = MOT_BREAK then
            result.Checked := false;

        DefaultMenuOrder[mo] := result.Index;
    end;
begin
    FrmDebug.AppendLog('FrmConfig - Creating');

    FormatTheHelpText(txtCommands);
    FormatTheHelpText(txtOther);

    defaultNodes := tvOptions.Items;
    tvOptions.Perform(TVM_SETITEMHEIGHT, tvOptions.Canvas.TextHeight('ZH')+6, 0);

    AutoCollapse(cpgClipboardBar);
    AutoCollapse(cpgTiggerWindow);
    AutoCollapse(cpgClipSets);
    AutoCollapse(cpgText);
    AutoCollapse(cpgKeystrokes);
    AutoCollapse(cpgTooltip);
    AutoCollapse(cpgMenu);
    AutoCollapse(cpgPopup);
    AutoCollapse(cpgClipMenu);
    AutoCollapse(cpgBehavior);
    AutoCollapse(cpgHotkeyAlt);
    AutoCollapse(cpgProgramOptions);
    AutoCollapse(cpgClipboard);
    AutoCollapse(cpgHistory);
    AutoCollapse(cpgHotkeys);

    AutoCollapse(cpgJumplist);
    AutoCollapse(cpgMisc);
    AutoCollapse(cpgColor);
    AutoCollapse(cpgDisplayOptions);
    AutoCollapse(cpgNonText);
    AutoCollapse(cpgConfigHelp);
    AutoCollapse(cpgArsClipIni);

    tempFont := TFont.Create;
    pcPanels.ActivePageIndex := 0;

    lvFormats.Items.Count := -1;
    lvFormats.HandleNeeded;
    li := lvFormats.Items.Add;
    li.Caption := 'RichText';
    li.Checked := true;
    li := lvFormats.Items.Add;
    li.Caption := 'HTML';
    li.Checked := true;

    //Application.ProcessMessages;
    // BUG - this invalidates the listview count by sending the message LVSICF_NOINVALIDATEALL


    // set default Popup state
    lvOrder.Items.Clear;
    li := NewOrderItem(MOT_MENU, false);
    li := NewOrderItem(MOT_CURRENT, false);
    self.CopySelected := false;

    li := NewOrderItem(MOT_CANCEL, false);
    li := NewOrderItem(MOT_SYSTEM, false);
    li := NewOrderItem(MOT_FULL, false);
    li := NewOrderItem(MOT_SEARCH, false, false);

    li := NewOrderItem(MOT_SWITCH, false, false);
    li := NewOrderItem(MOT_BREAK, false, false);
    li := NewOrderItem(MOT_PASTEUTILS, false, false);
    li := NewOrderItem(MOT_PROGRAM, false, false);

    li := NewOrderItem(MOT_ALLPERMANENT, false, false);
    li := NewOrderItem(MOT_PERMANENT, false);

    lvOrder.items.Count := -1;
    Application.ProcessMessages;

    self.HotkeyLoad();
    if not (cbPermanentItemsSubmenu.Checked or cbShowPermanentItemGroups.checked) then begin
        cbPermanentItemsSubmenu.Checked := true;
    end;

    if frmClipboardManager <> nil then begin
        if frmClipboardManager.IsNewClipboardAPI then begin
            cbDisableWatcher.Checked := true;
            cbDisableWatcher.Enabled := false;
            cbEnableExtendedChainChecking.Checked := false;
            cbEnableExtendedChainChecking.Enabled := false;
            cbDisableChainNotification.Checked := true;
            cbDisableChainNotification.Enabled := false;
        end;
    end;


    //
    //Hook onto keystoke
    //
    TTHotKeyPopup := nil;
    PTTHotKeyPopup := nil;
    PlainTextHotKey := nil;
    try
        HotKeyPopup := TACHotKey.Create(FrmMainPopup.handle, 'ArsClip.exe.MyHotKey',
            Hotkey_Ctrl, Hotkey_Alt, Hotkey_Shift,
            Hotkey_Winkey, Hotkey_Key
        );
    except
        ShowMessage('Failed to set hotkey ' + self.lblKeyname.Caption );
    end;
    try
        if PlainTextData.key <> 0 then
            PlainTextHotkey:= TACHotKey.Create(FrmMainPopup.handle, 'ArsClip.exe.PlainText',
                PlainTextData.Ctrl, PlainTextData.Alt, PlainTextData.Shft,
                PlainTextData.Win, PlainTextData.Key
            );
    except
        ShowMessage('Failed to set plaintext hotkey ' + self.lblPlaintext.Caption );
    end;


    // expand all tree branches
    tn := tvOptions.Items.GetFirstNode;
    while tn <> nil do begin
        if tn.HasChildren then
            tn.expand(true);
        tn := tn.getNextSibling;
    end;

    for i := 0 to pcPanels.PageCount - 1 do begin
        pcPanels.Pages[i].TabVisible := false;
    end;

    // click the first node by default
    tvOptions.Selected := tvOptions.Items.GetFirstNode;
    tvOptions.HideSelection := false;

    self.ignorecollapse := true;
    tvOptions.FullCollapse;
    self.ignorecollapse := false;

	//FrmTriggerWindow := TFrmTriggerWindow.Create(application);
end;
procedure TFrmConfig.FormDestroy(Sender: TObject);
begin
    MyFree(HotKeyPopup);
    MyFree(TTHotKeyPopup);
    MyFree(PTTHotKeyPopup);
end;
procedure TFrmConfig.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    self.HotkeyLoad;
end;
procedure TFrmConfig.FormHide(Sender: TObject);
begin
    frmPreviewPopup.Hide;
end;
procedure TFrmConfig.FormShow(Sender: TObject);
    procedure ShowHotkeys;
    var i : integer;
        sl : TStringList;
        li : TListItem;
    begin
        lvHotkeys.Clear;
        sl := TStringList.Create;
        FrmPermanent.GetNamesAndHotkeys(sl);
        for i := 0 to sl.Count-1 do begin
            li := lvHotkeys.Items.Add;
            li.Caption := sl.Names[i];
            li.SubItems.Add(sl.ValueFromIndex[i]);
        end;
        sl.Free;
    end;
begin
    ShowWindow(Application.Handle, SW_HIDE);

    tsProgramOptionsShow(sender);
    tsClipboardBarShow(sender);


    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
    Self.UpdateColorExample;
    ShowHotkeys;
end;


function TFrmConfig.GetTXTProgram : string;
begin
    result := fTXTProgram;
end;

function TFrmConfig.GetBMPProgram : string;
begin
    result := fBMPProgram;
end;
procedure TFrmConfig.ReportTXTProgram(s : string);
begin
    if fTXTProgram = '' then begin
        fTXTProgram := s;
    end;
end;
procedure TFrmConfig.ReportBMPProgram(s : string);
begin
    if fBMPProgram = '' then begin
        fBMPProgram := s;
    end;

end;



function TFrmConfig.GetMimicDelayMS : integer;
begin
    if not MimicDelayMSEnabled then begin
        result := 0;
    end else begin
        result := self.MimicDelayMS;
    end;
end;

function TFrmConfig.GetHotKeyID: integer;
begin
    result := HotKeyPopup.GetID;
end;

function TFrmConfig.GetRightClickDelay: integer;
begin
    result := tbHoldDelay.Position * 100;
end;
function TFrmConfig.GetRightclickTriggerWarned: boolean;
begin
    result := self.RightclickTriggerWarned;
end;

function TFrmConfig.GetAccelAlphaNumeric: string;
begin
	result := alphanumerickeys; 
end;
function TFrmConfig.GetAccelSymbols: string;
begin
	result := symbolkeys;
end;

function TFrmConfig.GetCtrlClickAction: TClickAction;
begin
    result := TClickAction(cbxCtrlClickAction.ItemIndex);
end;
function TFrmConfig.GetShiftClickAction: TClickAction;
begin
    result := TClickAction(cbxShiftClickAction.ItemIndex);
end;
function TFrmConfig.GetMiddleClickAction : TClickAction;
begin
    result := TClickAction(cbxMiddleClickAction.ItemIndex);
end;
function TFrmConfig.GetAltClickAction : TClickAction;
begin
    result := TClickAction(cbxAltClickAction.ItemIndex);
end;
function TFrmConfig.GetTabClickAction : TClickAction;
begin
    result := TClickAction(cbxTabKey.ItemIndex);
end;

function TFrmConfig.GetMouseWheelAction : TWheelAction;
begin
    result := TWheelAction(cbxMouseWheelAction.ItemIndex);
end;

function TFrmConfig.GetPasteDelay: integer;
begin
    result := self.PasteDelay;
end;

function TFrmConfig.GetPlaintextHokeyID: integer;
begin
    result := -1;
    if PlainTextHotKey <> nil then
        result := PlainTextHotKey.GetID;
end;

function TFrmConfig.GetHumanReadableHotkey : string;
var b : boolean;
begin
    result := '';
    if assigned(frmhotkey) then

    result := FrmHotkey.GetHumanReadable(Hotkey_alt, Hotkey_shift, Hotkey_ctrl, Hotkey_winkey, Hotkey_key, b);
end;
function TFrmConfig.GetHumanReadableTTHotkey : string;
var b : boolean;
begin
    result := FrmHotkey.GetHumanReadable(TTHotkey_alt, TTHotkey_shift, TTHotkey_ctrl, TTHotkey_winkey, TTHotkey_key, b);
end;
function TFrmConfig.GetHumanReadablePTTHotkey: string;
var b : boolean;
begin
    result := FrmHotkey.GetHumanReadable(PTTHotkey_alt, PTTHotkey_shift, PTTHotkey_ctrl, PTTHotkey_winkey, PTTHotkey_key, b);
end;
function TFrmConfig.GetHumanReadablePlaintextHotkey: string;
var b : boolean;
begin
    if (PlainTextData.key = 0) then begin
        result := 'none';
        EXIT;
    end;
    result := FrmHotkey.GetHumanReadable(
        PlainTextData.alt,
        PlainTextData.shft,
        PlainTextData.ctrl,
        PlainTextData.win,
        PlainTextData.key,
        b
    );
end;

function TFrmConfig.ClipboardBarSetVisible: boolean;
begin
    result := self.ClipboardBarVisible;
end;
function TFrmConfig.CopySelectedForPopup: boolean;
begin
    result := self.CopySelected;
end;

function TFrmConfig.GetPreCaptureDelayMS: integer;
begin
    result := PreCaptureDelayMS;
end;

function TFrmConfig.GetFont: TFont;
begin
    result := tempFont;

    self.UpdateFontLabel(result);
end;

function TFrmConfig.GetINIFileName: string;
begin
    Result := UnitMisc.GetAppPath + 'arsclip.ini';
end;
function TFrmConfig.GetNewClipWav: string;
begin
    result := self.sound_newclip;
end;
function TFrmConfig.GetOldTrayPopup: boolean;
begin
    result := self.OldTrayPopup;
end;

procedure TFrmConfig.FormActivate(Sender: TObject);
begin
    self.UpdateColorExample;
end;

function TFrmConfig.FormatCount: integer;
var i : integer;
begin
    result := 0;
    for i := 0 to lvFormats.Items.count - 1 do begin
        if lvFormats.Items[i].Checked then inc(result);
    end;
end;
function TFrmConfig.GetFormat(index: integer): FormatOrder;

var i, j : integer;
    s : string;
begin
    result := FO_UNICODE;
    // find the index of the N-th checked item
    j := -1;
    for i := 0 to lvFormats.Items.count - 1 do begin
        if lvFormats.Items[i].Checked then inc(j);
        if j = index then begin
            j := i;
            BREAK;
        end;
    end;


    if (j <> -1) then begin
        s := lvFormats.Items[j].Caption;
        result := FO_UNICODE;
        if s = 'Unicode' then result := FO_UNICODE;
        if s = 'RichText' then result := FO_RICHTEXT;
        if s = 'HTML' then result := FO_HTML;
    end;
end;

function TFrmConfig.GetIconType : TCBXIconType;
begin
    result := TCBXIconType(cbxIconType.ItemIndex);
end;
function TFrmConfig.GetRepeatIcons : TCBXRepeatIcons;
begin
    result := TCBXRepeatIcons(cbxRepeatIcons.ItemIndex);
end;
function TFrmConfig.GetIconClickAction : TCBXIconClickAction;
begin
    result := TCBXIconClickAction(cbxIconClickAction.ItemIndex);
end;


const ArsClip = 'ArsClip';
procedure TFrmConfig.UpdateFontLabel(f : TFont);
begin
    with lblFontName do begin
        Caption := f.Name;
        Font.name := f.Name;
        font.Style := f.style;
        font.Size := f.Size;
    end;

end;

procedure TFrmConfig.HotkeySave;
var ini: TInifile;

    procedure PopupHotkey;
    begin
        // Hotkey Panel
        ini.WriteInteger(ArsClip,'Hotkey_Key', Hotkey_Key);
        ini.WriteBool(ArsClip,'Hotkey_Alt', Hotkey_Alt);
        ini.WriteBool(ArsClip,'Hotkey_Shift', Hotkey_Shift);
        ini.WriteBool(ArsClip,'Hotkey_Ctrl', Hotkey_Ctrl);
        ini.WriteBool(ArsClip,'Hotkey_Winkey', Hotkey_Winkey);

        ini.WriteInteger(ArsClip, 'PlainTextData_key', PlainTextData.key);
        ini.WriteBool(ArsClip, 'PlainTextData_alt', PlainTextData.alt);
        ini.WriteBool(ArsClip, 'PlainTextData_shft', PlainTextData.shft);
        ini.WriteBool(ArsClip, 'PlainTextData_ctrl', PlainTextData.ctrl);
        ini.WriteBool(ArsClip, 'PlainTextData_win', PlainTextData.win);

        ini.WriteBool(ArsClip, cbHotkeyTooltip.Name, cbHotkeyTooltip.Checked);
    end;
    procedure HotkeyAlternatives;
    begin
        // mouse trigger
        ini.WriteBool(ArsClip, cbRightTriggerEnable.Name, cbRightTriggerEnable.checked);
        ini.WriteInteger(ArsClip, cbxMouseButton.Name, cbxMouseButton.ItemIndex);
        ini.WriteInteger(ArsClip, tbHoldDelay.Name, tbHoldDelay.Position);

        ini.WriteBool(Arsclip, 'PopupDoubleclick', cbPopupDoubleclick.checked);
        ini.WriteBool(Arsclip, 'PopupDoubleclickTray', cbPopupDoubleclickTray.checked);
        ini.WriteBool(Arsclip, cbPopupSingleclickTray.Name, cbPopupSingleclickTray.checked);
        ini.WriteBool(Arsclip, cbPopupSingleclick.Name, cbPopupSingleclick.Checked);
    end;
    procedure ClipboardMonitor;
    begin
        if (cbDisable.Checked) then begin
            ini.WriteString(ArsClip, 'DisableMonitoring', 'Y');
        end else begin
            ini.WriteString(ArsClip, 'DisableMonitoring', 'N');
        end;
        ini.WriteBool(ArsClip, 'RememberHistory', cbRemember.checked);

        // new clip event
        ini.WriteBool(ArsClip, 'DisableWhenScrollLock', cbDisableWhenScrollLock.checked);
        ini.WriteBool(ArsClip, 'DisableSystemTrayIconNotification', cbDisableSystemTrayIconNotification.Checked   );
        Ini.WriteBool(ArsClip,'EnableSound', cbEnableSound.Checked);
        ini.WriteString('Sound','NewClip',self.Sound_NewClip);

        // global clipboard
        ini.WriteBool(ArsClip, cbGlobalClipboard.Name, cbGlobalClipboard.Checked);

        // troubleshooting
        ini.WriteBool(ArsClip, cbDisableChainNotification.name, cbDisableChainNotification.checked );
        ini.WriteBool(ArsClip, cbEnableExtendedChainChecking.Name, cbEnableExtendedChainChecking.Checked);
        ini.WriteBool(ArsClip, cbDisableWatcher.name, cbDisableWatcher.checked );

    end;
    procedure TextClips;
    var i : integer;
    begin
        for i := 0 to lvFormats.items.Count - 1 do begin
            ini.WriteString(ArsClip, lvFormats.name  + IntToStr(i) , lvFormats.Items[i].Caption);
            ini.WriteBool(ArsClip, lvFormats.name  + IntToStr(i) + 'checked' , lvFormats.Items[i].checked);
        end;

        //advanced
        ini.WriteBool(ArsClip, cbAutofixURLs.Name, cbAutofixURLs.Checked);
        ini.WriteBool(ArsClip, 'MoveDuplicate', cbMoveDuplicate.checked );
        ini.writeBool(ArsClip, cbRemoveFormat.name, cbRemoveFormat.checked );
        ini.WriteBool(ArsClip, cbCaseSensitive.name, cbCaseSensitive.checked);
        ini.WriteBool(ArsClip, cbIgnoreSmallText.name, cbIgnoreSmallText.checked);
        ini.WriteBool(ArsClip, cbDontCopyLargeText.name, cbDontCopyLargeText.checked);
        ini.WriteInteger(ArsClip, txtTextSizeLimitKB.name, StrToInt(txtTextSizeLimitKB.text));

    end;
    procedure NonTextClips;
    begin
        ini.WriteBool(ArsClip, 'MonitorFilenames', cbMonitorFilenames.checked);
        //-------------------
        // Non-text items
        //-------------------
        ini.WriteBool(ArsClip,'EnableOtherItems', cbOtherItems.Checked);
        ini.WriteInteger(ArsClip,'OtherSizeLimitKB', StrToInt(txtOtherSizeLimitKB.text));
        ini.WriteBool(ArsClip,cbAlwaysPicture.Name, cbAlwaysPicture.Checked);

        ini.WriteBool(ArsClip, cbNoThumbnails.Name, cbNoThumbnails.checked);

    end;
    procedure History;
    begin
        //
        //     History
        //
        ini.WriteInteger(ArsClip, 'RemovedItemsSize', udRemovedSize.Position);
//        RemovedQueue.SetQueueSize(udRemovedSize.position);
        ini.WriteInteger(ArsClip, 'QueueSize', udQueueSize.position);
        ClipQueue.SetQueueSize(udQueueSize.position);
    end;
    procedure Popup;
    begin
        ini.WriteBool(ArsClip, cbEditClipWindow.Name, cbEditClipWindow.checked);

    end;
    procedure Behavior;
    begin
        //pasting
        if (rbTyping.Checked) then begin
            ini.WriteString(ArsClip,'PasteMethod', 'MimicTyping');
        end else if (rbPaste.checked) then begin
            ini.WriteString(ArsClip, 'PasteMethod', 'CTRL+V');
        end else if (rbPasteSI.Checked) then begin
            ini.WriteString(ArsClip, 'PasteMethod', 'SHIFT+INSERT');
        end else begin
            ini.WriteString(ArsClip, 'PasteMethod', 'ClipboardOnly');
        end;


        ini.WriteBool(ArsClip, rbPlainAndFormatted.Name, rbPlainAndFormatted.Checked);
        ini.WriteBool(ArsClip, rbFormattedOnly.Name, rbFormattedOnly.Checked);
        ini.WriteBool(ArsClip, rbPlainOnly.Name, rbPlainOnly.Checked);


        //location
        ini.WriteBool(ArsClip, rbLocationAutomatic.Name, rbLocationAutomatic.Checked);
        ini.WriteBool(ArsClip, rbLocationMouseCursor.Name, rbLocationMouseCursor.Checked);
        ini.WriteBool(ArsClip, rbLocationProgramCorner.Name, rbLocationProgramCorner.Checked);

        //mouse
        ini.WriteBool(ArsClip, cbAutoExpand.Name, cbAutoExpand.Checked);
        ini.WriteBool(ArsClip, cbAutoCollapse.Name, cbAutoCollapse.Checked);
        ini.WriteBool(Arsclip, 'MoveSelectedToFirst', cbMoveFirst.Checked );

        ini.WriteInteger(ArsClip, cbxMouseWheelAction.Name, cbxMouseWheelAction.ItemIndex);
    end;
    procedure KeystrokesClicks;
    begin
        ini.WriteInteger(ArsClip, cbxShiftClickAction.Name, cbxShiftClickAction.ItemIndex);
        ini.WriteInteger(ArsClip, cbxCtrlClickAction.Name, cbxCtrlClickAction.ItemIndex);
        ini.WriteInteger(ArsClip, cbxMiddleClickAction.Name, cbxMiddleClickAction.ItemIndex);
        ini.WriteInteger(ArsClip, cbxAltClickAction.Name, cbxAltClickAction.ItemIndex);
        ini.WriteInteger(ArsClip, cbxTabKey.name+'_2', cbxTabKey.ItemIndex);


        //advanced;
        ini.WriteBool(ArsClip, cbPopupCharLimit.name, cbPopupCharLimit.Checked);
        ini.WriteInteger(ArsClip, udPopupKeysLimit.Name, udPopupKeysLimit.position);
        ini.WriteBool(ArsClip, cbPinnedShortcuts.Name, cbPinnedShortcuts.Checked);

        if (cbUseKeyboard.Checked) then begin
            ini.WriteString(ArsClip, 'PopupUseKeyboard', 'Y');
        end else begin
            ini.WriteString(ArsClip, 'PopupUseKeyboard', 'N');
        end;

    end;
    procedure TooltipHint;
    begin
        ini.WriteInteger(ArsClip, UDToolHeight.Name, UDToolHeight.Position);
        ini.WriteInteger(ArsClip, UDToolWidth.Name, UDToolWidth.Position);
        ini.WriteInteger(ARsClip, tbTooltipDelay.Name, tbTooltipDelay.Position);
        ini.WriteBool(ArsClip, cbSystemTrayTooltip.Name, cbSystemTrayTooltip.Checked);
        ini.WriteBool(ArsClip, cbTooltipRichText.Name, cbTooltipRichText.Checked);
        ini.WriteBool(ArsClip, cbShowHeaderFooter.Name, cbShowHeaderFooter.Checked);
    end;
    procedure ClipMenu;
    var i : integer;
    begin
        ini.WriteBool(ArsClip,cbClipMenuPin.name,cbClipMenuPin.Checked);
        ini.WriteBool(ArsClip,cbClipMenuEdit.name,cbClipMenuEdit.Checked);
        ini.WriteBool(ArsClip,cbClipMenuDelete.name,cbClipMenuDelete.Checked);
        ini.WriteBool(ArsClip,cbClipMenuDestroy.name,cbClipMenuDestroy.Checked);
        ini.WriteBool(ArsClip,cbClipMenuPasteUsing.name,cbClipMenuPasteUsing.Checked);
        ini.WriteBool(ArsClip,cbClipMenuPasteAs.name,cbClipMenuPasteAs.Checked);
        ini.WriteBool(ArsClip,cbClipMenuPermanent.name,cbClipMenuPermanent.Checked);
        ini.WriteBool(ArsClip,cbClipMenuConfigure.name,cbClipMenuConfigure.Checked);

//        ini.WriteBool(ArsClip,cbCustomMenu1.Name, cbCustomMenu1.Checked);
//        ini.WriteBool(ArsClip,cbCustomMenu2.Name, cbCustomMenu2.Checked);
//        ini.WriteBool(ArsClip,cbCustomMenu3.Name, cbCustomMenu3.Checked);
//
//        ini.WriteString(ArsClip,txtCustomCaption3.Name, txtCustomCaption3.text);
//        ini.WriteString(ArsClip,txtCustomCaption2.Name, txtCustomCaption2.text);
//        ini.WriteString(ArsClip,txtCustomCaption1.Name, txtCustomCaption1.text);
//
//        ini.WriteString(ArsClip,txtCustomClip3.Name, txtCustomClip3.text);
//        ini.WriteString(ArsClip,txtCustomClip2.Name, txtCustomClip2.text);
//        ini.WriteString(ArsClip,txtCustomClip1.Name, txtCustomClip1.text);

        for i := 0 to clbCustomMenus.Items.Count-1 do begin
            ini.WriteBool(ArsClip,'cbCustomMenu'+IntToStr(i+1), clbCustomMenus.Checked[i]);
            ini.WriteString(ArsClip,'txtCustomCaption'+IntToStr(i+1), clbCustomMenus.Items[i]);
            ini.WriteString(ArsClip,'txtCustomClip'+IntToStr(i+1), CustomMenuData[i]);
        end;
    end;
    procedure MenuItems;
    var i : integer;
    begin
        for i := ord(low(TMenuOrderType)) to ord(high(TMenuOrderType)) do begin
            ini.DeleteKey(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i) + 'data');
            ini.DeleteKey(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i) + 'sub');
            ini.DeleteKey(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i) + 'checked');
        end;
        for i := 0 to lvOrder.items.Count - 1 do begin
            ini.WriteInteger(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i) + 'data' , Integer(lvOrder.Items[i].data));
            ini.WriteString(ArsClip, LVORDER_ID + lvOrder.name  + IntToStr(i) + 'sub' , lvOrder.Items[i].SubItems[0]);
            ini.WriteBool(ArsClip, LVORDER_ID + lvOrder.name  + IntToStr(i) + 'checked', lvOrder.Items[i].Checked);
        end;

        // menu options
        ini.WriteInteger(ArsClip, UDWidth.Name, udWidth.Position);
        ini.WriteInteger(ArsClip, udMinHeight.Name, udMinHeight.Position);
        ini.WriteBool(ArsClip,cbDoubleHeight.Name, cbDoubleHeight.checked);
        //ini.WriteBool(ArsClip, 'CopyIcons', cbCopyIcons.checked);
        ini.WriteInteger(ArsClip, cbxIconType.Name, cbxIconType.ItemIndex);
        ini.WriteInteger(ArsClip, cbxRepeatIcons.Name, cbxRepeatIcons.ItemIndex);
        ini.WriteInteger(ArsClip, cbxIconClickAction.Name, cbxIconClickAction.ItemIndex);

        //perm
        ini.WriteBool(ArsClip, cbShowAllAsSubmenus.Name, cbShowAllAsSubmenus.checked);
        ini.WriteBool(ArsClip, cbShowAllItems.Name, cbShowAllItems.checked);
        ini.WriteBool(ArsClip,'ShowPermanentItemGroups', cbShowPermanentItemGroups.checked );
        ini.WriteBool(ArsClip, 'ShowPermanentItemSubmenu', cbPermanentItemsSubmenu.Checked );
    end;
    procedure ColorScheme;
    begin
        ini.WriteBool(ArsClip, cbFontColor.Name, cbFontColor.checked);
        ini.WriteBool(ArsClip, cbBackgroundColor.Name, cbBackgroundColor.checked);
        ini.WriteBool(ArsClip, cbHighlightColor.Name, cbHighlightColor.checked);
        ini.WriteBool(ArsClip, cbClickedColor.Name, cbClickedColor.checked);
        ini.WriteBool(ArsClip, cbTitleColor.Name, cbTitleColor.checked);

        ini.WriteInteger(ArsClip, pnlFontColor.Name, pnlFontColor.color);
        ini.WriteInteger(ArsClip, pnlBackgroundColor.Name, pnlBackgroundColor.color);
        ini.WriteInteger(ArsClip, pnlHighlightColor.Name, pnlHighlightColor.color);
        ini.WriteInteger(ArsClip, pnlClickedColor.Name, pnlClickedColor.color);
        ini.WriteInteger(ArsClip, pnlTitleColor.Name, pnlTitleColor.color);
    end;

    procedure ClipSets;
    begin
        ini.WriteInteger(ArsClip, udClipsPerSet.Name, udClipsPerSet.Position);
        ini.WriteBool(ArsClip, cbEnableClipSets.name, cbEnableClipSets.checked);
        ini.WriteBool(ArsClip, cbEnableClipsSetsWhenTall.Name, cbEnableClipsSetsWhenTall.checked);
        ini.WriteBool(ArsClip, rbClipSetsAlways.Name, rbClipSetsAlways.Checked);
        ini.WriteBool(ArsClip, rbClipSetsSelective.Name, rbClipSetsSelective.Checked);

        ini.WriteInteger(ArsClip, cbxFilterEnter.Name,cbxFilterEnter.itemindex);
        ini.WriteInteger(ArsClip, cbxFilterESC.Name,cbxFilterESC.itemindex);
        ini.WriteInteger(ArsClip, cbxFilterTab.Name,cbxFilterTab.itemindex);

        ini.WriteBool(ArsClip, cbFilterSimplified.Name, cbFilterSimplified.Checked);
        ini.WriteBool(ArsClip, cbFilterAlways.Name, cbFilterAlways.Checked);
    end;
    procedure ClipboardBar;
    begin
        ini.WriteBool(ArsClip, cbShowPopupWhenClicked.name, cbShowPopupWhenClicked.checked);
        ini.WriteBool(ArsClip, cbShowTooltipOnHover.name, cbShowTooltipOnHover.checked);
        ini.WriteInteger(ArsClip, udNormalOpacity.Name, udNormalOpacity.Position);
        if assigned(frmClipboardBar) then begin
            frmClipboardBar.NormalOpacity := udNormalOpacity.Position;
        end;


        ini.WriteBool(ArsClip, cbBarSnapToScreen.Name, cbBarSnapToScreen.Checked);
        ini.WriteBool(ArsClip, cbClipboardBarVirtualDesktop.name, cbClipboardBarVirtualDesktop.checked);

        ini.Writebool(ArsClip, btnBarTop.name, btnBarTop.down);
        ini.Writebool(ArsClip, btnBarTopRight.name, btnBarTopRight.down);
        ini.Writebool(ArsClip, btnBarTopLeft.name, btnBarTopLeft.down);
        ini.Writebool(ArsClip, btnBarLeft.name, btnBarLeft.down);
        ini.Writebool(ArsClip, btnBarRight.name, btnBarRight.down);
        ini.Writebool(ArsClip, btnBarBottom.name, btnBarBottom.down);
        ini.Writebool(ArsClip, btnBarBottomLeft.name, btnBarBottomLeft.down);
        ini.Writebool(ArsClip, btnBarBottomRight.name, btnBarBottomRight.down);
    end;
    procedure TriggerWindows;
    begin
     // trigger window
        ini.WriteBool(ArsClip, cbTriggerWindow.Name, cbTriggerWindow.Checked);
        ini.WriteInteger(ArsClip, tbDelay.name, tbdelay.Position);
        ini.writebool(ArsClip, sbtop.name, sbtop.down);
        ini.writebool(ArsClip, sbbottom.name, sbbottom.down);
        ini.writebool(ArsClip, sbleft.name, sbleft.down);
        ini.writebool(ArsClip, sbright.name, sbright.down);
        ini.writebool(ArsClip, sbtopleft.name, sbtopleft.down);
        ini.writebool(ArsClip, sbtopright.name, sbtopright.down);
        ini.writebool(ArsClip, sbbottomleft.name, sbbottomleft.down);
        ini.writebool(ArsClip, sbbottomright.name, sbbottomright.down);
        ini.WriteInteger(ArsClip, tbTriggerThickness.Name, tbTriggerThickness.Position);
    end;
    procedure Jumplist;
    begin
        ini.WriteInteger(ArsClip, cbxClickedAction.Name, cbxClickedAction.ItemIndex);
    end;
begin
    ini := TInifile.Create( self.GetINIFileName );

    PopupHotkey;
        HotkeyAlternatives;
    ClipboardMonitor;
        History;
        TextClips;
        NonTextClips;
    Popup;
        Behavior;
        KeystrokesClicks;
        TooltipHint;
        ClipMenu;
    //Popup Presentation
        MenuItems;
        ColorScheme;
        ClipSets;
    //Misc
        ClipboardBar;
        TriggerWindows;
        JumpList;

    self.CopySelected := false;

    //-----------
    // no visible control
    //----------------
    ini.WriteInteger(ArsClip,'RightClickDelay', self.RightClickDelay);
    ini.WriteBool(ArsClip, 'RightclickTriggerWarned', self.RightclickTriggerWarned);
    ini.WriteInteger(ArsClip,'PasteDelay', self.PasteDelay);
    ini.WriteString(ArsClip, 'LastPermanentPath', frmPermanent.GetPermanentPath);

    ini.WriteInteger(ArsClip, cbxMode.Name, cbxMode.ItemIndex);

    MyFree(ini);

end;
procedure TFrmConfig.HotkeyLoad;
var ini: TInifile;
    s : string;
    data : integer;
    i, j,k,m : integer;
    c : cardinal;
    fs : TFontStyles;

    showorderfound : array[TMenuOrderType] of boolean;
    li : TListItem;


    procedure CopyLI(dest, src : TListItem);
    begin
        dest.caption := src.caption;
        dest.SubItems.Clear;
        dest.SubItems.AddStrings(src.SubItems);
        dest.checked := src.Checked;
        dest.Data := src.data;
    end;
const ACCEL_SECTION  = 'Acellerators';
const
    ARSCLIP_HIDDEN = 'Hidden';
    MIN_CLIP_LENGTH = 'MinClipLength';
    SHOW_CLIP_CUES = 'ShowClipCues';
    AUTO_SAVE_TIME_MS = 'AutoSaveTimeMS';
    ICON_RETRY_COUNT = 'IconRetryCount';
    EXTRACT_ICON_FOR_POPUP = 'ExtractIconForPopup';
    SHARED_UPDATE_TIME_MS = 'SharedUpdateTimeMS';
    SEARCH_REMOVED_ON_BY_DEFAULT = 'SearchRemovedOnByDefault';
    ALWAYS_CLEAR_FILTER = 'AlwaysClearFilter';
    RETURN_POPUP_FOCUS_WHEN_PINNED = 'ReturnPopupFocusWhenPinned';
    procedure PopupHotkey;
    begin
        Hotkey_Key := ini.ReadInteger(ArsClip,'Hotkey_Key', Ord('Z'));
        Hotkey_Alt := ini.ReadBool(ArsClip,'Hotkey_Alt', false);
        Hotkey_Shift := ini.ReadBool(ArsClip,'Hotkey_Shift', true);
        Hotkey_Ctrl := ini.ReadBool(ArsClip,'Hotkey_Ctrl', true);
        Hotkey_Winkey := ini.ReadBool(ArsClip,'Hotkey_Winkey', false);

        PlainTextData.key := ini.ReadInteger(ArsClip, 'PlainTextData_key', 0);
        PlainTextData.alt := ini.ReadBool(ArsClip, 'PlainTextData_alt', false);
        PlainTextData.shft := ini.ReadBool(ArsClip, 'PlainTextData_shft', false);
        PlainTextData.ctrl := ini.ReadBool(ArsClip, 'PlainTextData_ctrl', false);
        PlainTextData.win := ini.ReadBool(ArsClip, 'PlainTextData_win', true);

        cbHotkeyTooltip.Checked := ini.ReadBool(ArsClip, cbHotkeyTooltip.Name, cbHotkeyTooltip.Checked);
    end;
    procedure ClipMenu;
    var i,j : integer;
        s : string;
    begin

        if not ini.readbool(ArsClip, 'NewClipMenuConfig', false) then begin
            ini.WriteBool(ArsClip, 'NewClipMenuConfig', true);

            ini.WriteBool(ArsClip,cbClipMenuPin.name,cbClipMenuPin.Checked);
            ini.WriteBool(ArsClip,cbClipMenuEdit.name,cbClipMenuEdit.Checked);
            ini.WriteBool(ArsClip,cbClipMenuDelete.name,cbClipMenuDelete.Checked);
            ini.WriteBool(ArsClip,cbClipMenuDestroy.name,cbClipMenuDestroy.Checked);
            ini.WriteBool(ArsClip,cbClipMenuPasteUsing.name,cbClipMenuPasteUsing.Checked);
            ini.WriteBool(ArsClip,cbClipMenuPasteAs.name,cbClipMenuPasteAs.Checked);
            ini.WriteBool(ArsClip,cbClipMenuPermanent.name,cbClipMenuPermanent.Checked);
            ini.WriteBool(ArsClip,cbClipMenuConfigure.name,cbClipMenuConfigure.Checked);
        end else begin
            cbClipMenuPin.Checked := ini.ReadBool(ArsClip,cbClipMenuPin.name,cbClipMenuPin.Checked);
            cbClipMenuEdit.Checked := ini.ReadBool(ArsClip,cbClipMenuEdit.name,cbClipMenuEdit.Checked);
            cbClipMenuDelete.Checked := ini.ReadBool(ArsClip,cbClipMenuDelete.name,cbClipMenuDelete.Checked);
            cbClipMenuDestroy.Checked := ini.ReadBool(ArsClip,cbClipMenuDestroy.name,cbClipMenuDestroy.Checked);
            cbClipMenuPasteUsing.Checked := ini.ReadBool(ArsClip,cbClipMenuPasteUsing.name,cbClipMenuPasteUsing.Checked);
            cbClipMenuPasteAs.Checked := ini.ReadBool(ArsClip,cbClipMenuPasteAs.name,cbClipMenuPasteAs.Checked);
            cbClipMenuPermanent.Checked := ini.ReadBool(ArsClip,cbClipMenuPermanent.name,cbClipMenuPermanent.Checked);
            cbClipMenuConfigure.Checked := ini.ReadBool(ArsClip,cbClipMenuConfigure.name,cbClipMenuConfigure.Checked);
        end;


        i := 1;
        CustomMenuData := TStringList.Create;
        clbCustomMenus.Clear;
        repeat
            s := ini.ReadString(ArsClip, 'txtCustomCaption'+IntToStr(i),'');
            if s <> '' then begin
                j := clbCustomMenus.Items.Add(s);
                clbCustomMenus.Checked[j] := ini.ReadBool(ArsClip,'cbCustomMenu'+IntToStr(i),false);
                CustomMenuData.Add(ini.ReadString(ArsClip,'txtCustomClip'+IntToStr(i),''));
                inc(i);
            end;
        until s='';
        // default scripts
        if i=1 then begin
            j := clbCustomMenus.Items.Add('Paste and Delete');
            clbCustomMenus.Checked[j] :=  false;
            CustomMenuData.Add('[INDEX=$i][TOCLIPBOARD=$i][PASTEDEFAULT][DELETECLIP=$i]');

            j := clbCustomMenus.Items.Add('Paste with Time');
            clbCustomMenus.Checked[j] :=  false;
            CustomMenuData.Add('Time:[DATE="hh:nn:ss ampm"] [INDEX=$i][TOCLIPBOARD=$i][TRIMCLIPBOARD][CLIPBRDCURRENT]');

            j := clbCustomMenus.Items.Add('Move to Top');
            clbCustomMenus.Checked[j] :=  false;
            CustomMenuData.Add('[STAYOPEN][INDEX=$i][MOVECLIP="$i" TO="0"]');
        end;
        btnCustomMenu1.Enabled := false;
    end;
    procedure Behavior;
    begin
        //
        // Pasting options
        //
        rbTyping.Checked := ini.ReadString(ArsClip, 'PasteMethod', 'CTRL+V') = 'MimicTyping';
        rbPaste.Checked := ini.ReadString(ArsClip, 'PasteMethod', 'CTRL+V') = 'CTRL+V';
        rbClipboardOnly.checked := ini.ReadString(ArsClip, 'PasteMethod', 'CTRL+V') = 'ClipboardOnly';
        rbPasteSI.Checked := ini.ReadString(ArsClip, 'PasteMethod', 'CTRL+V') = 'SHIFT+INSERT';

        rbPlainAndFormatted.Checked := ini.ReadBool(ArsClip, rbPlainAndFormatted.Name, true);
        rbFormattedOnly.Checked := ini.ReadBool(ArsClip, rbFormattedOnly.Name, false);
        rbPlainOnly.Checked := ini.ReadBool(ArsClip, rbPlainOnly.Name, false);

        // custom script
    end;
    procedure ProgramOptions;
        procedure DisableAll(p : TWinControl) ;
        var
            i : integer;
        begin
            for i := 0 to p.ControlCount-1 do begin
                if not (p.Controls[i] is TLabel) then
                    p.Controls[i].Enabled := false;
            end;
        end;
    begin

    end;
    procedure MenuOrder;
    var i,j,k,m : integer;
        procedure RemoveDeprecated(MenuId : TMenuOrderType);
        begin
            li := lvorder.findcaption(0,self.MenuOrderText(MenuId,false),false,true,false);
            if (li <> nil) then lvorder.Items.Delete(li.index);
        end;
    begin
        for i := ord(low(tmenuordertype)) to ord(high(tmenuordertype)) do begin
            showorderfound[tmenuordertype(i)] := false;
        end;
        for i := ord(low(tmenuordertype)) to ord(high(tmenuordertype)) do begin
            data := ini.ReadInteger(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i)+'data' ,-1);
            if (data <> -1) then begin
                if TMenuOrderType(data) in [MOT_LAST, MOT_SELECTED, MOT_SEARCH, MOT_FULL, MOT_SYSTEM] then CONTINUE;
                li := lvorder.FindCaption(0,self.MenuOrderText(TMenuOrderType(data),false),false,true,false);

                if li <> nil then begin
                    showorderfound[tmenuordertype(data)] := true;
                    defaultmenuorder[tmenuordertype(data)] := i;
                    li.subitems[0] := ini.ReadString(ArsClip, LVORDER_ID + lvOrder.name  + IntToStr(i) + 'sub' , 'no');
                    li.Checked := ini.ReadBool(ArsClip, LVORDER_ID +  lvOrder.name  + IntToStr(i) + 'checked', true);

                    if TMenuOrderType(data) = MOT_SELECTED  then
                        self.CopySelected := lvOrder.Items[i].Checked;
                end;
            end;
        end;
        //
        // move all items to default positions
        // (basic bubble sort)  - TODO fix this wrong implementation
        for i := ord(low(tmenuordertype)) to ord(high(tmenuordertype)) {- 1} do begin
            li := lvorder.FindCaption(0,self.MenuOrderText(TMenuOrderType(i),false),false,true,false);
            if (li <> nil) and showorderfound[TMenuOrderType(i)] then begin
                k := Min(lvorder.Items.Count-1, DefaultMenuOrder[TMenuOrderType(i)]);

                j := li.Index;
                if (j>k) then begin
                    for m := j downto k + 1 do begin
                        // swap m and (m-1)
                        li := lvOrder.Items.Add;
                        CopyLI(li, lvOrder.items[m]);
                        CopyLI(lvOrder.items[m], lvOrder.items[m-1]);
                        CopyLI(lvOrder.items[m-1], li);
                        lvOrder.Items.Delete(li.Index);
                    end;
                end else if (j<k) then begin
                    for m := j to k - 1 do begin
                        // swap m and (m-1)
                        li := lvOrder.Items.Add;
                        CopyLI(li, lvOrder.items[m]);
                        CopyLI(lvOrder.items[m], lvOrder.items[m+1]);
                        CopyLI(lvOrder.items[m+1], li);
                        lvOrder.Items.Delete(li.Index);
                    end;

                end;
            end;
        end;
        for i := ord(low(tmenuordertype)) to ord(high(tmenuordertype)) {- 1} do begin
            li := lvorder.FindCaption(0,self.MenuOrderText(TMenuOrderType(i),false),false,true,false);
            if (li <> nil) and showorderfound[TMenuOrderType(i)] then begin
                k := Min(lvorder.Items.Count-1, DefaultMenuOrder[TMenuOrderType(i)]);

                j := li.Index;
                if (j>k) then begin
                    for m := j downto k + 1 do begin
                        // swap m and (m-1)
                        li := lvOrder.Items.Add;
                        CopyLI(li, lvOrder.items[m]);
                        CopyLI(lvOrder.items[m], lvOrder.items[m-1]);
                        CopyLI(lvOrder.items[m-1], li);
                        lvOrder.Items.Delete(li.Index);
                    end;
                end else if (j<k) then begin
                    for m := j to k - 1 do begin
                        // swap m and (m-1)
                        li := lvOrder.Items.Add;
                        CopyLI(li, lvOrder.items[m]);
                        CopyLI(lvOrder.items[m], lvOrder.items[m+1]);
                        CopyLI(lvOrder.items[m+1], li);
                        lvOrder.Items.Delete(li.Index);
                    end;

                end;
            end;
        end;

        RemoveDeprecated(MOT_LAST);
        RemoveDeprecated(MOT_SELECTED);
        RemoveDeprecated(MOT_SEARCH);
        RemoveDeprecated(MOT_FULL);
        RemoveDeprecated(MOT_SYSTEM);
    end;
    procedure HandleColors;
    begin
        cbFontColor.checked := ini.Readbool(ArsClip, cbFontColor.Name, false);
        cbBackgroundColor.checked := ini.Readbool(ArsClip, cbBackgroundColor.Name, false);
        cbHighlightColor.checked := ini.Readbool(ArsClip, cbHighlightColor.Name, false);
        cbClickedColor.Checked := ini.Readbool(ArsClip, cbClickedColor.Name, false);
        cbTitleColor.checked := ini.Readbool(ArsClip, cbTitleColor.Name, false);

        pnlFontColor.color :=  ini.readInteger(ArsClip, pnlFontColor.Name, pnlFontColor.color);
        pnlBackgroundColor.color := ini.readInteger(ArsClip, pnlBackgroundColor.Name, pnlBackgroundColor.color);
        pnlHighlightColor.color := ini.readInteger(ArsClip, pnlHighlightColor.Name, pnlHighlightColor.color);
        pnlClickedColor.color := ini.readInteger(ArsClip, pnlClickedColor.Name, pnlClickedColor.color);
        if (not cbTitleColor.checked) then begin
            pnlTitleColor.color := pnlBackgroundColor.Color;
        end else begin
            pnlTitleColor.color := ini.readInteger(ArsClip, pnlTitleColor.Name, pnlTitleColor.color);
        end;


        UpdateColorExample;
    end;
    procedure HandleHidden;
    begin
        self.minClipLength := ini.ReadInteger(ARSCLIP_HIDDEN,MIN_CLIP_LENGTH, 4);
        ini.WriteInteger(ARSCLIP_HIDDEN, MIN_CLIP_LENGTH, minClipLength);
        self.showClipCues := ini.ReadBool(ARSCLIP_HIDDEN, SHOW_CLIP_CUES, true);
        ini.WriteBool(ARSCLIP_HIDDEN, SHOW_CLIP_CUES, self.showClipCues);
        i := ini.ReadInteger(ARSCLIP_HIDDEN, AUTO_SAVE_TIME_MS, 10 * 60 * 1000 );
        ini.WriteInteger(ARSCLIP_HIDDEN, AUTO_SAVE_TIME_MS, 10 * 60 * 1000 );

        iconRetryCount := ini.ReadInteger(ARSCLIP_HIDDEN,ICON_RETRY_COUNT, 15);
        ini.WriteInteger(ARSCLIP_HIDDEN,ICON_RETRY_COUNT, iconRetryCount);


        extractIconForPopup := ini.ReadBool(ARSCLIP_HIDDEN, EXTRACT_ICON_FOR_POPUP, true);
        ini.WriteBool(ARSCLIP_HIDDEN, EXTRACT_ICON_FOR_POPUP, extractIconForPopup);

        sharedUpdateTimeMS := ini.ReadInteger(ARSCLIP_HIDDEN,SHARED_UPDATE_TIME_MS, 60000);
        ini.WriteInteger(ARSCLIP_HIDDEN,SHARED_UPDATE_TIME_MS, sharedUpdateTimeMS);

        searchRemovedOn := ini.ReadBool(ARSCLIP_HIDDEN, SEARCH_REMOVED_ON_BY_DEFAULT, false);
        ini.WriteBool(ARSCLIP_HIDDEN, SEARCH_REMOVED_ON_BY_DEFAULT, searchRemovedon);

        alwaysClearFilter := ini.ReadBool(ARSCLIP_HIDDEN, ALWAYS_CLEAR_FILTER, false );
        ini.WriteBool(ARSCLIP_HIDDEN, ALWAYS_CLEAR_FILTER, alwaysClearFilter);

        returnPopupFocusWhenPinned := ini.ReadBool(ARSCLIP_HIDDEN, RETURN_POPUP_FOCUS_WHEN_PINNED, true);
        ini.WriteBool(ARSCLIP_HIDDEN, RETURN_POPUP_FOCUS_WHEN_PINNED, returnPopupFocusWhenPinned);
    end;
begin
    isLoading := true;
    try
    FrmDebug.AppendLog('HotkeyLoad - start');
    //
    // read last assigned hotkey
    // CTRL+SHIFT+Z is default
    //
    // fake the user selecting the Modifier and the Normal Key


    ini := TInifile.Create( self.GetINIFileName );

    if (Win32MajorVersion >= 6) then begin
        tempFont.Name := ini.ReadString('Font','Name', 'Segoe UI');
    end else begin
        tempFont.Name := ini.ReadString('Font','Name', 'Arial');
    end;
    tempFont.Charset := ini.ReadInteger('Font','CharSet', self.Font.Charset);
    tempFont.Color := ini.ReadInteger('Font','Color', self.Font.Color);
    tempFont.Size := ini.ReadInteger('Font','Size', 9);

    if not ini.ValueExists(ACCEL_SECTION, 'Symbols') then begin
    	ini.WriteString(ACCEL_SECTION, 'Symbols', '-=[]\;'',./~!@#$%^&*()_+{}|:"<>?`');
    end;
    if not ini.ValueExists(ACCEL_SECTION, 'AlphaNumeric') then begin
    	ini.WriteString(ACCEL_SECTION, 'AlphaNumeric', '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ');
    end;
    alphanumerickeys := ini.ReadString(ACCEL_SECTION,'AlphaNumeric','');
    symbolkeys := ini.ReadString(ACCEL_SECTION,'Symbols','');


    c := ini.ReadInteger('Font','Style',0);
    move(c, fs, 4);
    tempFont.Style := fs;

    FontDialog.Font := tempFont;
    //tempFont:= FrmDummyUnicodePopup.Font;


    // hidden settings
    self.PreCaptureDelayMS := ini.ReadInteger(ArsClip,'PreCaptureDelay', 50);
    ini.WriteInteger(ArsClip,'PreCaptureDelay', self.PreCaptureDelayMS);
    self.RightClickDelay := ini.ReadInteger(ArsClip,'RightClickDelay', 400);
    self.RightClickDelay := max(200, self.RightClickDelay);
    ini.WriteInteger(ArsClip,'RightClickDelay', self.RightClickDelay);
    self.OldTrayPopup := ini.ReadBool(ArsClip, 'OldTrayPopup', false);
    ini.WriteBool(ArsClip,'OldTrayPopup', self.OldTrayPopup);
    self.MimicDelayMS := ini.ReadInteger(ArsClip,'MimicDelayMS', 10);
    self.MimicDelayMSEnabled := ini.ReadBool(ArsClip,'MimicDelayMSEnabled',false);
    ini.WriteInteger(ArsClip, 'MimicDelayMS', self.MimicDelayMS);
    ini.WriteBool(ArsClip,'MimicDelayMSEnabled',self.MimicDelayMSEnabled);




    self.fTXTProgram := ini.ReadString(ArsClip,'TXTProgram','');
    if fTXTProgram = '' then begin
        fTXTProgram := UnitMisc.GetAssociation('test.txt');
        if fTXTProgram = '' then begin
            fTXTProgram := UnitMisc.GetAssociation('test.txt','edit');
        end;

        ini.WriteString(ArsClip, 'TXTProgram',
            ReplaceStr(self.fTXTProgram,'"','\"')
        );
    end else begin
        self.fTXTProgram := ReplaceStr(self.fTXTProgram,'\"','"');
    end;

    self.fBMPProgram := ini.ReadString(ArsClip,'BMPPRogram','');
    if fBMPProgram = '' then begin
        fBMPProgram := UnitMisc.GetAssociation('test.bmp');
        if fBMPProgram = '' then begin
            fBMPProgram := UnitMisc.GetAssociation('test.bmp','edit');
        end;
        ini.WriteString(ArsClip, 'BMPProgram', ReplaceStr(self.fBMPProgram,'"','\"'));
    end else begin
        self.fBMPProgram := ReplaceStr(self.fBMPProgram,'\"','"');
    end;




    PopupHotkey;
    ClipMenu;
    Behavior;
    ProgramOptions;

    //----------------
    // 'Popup' panel
    //----------------
    cbMoveFirst.Checked := ini.ReadBool(ArsClip, 'MoveSelectedToFirst', false);
    cbUseKeyboard.Checked := (ini.ReadString(ArsClip,'PopupUseKeyboard', 'Y') = 'Y');
    cbPopupDoubleclick.checked := ini.ReadBool(Arsclip, 'PopupDoubleclick', false);
    cbPopupDoubleclickTray.checked := ini.ReadBool(Arsclip, 'PopupDoubleclickTray', false);
    //udCharacters.position := ini.ReadInteger(ArsClip, 'CharactersToShow', 30);
    //frmMainPopup.SetVisibleCharacterCount(udCharacters.position);

    cbAutoExpand.Checked := ini.readBool(ArsClip, cbAutoExpand.Name, false);
	cbAutoCollapse.Checked := ini.readBool(ArsClip, cbAutoCollapse.Name, cbAutoCollapse.checked);

    cbxMouseWheelAction.ItemIndex := ini.ReadInteger(ArsClip, cbxMouseWheelAction.Name, cbxMouseWheelAction.ItemIndex);
    cbEditClipWindow.checked := ini.ReadBool(ArsClip, cbEditClipWindow.Name, false);

    //
    // Hotkey Alternatives / Keystrokes
    //

    cbxShiftClickAction.ItemIndex := ini.ReadInteger(ArsClip, cbxShiftClickAction.Name, cbxShiftClickAction.ItemIndex);
    cbxCtrlClickAction.ItemIndex := ini.ReadInteger(ArsClip, cbxCtrlClickAction.Name, cbxCtrlClickAction.ItemIndex);
    cbxMiddleClickAction.ItemIndex := ini.ReadInteger(ArsClip, cbxMiddleClickAction.Name, cbxMiddleClickAction.ItemIndex);
    cbxAltClickAction.ItemIndex := ini.ReadInteger(ArsClip, cbxAltClickAction.Name, cbxAltClickAction.ItemIndex);
    cbxTabKey.ItemIndex := ini.ReadInteger(ArsClip, cbxTabKey.name+'_2', cbxTabKey.ItemIndex);

    cbPopupCharLimit.Checked := ini.ReadBool(ArsClip, cbPopupCharLimit.name, cbPopupCharLimit.Checked);
    udPopupKeysLimit.Position := ini.ReadInteger(ArsClip, udPopupKeysLimit.Name, udPopupKeysLimit.position);
    cbPinnedShortcuts.Checked := ini.ReadBool(ArsClip, cbPinnedShortcuts.Name, true);

    tbHoldDelay.Position := ini.ReadInteger(ArsClip, tbHoldDelay.Name, 4 {400ms});

    rbLocationAutomatic.Checked := ini.ReadBool(ArsClip, rbLocationAutomatic.Name, true);
    rbLocationMouseCursor.Checked := ini.ReadBool(ArsClip, rbLocationMouseCursor.Name, false);
    rbLocationProgramCorner.Checked := ini.ReadBool(ArsClip, rbLocationProgramCorner.Name, false);



    cbPopupSingleclickTray.checked := ini.ReadBool(Arsclip, cbPopupSingleclickTray.Name, false);
    cbPopupSingleclick.Checked := ini.ReadBool(Arsclip, cbPopupSingleclick.Name, false);
    udWidth.Position := ini.ReadInteger(ArsClip, UDWidth.Name, 320);
    udMinHeight.Position := ini.ReadInteger(ArsClip, udMinHeight.Name, 18);
    cbRightTriggerEnable.Checked := ini.readbool(ArsClip, cbRightTriggerEnable.Name, true);
    cbxMouseButton.ItemIndex := ini.ReadInteger(ArsClip, cbxMouseButton.Name, 0);

    self.cbRightTriggerEnableClick(self);
    // setting the ItemIndex doesn't auto set of any event

    //-------------------
    // Show Options
    //-------------------

    cbDoubleHeight.checked := ini.ReadBool(ArsClip, cbDoubleHeight.name, true);
    cbShowPermanentItemGroups.checked := ini.ReadBool(ArsClip,'ShowPermanentItemGroups', true );
    cbPermanentItemsSubmenu.checked := ini.Readbool(ArsClip,'ShowPermanentItemSubmenu', false);
    cbShowAllItems.checked := ini.ReadBool(ArsClip, cbShowAllItems.Name, true);
    cbShowAllAsSubmenus.checked := ini.ReadBool(ArsClip, cbShowAllAsSubmenus.Name, false);
    cbNoThumbnails.checked := ini.ReadBool(ArsClip, cbNoThumbnails.Name, false);

    HandleColors;


    cbxIconType.ItemIndex := ini.ReadInteger(ArsClip, cbxIconType.Name, cbxIconType.ItemIndex);
    cbxRepeatIcons.ItemIndex := ini.ReadInteger(ArsClip, cbxRepeatIcons.Name, cbxRepeatIcons.ItemIndex);
    cbxIconClickAction.ItemIndex := ini.ReadInteger(ArsClip, cbxIconClickAction.Name, cbxIconClickAction.ItemIndex);


    //
    // Clip Sets
    //

    udClipsPerSet.Position := ini.ReadInteger(ArsClip, udClipsPerSet.Name, udClipsPerSet.Position);
    cbEnableClipSets.checked := ini.ReadBool(ArsClip, cbEnableClipSets.name, cbEnableClipSets.checked);
    cbEnableClipsSetsWhenTall.checked := ini.ReadBool(ArsClip, cbEnableClipsSetsWhenTall.Name, cbEnableClipsSetsWhenTall.checked);
    rbClipSetsAlways.Checked := ini.ReadBool(ArsClip, rbClipSetsAlways.Name, true);
    rbClipSetsSelective.Checked := ini.ReadBool(ArsClip, rbClipSetsSelective.Name, false);

    cbxFilterEnter.ItemIndex := ini.ReadInteger(ArsClip, cbxFilterEnter.Name,1);
    cbxFilterESC.ItemIndex := ini.ReadInteger(ArsClip, cbxFilterESC.Name,0);
    cbxFilterTab.ItemIndex := ini.ReadInteger(ArsClip, cbxFilterTab.Name,0);

    cbFilterSimplified.Checked := ini.ReadBool(ArsClip, cbFilterSimplified.Name, true);
    cbFilterAlways.Checked := ini.ReadBool(ArsClip, cbFilterAlways.Name, cbFilterAlways.Checked);
    //-------------------
    // Pasting
    //-------------------

    //-------------------
    // Clipboard
    //-------------------
    cbDisable.Checked := (ini.ReadString(ArsClip,'DisableMonitoring','N') = 'Y');
    cbDisableWhenScrollLock.Checked := ini.ReadBool(ArsClip, 'DisableWhenScrollLock', true);
    frmClipboardManager.SetDisableWhenScrollLock(cbDisableWhenScrollLock.checked);
    cbDisableSystemTrayIconNotification.Checked := ini.ReadBool(ArsClip,'DisableSystemTrayIconNotification', false);
    cbDisableChainNotification.checked := ini.ReadBool(ArsClip, cbDisableChainNotification.name,  false);
    cbEnableExtendedChainChecking.Checked := ini.ReadBool(ArsClip, cbEnableExtendedChainChecking.Name, false);
    cbAutofixURLs.Checked := ini.ReadBool(ArsClip, cbAutofixURLs.Name, false);
    cbDisableWatcher.checked := ini.ReadBool(ArsClip, cbDisableWatcher.name,  false);

    // global clipboard
    cbGlobalClipboard.Checked := ini.ReadBool(ArsClip, cbGlobalClipboard.Name, cbGlobalClipboard.Checked);


    //------------------------
    // Clipboard Non-text
    //------------------------

    cbOtherItems.Checked := ini.ReadBool(ArsClip,'EnableOtherItems', true);
    cbAlwaysPicture.Checked := ini.ReadBool(ArsClip,cbAlwaysPicture.Name, true);
    txtOtherSizeLimitKB.text := IntToStr(ini.ReadInteger(ArsClip,'OtherSizeLimitKB', 500));

    // Ect - util stuff
    // HuH? The "Other" config options above seem not to work
    txtOtherSizeLimitKB.OnChange(self);


    cbEnableSound.Checked := Ini.ReadBool(ArsClip,'EnableSound', False);
    PlaySound_Init;


    //
    // History
    //

    //udRecentlyRemoved.Position := ini.ReadInteger(ArsClip, udRecentlyRemoved.Name, 5);
    udqueuesize.Position  := ini.ReadInteger(ArsClip, 'QueueSize', 15);
    udRemovedSize.Position := ini.ReadInteger(ArsClip, 'RemovedItemsSize', 50);
//    udOtherSize.Position := ini.ReadInteger(ArsClip, 'OtherSize', 5);

//    OtherQueue.SetQueueSize(udOtherSize.position);
    ClipQueue.SetQueueSize(udQueueSize.position);
    RemovedQueue.SetQueueSize(udRemovedSize.position);
    //UnitClipQueue.ResyncTempClipQueue;


    //-----------------------
    // Clipboard Text
    //-----------------------

    cbMonitorFilenames.Checked :=  ini.ReadBool(ArsClip, 'MonitorFilenames', false);
    cbRemember.Checked := ini.ReadBool(ArsClip, 'RememberHistory', true);
    cbMoveDuplicate.checked := ini.ReadBool(ArsClip, 'MoveDuplicate', true);
    cbRemoveFormat.checked := ini.ReadBool(ArsClip, cbremoveformat.name, false);
    cbCaseSensitive.checked := ini.ReadBool(ArsClip, cbCaseSensitive.name, false);
    cbIgnoreSmallText.Checked := ini.ReadBool(ArsClip,cbIgnoreSmallText.name, false);
    cbDontCopyLargeText.checked := ini.ReadBool(ArsClip, cbDontCopyLargeText.name, false);
    txtTextSizeLimitKB.text := IntToStr(ini.ReadInteger(ArsClip, txtTextSizeLimitKB.name, StrToInt(txtTextSizeLimitKB.text)));

    s := '';
    i := 0;
    j := 0;
    repeat
        s := ini.ReadString(ArsClip, lvFormats.name  + IntToStr(i) ,'');
        li := lvFormats.FindCaption(0,s,false,true,false);
        if  li = nil then begin
            if (s <> '') and (lowercase(s)<>'unicode') then begin
                lvFormats.Items[j].Caption := s;
                lvFormats.Items[j].checked := ini.ReadBool(ArsClip, lvFormats.name  + IntToStr(i) + 'checked', true);
                inc(j);
            end;
        end else begin
            li.checked := ini.ReadBool(ArsClip, lvFormats.name  + IntToStr(i) + 'checked', true);
        end;
        inc(i);
    until (s = '');



    //------------------------
    //  Show Order
    //------------------------


    s := '';

    //self.CopySelected := false;

    // First, generate a list of all found items with their default states
    MenuOrder;


    cbUseKeyboard.OnClick(self);
    cbDisable.OnClick(self);

    frmPermanent.SetPermanentPath(ini.ReadString(ArsClip, 'LastPermanentPath', UnitFrmPermanentNew.DEFAULT_FOLDER));

    //------------------------
    //  Tooltip
    //------------------------
    //cbFullHeader.Checked := ini.ReadBool(ArsClip,'FullHeader', true);
    //cbCopyVisibleItem.Checked := ini.ReadBool(ArsClip,'CopyVisibleItem', false);


    //------------------------
    //  Tooltip Hint
    //------------------------

    UDToolHeight.Position := ini.ReadInteger(ArsClip, UDToolHeight.Name, 200);
    UDToolWidth.Position := ini.ReadInteger(ArsClip, UDToolWidth.Name, 320);
    tbTooltipDelay.Position := ini.ReadInteger(ARsClip, tbTooltipDelay.Name, 300);
    cbSystemTrayTooltip.Checked := ini.ReadBool(ArsClip, cbSystemTrayTooltip.Name, true);
    cbTooltipRichText.Checked := ini.ReadBool(ArsClip, cbTooltipRichText.Name, cbTooltipRichText.Checked);
    cbShowHeaderFooter.Checked := ini.ReadBool(ArsClip, cbShowHeaderFooter.Name, cbShowHeaderFooter.Checked);

    //
    // these are here because because there is no "onchange"
    // triggered when the control's state is changed
    //
//    if (rbOtherPaste.Checked) then begin
//        frmMainPopup.SetOtherPasteMethodPasting;
//    end else begin
//        FrmMainPopup.SetOtherPasteMethodClipboardOnly;
//    end;

    if rbTyping.checked then
        Paste.SetMimicTyping;

    if rbClipboardOnly.checked then
        Paste.SetClipboardOnly;

    if rbPaste.Checked then
        Paste.SetUsePaste;
    if rbPasteSI.Checked then
        Paste.SetUsePasteSI;

    lblKeyname.Caption := self.GetHumanReadableHotkey;
    //lblTooltipKeyname.Caption := self.GetHumanReadableTTHotkey;
    //lblPreviousTooltipKeyname.Caption := self.GetHumanReadablePTTHotkey;
    lblPlaintext.Caption := self.getHumanReadablePlaintextHotkey;

    // ----------------
    // Trigger Window
    // ----------------


    tbdelay.Position := ini.ReadInteger(ArsClip, tbDelay.name, 50);
    sbtop.down := ini.Readbool(ArsClip, sbtop.name, false);
    sbbottom.down := ini.Readbool(ArsClip, sbbottom.name, false);
    sbleft.down := ini.Readbool(ArsClip, sbleft.name, false);
    sbright.down := ini.Readbool(ArsClip, sbright.name, true);
    sbtopleft.down := ini.Readbool(ArsClip, sbtopleft.name, false);
    sbtopright.down := ini.Readbool(ArsClip, sbtopright.name, false);
    sbbottomleft.down := ini.Readbool(ArsClip, sbbottomleft.name, false);
    sbbottomright.down := ini.Readbool(ArsClip, sbbottomright.name, false);
    tbTriggerThickness.Position := ini.ReadInteger(ArsClip, tbTriggerThickness.Name, tbTriggerThickness.Position);
    cbTriggerWindow.Checked := ini.ReadBool(ArsClip, cbTriggerWindow.Name, false);

    // JumpList
    cbxClickedAction.ItemIndex := ini.ReadInteger(ArsClip, cbxClickedAction.Name, 0);

    //
    // Clipboard Bar
    //

    cbShowPopupWhenClicked.checked := ini.ReadBool(ArsClip, cbShowPopupWhenClicked.name, true);
    cbShowTooltipOnHover.checked := ini.ReadBool(ArsClip, cbShowTooltipOnHover.name, false);
    udNormalOpacity.Position := ini.ReadInteger(ArsClip, udNormalOpacity.Name, 255);


    btnBarTop.down := ini.Readbool(ArsClip, btnBarTop.name, btnBarTop.down);
    btnBarTopRight.down := ini.Readbool(ArsClip, btnBarTopRight.name, btnBarTopRight.down);
    btnBarTopLeft.down := ini.Readbool(ArsClip, btnBarTopLeft.name, btnBarTopLeft.down);
    btnBarLeft.down := ini.Readbool(ArsClip, btnBarLeft.name, btnBarLeft.down);
    btnBarRight.down := ini.Readbool(ArsClip, btnBarRight.name, btnBarRight.down);
    btnBarBottom.down := ini.Readbool(ArsClip, btnBarBottom.name, btnBarBottom.down);
    btnBarBottomLeft.down := ini.Readbool(ArsClip, btnBarBottomLeft.name, btnBarBottomLeft.down);
    btnBarBottomRight.down := ini.Readbool(ArsClip, btnBarBottomRight.name, btnBarBottomRight.down);

    cbBarSnapToScreen.Checked := ini.ReadBool(ArsClip, cbBarSnapToScreen.Name, cbBarSnapToScreen.Checked);
    cbClipboardBarVirtualDesktop.Checked := ini.ReadBool(ArsClip, cbClipboardBarVirtualDesktop.name, cbClipboardBarVirtualDesktop.checked);


    //
    // Sound
    //

    self.Sound_NewClip := ini.ReadString('Sound','NewClip','c:\Windows\Media\chimes.wav');

    //
    // Etc - non controls
    //

    self.RightclickTriggerWarned := ini.ReadBool(ArsClip, 'RightclickTriggerWarned', false);
    self.PasteDelay := ini.ReadInteger(ArsClip,'PasteDelay', 10);
    self.ClipboardBarVisible := ini.ReadBool(arsclip, 'ClipboardBarVisible', false);

    cbxMode.ItemIndex := ini.ReadInteger(ArsClip, cbxMode.Name, cbxMode.ItemIndex);
    cbxMode.OnChange(self); // trigger change event

    HandleHidden;


    if i=0 then begin
        frmMainPopup.timAutoSave.Enabled := false;
    end else begin
        frmMainPopup.timAutoSave.Interval := i;
    end;

    MyFree(ini);

    FrmDebug.AppendLog('HotkeyLoad - end :=FrmConfig.lvOrder.items.Count=' + IntToStr(FrmConfig.lvOrder.items.Count));
    finally
        isLoading := false;
    end;
end;
{
--============================
-- // Load/Save hotkey info //
--============================
}

function SelectedIsDefault : boolean;
begin
	result := true;
    if frmconfig.lvprograms.selected = nil then EXIT;
	result := (frmconfig.cbxPasteMethod.ItemIndex = 4) and
    	not frmconfig.cbDisableMonitoring.checked and
        not frmconfig.cbDisableTrigger.checked and
        not frmconfig.cbExplorerCompat.Checked;
end;

procedure TFrmConfig.SaveLastPermPath;
var ini: TInifile;

begin
    ini := TInifile.Create( self.GetINIFileName );

    ini.WriteString(ArsClip, 'LastPermanentPath', frmPermanent.GetPermanentPath);

    MyFree(ini);
end;


procedure TFrmConfig.SaveClipboardBarPosition;
var
    ini : TIniFile;
    x,y,width,height : integer;
begin
    ini := TInifile.Create( self.GetINIFileName );
    ini.WriteBool(ArsClip, 'ClipboardBarVisible', frmClipboardBar.isvisible);
    frmClipboardBar.GetSizePos(x,y,width,height);

    ini.writeinteger(ArsClip, 'ClipboardBarX', x);
    ini.writeinteger(ArsClip, 'ClipboardBarY', y);
    ini.writeinteger(ArsClip, 'ClipboardBarWidth', width);
    ini.writeinteger(ArsClip, 'ClipboardBarHeight', height);
    myfree(ini);
end;
procedure TFrmConfig.SaveClipboardBarState;
var ini : TIniFile;
    x,y,width,height : integer;
begin
    ini := TInifile.Create( self.GetINIFileName );

    ini.WriteBool(ArsClip, 'ClipboardBarVisible', frmClipboardBar.isvisible);

    if not visibleOnly then begin
//    if frmClipboardBar.isvisible then begin
        frmClipboardBar.GetSizePos(x,y,width,height);

        ini.writeinteger(ArsClip, 'ClipboardBarX', x);
        ini.writeinteger(ArsClip, 'ClipboardBarY', y);
        ini.writeinteger(ArsClip, 'ClipboardBarWidth', width);
        ini.writeinteger(ArsClip, 'ClipboardBarHeight', height);
        ini.writebool(ArsClip, 'ClipboardBarCaption', false);

        ini.WriteBool(ArsClip, 'ClipboardBarCompactWhitespace', frmClipboardBar.CompactWhitespace1.Checked);
        ini.WriteBool(ArsClip, 'ClipboardBarSmallFont', frmClipboardBar.SmallFont1.Checked);
        ini.WriteBool(ArsClip, 'ClipboardBarMediumFont', frmClipboardBar.MediumFont1.Checked);
        ini.WriteBool(ArsClip, 'ClipboardBarLargeFont', frmClipboardBar.LargeFont1.Checked);

        ini.WriteBool(ArsClip, 'ClipboardBarToolbar', frmClipboardBar.pnlToolbar.Visible);
    end;


    MyFree(ini);
end;
procedure TFrmConfig.LoadClipboardBarState;
var ini : TIniFile;
    x,y,width,height : integer;
    b : boolean;
begin
    ini := TInifile.Create( self.GetINIFileName );
    height := 80; width := 150;
    b := ini.ReadBool(ArsClip, 'ClipboardBarVisible', true);

    frmClipboardBar.pnlToolbar.Visible := ini.ReadBool(ArsClip, 'ClipboardBarToolbar', false);

    x := ini.readinteger(ArsClip, 'ClipboardBarX', 0);
    y := ini.readinteger(ArsClip, 'ClipboardBarY', 0);
    width := ini.readinteger(ArsClip, 'ClipboardBarWidth', width);
    height := ini.readInteger(ArsClip, 'ClipboardBarHeight', height);
    frmClipboardBar.SetSizePos(x,y,width,height);

    frmClipboardBar.CompactWhitespace1.Checked := ini.ReadBool(ArsClip, 'ClipboardBarCompactWhitespace', false);
    frmClipboardBar.SmallFont1.Checked := ini.ReadBool(ArsClip, 'ClipboardBarSmallFont', false);
    frmClipboardBar.MediumFont1.Checked := ini.ReadBool(ArsClip, 'ClipboardBarMediumFont', true);
    frmClipboardBar.LargeFont1.Checked := ini.ReadBool(ArsClip, 'ClipboardBarLargeFont', false);

    frmClipboardBar.NormalOpacity := udNormalOpacity.Position;

    if b then frmClipboardBar.SetVisible(true, false);
    MyFree(ini);
end;

procedure TFrmConfig.lblHotkeyClick(Sender: TObject);
begin
    pcPanels.ActivePageIndex := tsHotkey.PageIndex;
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;
procedure TFrmConfig.lblShowOptionsClick(Sender: TObject);
begin
    pcPanels.ActivePageIndex := tsShowOptions.PageIndex;
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;
procedure TFrmConfig.lblTriggerWindowClick(Sender: TObject);
begin
   pcPanels.ActivePageIndex := tsTriggerWindow.PageIndex;
   tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;
procedure TFrmConfig.lblJumpListClick(Sender: TObject);
begin
   pcPanels.ActivePageIndex := tsJumplist.PageIndex;
   tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;
procedure TFrmConfig.lblClipboardBarClick(Sender: TObject);
begin
    pcPanels.ActivePageIndex := tsClipboardBar.PageIndex;
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;

procedure TFrmConfig.lblClipSetClick(Sender: TObject);
begin
try
    pcPanels.ActivePageIndex := tsClipSets.PageIndex;
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
except
end;
end;

procedure TFrmConfig.lblHotkeyAlternativesClick(Sender: TObject);
begin
    pcPanels.ActivePageIndex := tsHotkeyAlternatives.PageIndex;
   tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];
end;

procedure TFrmConfig.lbMenuOrderClick(Sender: TObject);
begin
    tvOptions.Selected := tvOptions.Items[ tsmenuorder.pageIndex];
end;
procedure TFrmConfig.sbBottomClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := true;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbbottomleftClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := true;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbbottomrightClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := true;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbEditPermanentClipsClick(Sender: TObject);
begin
    frmSysTrayMenu.PermanentClipsMenuItemClickEvent(sender);
end;
procedure TFrmConfig.sbLeftClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := true;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbRightClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := true;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := false;

    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;

end;
procedure TFrmConfig.sbTopClick(Sender: TObject);
begin
    sbTop.Down := true;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbtopleftClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := true;
    sbtopright.down := false;
    sbbottomleft.down := false;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
procedure TFrmConfig.sbtoprightClick(Sender: TObject);
begin
    sbTop.Down := false;
    sbBottom.Down := false;
    sbLeft.Down := false;
    sbright.down := false;
    sbtopleft.down := false;
    sbtopright.down := true;
    sbbottomleft.down := false;
    sbbottomright.down := false;
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;

end;

procedure TFrmConfig.SetRightclickTriggerWarned;
begin
    self.RightclickTriggerWarned := true;
    self.HotkeySave;
end;

procedure TFrmConfig.ForceOldTrayPopup;
begin
    self.OldTrayPopup := true;
end;

procedure TFrmConfig.lvFormatsClick(Sender: TObject);
begin
    btnFormatUp.Enabled := lvFormats.ItemIndex <> -1;
    btnFormatDown.Enabled := btnFormatUp.Enabled;
end;



procedure TFrmConfig.lvOrderChange(Sender: TObject; Item: TListItem;  Change: TItemChange);
begin
	self.UpdatePreview;
end;
procedure TFrmConfig.lvOrderClick(Sender: TObject);
begin
    btnToggle.Enabled := lvOrder.ItemIndex <> -1;
    btnMenuUp.Enabled := btnToggle.Enabled;
    btnMenuDown.Enabled := btnToggle.Enabled;
end;
procedure TFrmConfig.lvOrderInfoTip(Sender: TObject; Item: TListItem; var InfoTip: string);
begin
    InfoTip := MenuOrderText(TMenuOrderType(item.Data), true);
end;

function TFrmConfig.MenuOrderText(m: TMenuOrderType; description:boolean): string;
begin
    if description then begin
        case m of
            MOT_MENU:result := 'Popup Clip history';
            MOT_OTHER:result := 'Non-Text Clip history';
            MOT_CANCEL:result := 'Closes the popup';
            MOT_LAST:result := 'Last clicked text item on popup';
            MOT_CURRENT:result := 'Current clipboard''s contents';
            MOT_REMOVED:result := 'Submenu of Clips recently removed from the list';
            MOT_PROGRAM: result := 'Custom options for the current target program';
            MOT_SYSTEM:result := 'ArsClip''s System Options menu';
            MOT_PASTEUTILS:   result := 'Misc items menu';
            MOT_PERMANENT:result := 'Clips in the current Permanent Group';
            MOT_SWITCH:result := 'Switches to another Permanent Group';
            MOT_FULL: result := 'Switches between Full/Configured Mode';
            MOT_ALLPERMANENT: result := 'A submenu of All Permanent Clips and Groups';
            MOT_SELECTED: result := 'Edit the selected text in the current window';
            MOT_CLICKED: result := 'Submenu of Clips recently clicked on';
            MOT_SEARCH: result := 'Search all text Clips ';
            MOT_BREAK: result := 'Creates a new Column';
        end;
    end else begin
        case m of
            MOT_MENU:result := 'Popup Clips';
            MOT_OTHER:result := 'Non-Text';
            MOT_CANCEL:result := 'Cancel';
            MOT_LAST:result := 'Last:';
            MOT_CURRENT:result := '[Clipboard]:';
            MOT_REMOVED:result := 'Recently Removed';
            MOT_PROGRAM: result := 'Program Options';
            MOT_SYSTEM:result := 'System';
            MOT_PASTEUTILS:   result := 'Pasting Tools';
            MOT_PERMANENT:result := 'Current Permanent Clips';
            MOT_SWITCH:result := 'Permanent Groups Switch';
            MOT_FULL: result := 'Show More/Less';
            MOT_ALLPERMANENT: result := 'All Permanent';
            MOT_SELECTED : result := 'Edit Selected:';
            MOT_CLICKED: result := 'Recently Clicked';
            MOT_SEARCH: result := 'Search and Paste ...';
            MOT_BREAK: result := '(Column Break)';
        end;
    end;
end;




procedure TFrmConfig.MoveItem(x, before: TMenuOrderType);
var li1, li2 : TListItem;
begin
    FrmDebug.AppendLog('FrmConfig - MoveItem');
	self.HotkeyLoad;
	li1 := lvorder.FindCaption(0,self.MenuOrderText(TMenuOrderType(x),false),false,true,false);
    li2 := lvorder.FindCaption(0,self.MenuOrderText(TMenuOrderType(before),false),false,true,false);
    if (li1 <> nil) and (li2 <> nil) then begin

    	MoveListViewItem2(lvorder, lvorder.items.IndexOf(li1), lvorder.items.IndexOf(li2));
        self.HotkeySave;
    end;
end;

procedure TFrmConfig.Panel8Click(Sender: TObject);
begin
   frmMainPopup.Visible := frmMainPopup.Visible xor true;
end;
procedure TFrmConfig.pcPanelsChange(Sender: TObject);
begin
    tvOptions.Selected := tvOptions.Items[pcPanels.ActivePageIndex];

end;


procedure TFrmConfig.pnlColorClick(Sender: TObject);
var p : TPanel;
begin
    p := TPanel(Sender);
    ColorDialog1.Color := p.Color;
    if ColorDialog1.Execute( p.Handle ) then begin
        p.Color := ColorDialog1.Color;
    end;

    self.UpdatePreview(sender);
    UpdateColorExample;
end;

procedure TFrmConfig.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
    if (KEY = VK_ESCAPE) then begin
        self.btnCancel.Click;
    end;
end;



//============================
// Clipboard Options
//============================
procedure TFrmConfig.UpdatePreview(Sender : TObject=nil);
begin
	if self.Visible then begin
    	timUpdatePreview.Enabled := false;
		timUpdatePreview.Enabled := true;
    end;
end;



procedure TFrmConfig.cbUseKeyboardClick(Sender: TObject);
begin
//    frmMainPopup.setpopupusekeyboard(cbUseKeyboard.Checked);
    self.UpdatePreview;
end;
procedure TFrmConfig.cbUseVirtualDesktopMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
    if cbTriggerWindow.checked then begin
        FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.prEnable := true;
    end;
end;
{
Make the user use the up/down to change the queue size
}
procedure TFrmConfig.txtPopupClipQueueSizeKeyPress(Sender: TObject; var Key: Char);
begin
    // ignore keystrokes
    key := chr(0);
end;
procedure TFrmConfig.txtOldHistorySizeKeyPress(Sender: TObject;  var Key: Char);
begin
    // ignore keystrokes
    Key := Chr(0);
end;
procedure TFrmConfig.txtOtherSizeKeyPress(Sender: TObject; var Key: Char);
begin
    key := chr(0);
end;
procedure TFrmConfig.txtOtherSizeLimitKBChange(Sender: TObject);
var limit : integer;
begin
    limit := StrToInt(FrmConfig.txtOtherSizeLimitKB.text) * 1024;

    cbDontCopy.Checked := limit <> 0;
    OtherQueue.SetClipSizeLimit( limit );
end;
procedure TFrmConfig.udQueueSizeXClick(Sender: TObject; Button: TUDBtnType);
begin
    ClipQueue.SetQueueSize(udQueueSize.position);
end;
procedure TFrmConfig.udRemovedSizeXClick(Sender: TObject; Button: TUDBtnType);
begin
    //RemovedQueue.SetQueueSize(udRemovedSize.position);
end;
procedure TFrmConfig.cbDisableClick(Sender: TObject);
begin
    if assigned(frmClipboardManager) then
        frmClipboardManager.SetDisableMonitoring(cbdisable.Checked);
end;
procedure TFrmConfig.cbMonitorFilenamesClick(Sender: TObject);
begin
    frmClipboardManager.SetFilenameMonitoring(cbMonitorFilenames.checked);
end;
procedure TFrmConfig.cbRememberClick(Sender: TObject);
begin
    frmMainPopup.SetRememberHistory(cbRemember.checked);
    // this loads only the first time

    if (cbRemember.Checked) then begin
        frmClipboardManager.LoadHistory(False);

    end;
end;
procedure TFrmConfig.cbRightTriggerEnableClick(Sender: TObject);
begin
    if cbRightTriggerEnable.checked then begin
        frmmainpopup.timMouseHeld.Enabled := true;
    end else begin
        frmmainpopup.timMouseHeld.Enabled := false;
    end;
end;
procedure TFrmConfig.cbBarSnapToScreenClick(Sender: TObject);
begin
    if cbBarSnapToScreen.Checked then
        frmClipboardBar.SnapToScreen;
end;

procedure TFrmConfig.cbxIconTypeClick(Sender: TObject);
begin
    frmClipboardManager.SetCopyIcon(cbxIconType.ItemIndex=0);
    self.UpdatePreview;
end;
procedure TFrmConfig.cbCopyIconsxClick(Sender: TObject);
begin
//    frmClipboardManager.SetCopyIcon(cbCopyIcons.Checked);
//    self.UpdatePreview;
end;
procedure TFrmConfig.cbMoveDuplicateClick(Sender: TObject);
begin
    ClipQueue.SetMoveDuplicateTop(cbMoveDuplicate.checked);
end;
procedure TFrmConfig.cbShowEditHistoryClick(Sender: TObject);
begin
    //FrmMainPopup.SetShowEditHistory(cbShowEditHistory.checked);
end;
procedure TFrmConfig.btnEditPermanentItemsClick(Sender: TObject);
begin
    frmEditHistory.ShowPermanent;
end;
procedure TFrmConfig.rbTypingClick(Sender: TObject);
begin
    Paste.SetMimicTyping;
end;
procedure TFrmConfig.rbPasteClick(Sender: TObject);
begin
    Paste.SetUsePaste;
end;
procedure TFrmConfig.rbPasteSIClick(Sender: TObject);
begin
    Paste.SetUsePasteSI;
end;


procedure TFrmConfig.rbClipboardOnlyClick(Sender: TObject);
begin
    Paste.SetClipboardOnly;
end;
procedure TFrmConfig.cbMoveFirstClick(Sender: TObject);
begin

end;
//
// close/save/cancel
// TreeView clicks
//
procedure TFrmConfig.btnSaveClick(Sender: TObject);
begin
    self.HotkeySave;

    if (cbGlobalClipboard.Checked) then begin
        TGlobalClipboard.JoinInstancePool;
    end else begin
        TGlobalClipboard.LeaveInstancePool;
    end;

    try
        if HotKeyPopup = nil then begin
            try
                HotKeyPopup := TACHotKey.Create(
                    FrmMainPopup.Handle, 'ArsClip.HotkeyPopup',
                    Hotkey_Ctrl, Hotkey_Alt,
                    Hotkey_Shift, Hotkey_Winkey, Hotkey_key);
            except
                // if it wasn't already created, this save is likely
                // generating the same error as when the program started
                // -- ignore here
            end;

        end else begin
            HotKeyPopup.SetHotKey(Hotkey_Ctrl, Hotkey_Alt,
                Hotkey_Shift, Hotkey_Winkey, Hotkey_key);
        end;

        if PlainTextHotKey = nil then begin
            try
                PlainTextHotKey := TACHotKey.Create(
                    FrmMainPopup.Handle, 'ArsClip.PlainTextHotKey',
                    PlainTextData.Ctrl, PlainTextData.Alt,
                    PlainTextData.Shft, PlainTextData.Win, PlainTextData.key);
            except

            end;

        end else begin
            PlainTextHotKey.SetHotKey(PlainTextData.Ctrl, PlainTextData.Alt,
                PlainTextData.Shft, PlainTextData.Win, PlainTextData.key);
        end;
    except
        //EXIT;
    end;
    {if (self.SetHotKey) then begin}
        self.close;
    {end;}
end;
procedure TFrmConfig.btnShowDebugClick(Sender: TObject);
begin
    FrmDebug.Visible := true;
end;

procedure TFrmConfig.btnSoundBrowseClick(Sender: TObject);
var ini : TInifile;

begin
    odSound.InitialDir := 'C:\Windows\media';
    odSound.Filter :=  'Wave files (*.wav)|*.WAV';
    if odSound.Execute(self.Handle) then begin
        //PlaySound_SetWavefile(odSound.FileName);

        ini := TInifile.Create( self.GetINIFileName );
        self.Sound_NewClip := odSound.Filename;
        myfree(ini);
    end;
end;
procedure TFrmConfig.btnSystemClipsClick(Sender: TObject);
begin
//    FrmPermanent.ShowAndSelectSystem;
    frmEditHistory.ShowPermanentSystem;
    self.Hide;
end;

procedure TFrmConfig.btnTestClick(Sender: TObject);
begin
    //UnitSound.PlaySound_NewClipboardItem;
    UnitSound.PlaySound_PlayFile(self.Sound_NewClip);

end;
procedure TFrmConfig.btnToggleClick(Sender: TObject);
var li : TListITem;
begin
	timUpdatePreview.Enabled := false;
    timUpdatePreview.Enabled := true;
    li := lvOrder.Selected;
    if li <> nil then begin
        if li.SubItems[0] = 'Yes' then
         li.SubItems[0] := 'no'
        else
         li.SubItems[0] := 'Yes';

    end;
end;
procedure TFrmConfig.btnAddNameClick(Sender: TObject);
var s : string;
	li : TListITem;
begin
	if InputQuery('Add Executable','Enter the name in "filename.exe" format',s) then begin
        li := lvprograms.Items.Add;
        li.Caption := s;
        li.ImageIndex := -1;
    end;
end;


{Clipboard Bar Snap Positions}
procedure TFrmConfig.ResetClipboardBarButtons;
begin
    btnBarTopLeft.Down := false;
    btnBarLeft.Down := false;
    btnBarBottomLeft.Down := false;
    btnBarBottom.Down := false;
    btnBarTop.Down := false;
    btnBarTopRight.Down := false;
    btnBarRight.Down := false;
    btnBarBottomRight.Down := false;
    frmClipboardBar.SnapToScreen;
end;
procedure TFrmConfig.btnBarBottomClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarBottomLeftClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarBottomRightClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarLeftClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarRightClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarTopClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarTopLeftClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.btnBarTopRightClick(Sender: TObject);
begin
    self.ResetClipboardBarButtons;
end;
procedure TFrmConfig.cbClipboardBarVirtualDesktopClick(Sender: TObject);
begin
    if cbBarSnapToScreen.Checked then
        frmClipboardBar.SnapToScreen;
end;



procedure TFrmConfig.btnCancelClick(Sender: TObject);
begin
    self.Close;
end;



{Routines for customzing the TTreeView}
procedure TFrmConfig.tvOptionsChange(Sender: TObject; Node: TTreeNode);
var i : integer;
    ts : TTabSheet;
begin
    //self.ShowNewPanel;
    if (basicnodes<>nil) and (tvOptions.Items.Count = basicNodes.Count) then begin
        pcPanels.ActivePageIndex := Integer(tvOptions.Selected.Data);
    end else begin
        pcPanels.ActivePageIndex := (tvOptions.Selected.AbsoluteIndex);
    end;
    ts := pcPanels.Pages[pcPanels.ActivePageIndex];
    for i := 0 to ts.ControlCount-1 do begin
        if ts.Controls[i] is TCategoryPanelGroup then begin
            CurrentCPG := TCategoryPanelGroup(ts.Controls[i]);
        end;
    end;
end;
procedure TFrmConfig.tvOptionsChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
begin
    if tvOptions.Selected = nil then EXIT;

    if node.HasChildren and
        node.Expanded and
        (node <> tvOptions.Selected) then begin
        dontcollapse := true;
    end;
end;
procedure TFrmConfig.tvOptionsClick(Sender: TObject);
var tn : TTreeNode;
begin
    tn := tvOptions.Selected;
    if tn <> nil then begin
        self.OnMouseUp(sender, mbLeft,[ssShift],0,0)
    end;


end;
procedure TFrmConfig.tvOptionsCollapsing(Sender: TObject; Node: TTreeNode; var AllowCollapse: Boolean);
begin
    AllowCollapse := false;
    if nocollapse then begin
        EXIT;
    end;
    if ignorecollapse then begin
        AllowCollapse := true;
        EXIT;
    end;

    if dontcollapse then begin
        dontcollapse := false;
        EXIT;
    end;

    AllowCollapse := false;
    if tvOptions.Selected <> nil then begin
        if tvOptions.Selected = node then
            AllowCollapse := tvOptions.Selected.HasChildren
        {and (tvOptions.selected <> node)};
    end;
end;
procedure TFrmConfig.tvOptionsCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var r : TRect;
    ico : TIcon;
    CaptionLeft : integer;
    bm, bm2 : TBitmap;
    BlendFunc: TBlendFunction;
const INDENT = 8;
    procedure CalculateCaptionLeft;
    begin
        r := node.DisplayRect(false);
        CaptionLeft := r.left + TTreeView(sender).Images.Width+5;
    end;
    procedure EraseBackground;
    begin
        r := node.DisplayRect(false);
        sender.Canvas.Brush.Color := clWhite;
        sender.Canvas.pen.Color := clWhite;
        sender.Canvas.Rectangle(r);
    end;
    procedure BackgroundColor;
    begin
        sender.canvas.brush.Color := clWhite;
        if (node.Parent=nil) then
            sender.canvas.brush.Color := dimcolor(sender.canvas.brush.Color,0.98);
        if (cdsFocused in state) or
            (cdsHot in state) or
            (cdsSelected in state)  then begin
            if (cdsHot in state) then begin
                sender.canvas.brush.Color :=
                    blend(clHighlight,clwhite,70);
            end else begin
                sender.canvas.brush.Color := blend(
                    blend(cl3DLight,clHighlight,95),
                    clWhite,
                    85
                );
            end;
            if (cdsHot in state)  then begin
            end else begin
                sender.Canvas.font.color := ColorToRGB(clBtnText);
            end;
        end;
    end;
    procedure Highlight;
    begin
        r := node.DisplayRect(false);
        if (node.Parent<>nil) then begin
            r.Left := CaptionLeft;
        end;
        sender.Canvas.FillRect(r);
        if (cdsHot in state) then begin
            inc(r.Top);
            inc(r.Bottom);
            GradientFillCanvas(
                sender.Canvas,
                blend(sender.Canvas.Brush.color,clWhite,10),
                sender.Canvas.Brush.color,
                r,gdVertical
            );
        end;
    end;
    procedure RootDecoration;
    begin
        r := node.DisplayRect(false);
        if (node.Parent = nil) and not (cdsHot in state) then begin
            inc(r.Top);
            //inc(r.Bottom);
            r.left := r.right - (r.Right-r.Left) div 14;
            GradientFillCanvas(
                sender.Canvas,sender.Canvas.Brush.color,
                DimColorOrReverse(sender.Canvas.Brush.color,0.975),
                r,gdHorizontal
            );
        end;
        r := node.DisplayRect(false);
        if (node.Parent = nil) then begin

            sender.Canvas.Pen.Color := Blend(clBtnText,clWhite, 20);
            sender.Canvas.MoveTo(r.Left,r.Bottom-1);
            sender.Canvas.LineTo(r.right,r.Bottom-1);

            if sender.Selected = node then begin
                ico := TIcon.Create;
                TTreeView(sender).images.GetIcon(node.ImageIndex, ico);
                sender.Canvas.Draw(0,r.Top+1, ico);
                myfree(ico);
            end else begin
                bm := TBitmap.Create;
                bm.PixelFormat := pf24bit;
                bm.Width := 16;
                bm.Height := 16;
                bm.TransparentColor := clnone;
                bm.Canvas.Brush.Color := sender.Canvas.Brush.Color;
                bm.Canvas.FillRect(bm.Canvas.ClipRect);

                ico := TIcon.Create;
                TTreeView(sender).images.GetIcon(node.ImageIndex, ico);
                bm.Canvas.Draw(0,0, ico);
                myfree(ico);

                UnitMisc.ToGrayscale(bm,bm.TransparentColor);

                BlendFunc.BlendOp := AC_SRC_OVER;
                BlendFunc.BlendFlags := 0;
                BlendFunc.SourceConstantAlpha := 100;
                BlendFunc.AlphaFormat := 0;
                Windows.AlphaBlend(sender.Canvas.Handle, r.left,r.top+1, 16,16, bm.Canvas.Handle,
                    0,0, 16,16, BlendFunc);
                myfree(bm);
            end;
        end;
    end;
begin
    defaultdraw := true;
    if not assigned(TTreeView(sender).images) then EXIT;
    DefaultDraw := false;


    EraseBackground;
    CalculateCaptionLeft;
    BackgroundColor;
    Highlight;
    sender.Canvas.font.color := ColorToRGB(clBtnText);
    RootDecoration;

    r := node.DisplayRect(false);
    if (node.Parent <> nil) then begin
        dec(CaptionLeft,3);
        ico := TIcon.Create;
        TTreeView(sender).images.GetIcon(node.ImageIndex, ico);
        sender.Canvas.Draw(CaptionLeft,r.Top+1, ico);
        myfree(ico);

        CaptionLeft := CaptionLeft + TTreeView(sender).Images.Width+5
    end;

    sender.Canvas.Brush.Style := bsClear;
    SetBkMode(sender.Canvas.Handle, TRANSPARENT) ;

    sender.Canvas.TextOut(CaptionLeft, r.top+2, node.Text);

end;
procedure TFrmConfig.tvOptionsExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean);
begin
    AllowExpansion := true;

    if ignoreexpand then EXIT;

    if node.Parent = nil then begin
        if tvOptions.Selected = node then begin
            self.ignorecollapse := true;
            tvOptions.FullCollapse;
            self.ignorecollapse := false;
        end;
    end;
end;
procedure TFrmConfig.bEditPopupHotkeyClick(Sender: TObject);
var w : word;
    s : string;
    ha, hs, hc, hw : boolean;
begin
    if FrmHotkey.GetHotkey( ha, hs ,hc , hw, w, s) then begin
       Hotkey_Alt    := ha;
       Hotkey_Shift  := hs;
       Hotkey_Ctrl   := hc;
       Hotkey_Winkey := hw;
       Hotkey_Key    := w;
       lblKeyname.caption := s;
    end;
end;
procedure TFrmConfig.btnEditPlaintextHotkeyClick(Sender: TObject);
var w : word;
    s : string;
    ha, hs, hc, hw : boolean;
begin
    if FrmHotkey.GetHotkey( ha, hs ,hc , hw, w, s) then begin
       PlainTextData.Alt    := ha;
       PlainTextData.Shft   := hs;
       PlainTextData.Ctrl   := hc;
       PlainTextData.Win    := hw;
       PlainTextData.Key    := w;
       lblPlaintext.caption := s;
    end;
end;
procedure TFrmConfig.btnClearPlaintextClick(Sender: TObject);
begin
    lblPlaintext.Caption := 'none';
    PlainTextData.key := 0;
end;


procedure TFrmConfig.btnEditPopupClipsClick(Sender: TObject);
begin
    frmSysTrayMenu.EditHistoryMenuItemClickEvent(sender); 
end;

{Clipboard > Execute Permanent Clip}
procedure TFrmConfig.btnPermClipsClick(Sender: TObject);
begin
    UnitMisc.ShowPopupRight(TControl(sender), pmPermClips);
end;
procedure TFrmConfig.btnPinClick(Sender: TObject);
begin
    FrmDummyShellForm.PinSelfToTaskbar;
end;

procedure TFrmConfig.pmPermClipsPopup(Sender: TObject);
var
    i, j : integer;
    mi : TMenuItem;
    submi : TMenuItem;
    sl : TStringList;
begin
    pmPermClips.Items.Clear;
    mi := TMenuItem.Create(pmPermClips);
    mi.Caption := '[none]';
    mi.hint := '';
    mi.OnClick := PermClipClick;
    pmPermClips.Items.Add(mi);

    sl := TStringList.Create;
    for i := 0 to FrmPermanent.PermFoldersGetCount-1 do begin
        mi := TMenuItem.Create(pmPermClips);
        mi.Caption := FrmPermanent.PermFoldersGetItem(i);
        mi.Enabled := false;

        sl.Clear;
        TClipDatabase.LoadPermanentNames(sl, mi.Caption);
        for j := 0 to sl.Count-1 do begin
            submi := TMenuItem.Create(pmPermClips);
            submi.Caption := sl[j];
            submi.Hint := mi.Caption;
            submi.OnClick := PermClipClick;
            mi.Enabled := true;
            mi.Add(submi);
        end;

        pmPermClips.Items.Add(mi);
    end;

end;
procedure TFrmConfig.PermClipClick(Sender : TObject);
begin
end;

procedure TFrmConfig.btnPreviewClick(Sender: TObject);

begin
    frmPreviewPopup.top := self.top;
    frmPreviewPopup.Left := self.Left+self.width;
    if not frmPreviewPopup.Visible  then
    	frmPreviewPopup.Show;
    frmPreviewPopup.UpdatePreview;
end;


procedure TFrmConfig.btnRemovedClipsClick(Sender: TObject);
begin
    frmSysTrayMenu.RemovedItemsMenuItemClickEvent(sender);
end;
procedure TFrmConfig.cbDisableWatcherClick(Sender: TObject);
begin
    if FrmChainWatcher <> nil then begin
        FrmChainWatcher.PermanentDisable(cbDisableWatcher.checked);
    end;
end;
procedure TFrmConfig.cbDisableWhenScrollLockClick(Sender: TObject);
begin
    frmClipboardManager.SetDisableWhenScrollLock(cbDisableWhenScrollLock.checked);
end;
procedure TFrmConfig.cbDontCopyClick(Sender: TObject);
begin
    if cbDontCopy.checked then begin
        if strtoint(txtOtherSizeLimitKB.Text) = 0 then
            txtOtherSizeLimitKB.Text := '500';
    end else begin
        txtOtherSizeLimitKB.Text := '0';
    end;
end;
procedure TFrmConfig.cbEnableClipboardBarMouseUp(Sender: TObject;  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
    frmClipboardBar.SetVisible(cbEnableClipboardBar.checked);
end;
procedure TFrmConfig.cbEnableSoundClick(Sender: TObject);
begin
    btnSoundBrowse.Enabled := false;
    btnTest.Enabled := false;
    if cbEnableSound.Checked then begin
        PlaySound_Init;
        btnSoundBrowse.Enabled := true;
        btnTest.Enabled := true;
    end else begin
        PlaySound_Remove;
        //self.Sound_NewClip := '';
    end;
end;


procedure TFrmConfig.cbFullModeClick(Sender: TObject);
begin
	if self.Visible then begin
    	timUpdatePreview.Enabled := false;
		timUpdatePreview.Enabled := true;
    end;
end;
//
// Per-program Options
//
procedure TFrmConfig.lvProgramsClick(Sender: TObject);
var exename : string;
    procedure SetEnabled(selected : boolean);
    begin
        cbxPasteMethod.Enabled := Selected;
        cbDisableTrigger.Enabled := Selected;
        cbDisableMonitoring.Enabled := Selected;
        cbExplorerCompat.Enabled := Selected;
        rbProgramPaste.Enabled := Selected;
        rbProgramMacro.Enabled := Selected;
        btnProgramCustomScript.Enabled := Selected;
    end;
var i : integer;
begin
    if lvPrograms.Selected = nil then begin
        SetEnabled(false);
        EXIT;
    end;
    SetEnabled(true);
    exename := lvPrograms.selected.caption;
    i := Integer(Paste.GetPasteMethod( exename ));
    cbxPasteMethod.ItemIndex := i;
    cbDisableTrigger.checked :=  FrmSysTrayMenu.IsNoRightClickEXE( ExeName );
    cbDisableMonitoring.checked := FrmSysTrayMenu.IsDisabledEXE( ExeName );
    cbExplorerCompat.checked := frmSysTrayMenu.IsExplorerCompatEXE( exename );

    rbProgramPaste.Checked := i<>integer(PASTE_PROGRAMCUSTOMMACRO);
    rbProgramMacro.Checked := not rbProgramPaste.Checked;
end;
procedure TFrmConfig.cbExplorerCompatClick(Sender: TObject);
var s : string;
begin
    s := lvPrograms.Selected.Caption;
    lvPrograms.Selected.ImageIndex := 5;

    frmSysTrayMenu.ToggleExplorerCompatEXE(s);
    cbExplorerCompat.Checked := frmSysTrayMenu.IsExplorerCompatEXE(s);

    if SelectedIsDefault then lvPrograms.Selected.ImageIndex := -1;
end;
procedure TFrmConfig.cbExplorerCompatMouseUp(Sender: TObject;  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var s : string;
begin
    s := lvPrograms.Selected.Caption;
    lvPrograms.Selected.ImageIndex := 5;

    frmSysTrayMenu.ToggleExplorerCompatEXE(s);
    cbExplorerCompat.Checked := frmSysTrayMenu.IsExplorerCompatEXE(s);

    if SelectedIsDefault then lvPrograms.Selected.ImageIndex := -1;
end;


procedure TFrmConfig.cbDisableTriggerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var s : string;
begin
    s := lvPrograms.Selected.Caption;
    lvPrograms.Selected.ImageIndex := 5;

    frmSysTrayMenu.ToggleNoRightClickEXE(s);
    cbDisableTrigger.Checked := frmSysTrayMenu.IsNoRightClickEXE(s);

    if SelectedIsDefault then lvPrograms.Selected.ImageIndex := -1;
end;
procedure TFrmConfig.cbDisableMonitoringMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var s : string;
begin
    s := lvPrograms.Selected.Caption;
    lvPrograms.Selected.ImageIndex := 5;

    frmSysTrayMenu.ToggletDisabledEXE(s);
    cbDisableMonitoring.Checked := frmSysTrayMenu.IsDisabledEXE(s);

    if SelectedIsDefault then lvPrograms.Selected.ImageIndex := -1;
end;

procedure TFrmConfig.rbProgramMacroClick(Sender: TObject);
begin
    btnProgramCustomScript.Enabled := rbProgramMacro.Checked;
    if rbProgramMacro.Checked then
        Paste.AssignPaste(lvPrograms.Selected.Caption, PASTE_PROGRAMCUSTOMMACRO);
end;
procedure TFrmConfig.cbxPasteMethodChange(Sender: TObject);
var s : string;
begin
    s := lvPrograms.Selected.Caption;
    lvPrograms.Selected.ImageIndex := 5;

    if rbProgramPaste.Checked then
        Paste.AssignPaste(s, TPasteMethod(cbxPasteMethod.ItemIndex));
    //frmSysTrayMenu.ToggletDisabledEXE(s);
    //cbDisableMonitoring.Checked := frmSysTrayMenu.IsDisabledEXE(s);
    if SelectedIsDefault then lvPrograms.Selected.ImageIndex := -1;
end;



//
// Custom Menus
//
procedure TFrmConfig.clbCustomMenusClick(Sender: TObject);
begin
    btnCustomMenu1.Enabled := clbCustomMenus.ItemIndex <> -1;
end;
procedure TFrmConfig.clbCustomMenusDragDrop(Sender, Source: TObject; X, Y: Integer);
var oldindex, newindex : integer;
    s1, s2 : string;
begin
    newindex := clbCustomMenus.ItemAtPos(point(x,y), true);
    oldindex := clbCustomMenus.ItemAtPos(CustomMenuPoint, true);

    clbCustomMenus.Items.Move(oldindex, newindex);
    CustomMenuData.Move(oldindex, newindex);

    clbCustomMenus.ItemIndex := newIndex;

end;
procedure TFrmConfig.clbCustomMenusDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
    Accept := Sender = clbCustomMenus;
end;
procedure TFrmConfig.clbCustomMenusExit(Sender: TObject);
begin
    btnCustomMenu1.Enabled := clbCustomMenus.ItemIndex <> -1;
end;
procedure TFrmConfig.clbCustomMenusMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
    CustomMenuPoint.X := x;
    CustomMenuPoint.Y := y;
end;

procedure TFrmConfig.btnCustomPasteEditClick(Sender: TObject);
var caption, clip : string;
begin
    caption := 'Custom Script';
    clip := '[KEY="010056CTRL+V"]';
    FrmPermanentEdit.Top := self.Top;
    FrmPermanentEdit.Left := self.Left;
    FrmPermanentEdit.ShowAsDialog(caption, clip);
    if clip <> '' then begin
        frmSysTrayMenu.SetProgramMacro(PASTE_MACRO, clip);
    end;
end;


procedure TFrmConfig.btnProgramCustomScriptClick(Sender: TObject);
var caption, clip : string;

begin
    caption := 'Custom Script';
    clip := frmSysTrayMenu.GetProgramMacro(lvPrograms.Selected.Caption);
    FrmPermanentEdit.Top := self.Top;
    FrmPermanentEdit.Left := self.Left;
    FrmPermanentEdit.ShowAsDialog(caption, clip);
    if clip <> '' then begin
        frmSysTrayMenu.SetProgramMacro(lvPrograms.Selected.Caption, clip);
    end;

end;


procedure TFrmConfig.btnCustomMenu1Click(Sender: TObject);
var caption, clip : string;
    i : integer;
begin
    i := clbCustomMenus.ItemIndex;
    caption := clbCustomMenus.Items[i];
    clip := CustomMenuData[i];
    FrmPermanentEdit.Top := self.Top;
    FrmPermanentEdit.Left := self.Left;
    if FrmPermanentEdit.ShowAsDialog(caption, clip) then begin
        clbCustomMenus.Items[i] := caption;
        CustomMenuData[i] := clip;
    end;
end;
procedure TFrmConfig.btnNewCustomMenuClick(Sender: TObject);
begin
    NewMacro('','[INDEX=$i][TOCLIPBOARD=$i]');
end;
procedure TFrmConfig.NewMacro(Caption, Clip : string);
begin
    FrmPermanentEdit.Top := self.Top;
    FrmPermanentEdit.Left := self.Left;
    if FrmPermanentEdit.ShowAsDialog(caption, clip) then begin
        clbCustomMenus.Checked[clbCustomMenus.Items.Add(Caption)] := true;
        CustomMenuData.Add(clip);
    end;
end;
procedure TFrmConfig.btnNewMacroPopupClick(Sender: TObject);
begin
    ShowPopupRight(btnNewMacroPopup, pmMacros);
end;
procedure TFrmConfig.miAppendClipboard1Click(Sender: TObject);
begin
    NewMacro(
        'Append to Clipboard',
        '[STAYOPEN][CLIPBOARDONLY][INDEX=$i][CLIPBRD][POPUPITEM=$i]'
    );
end;
procedure TFrmConfig.miGoogle1Click(Sender: TObject);
begin
    NewMacro(
        'Google',
        '[INDEX=$i][TOCLIPBOARD=$i][RUN]http://www.google.com/search?q=[CLIPBRDCURRENT][ENDRUN]'
    );
end;
procedure TFrmConfig.miPasteandEnter1Click(Sender: TObject);
begin
    NewMacro('Paste and ENTER','[INDEX=$i][TOCLIPBOARD=$i][PASTEDEFAULT][ENTER]');
end;
procedure TFrmConfig.miPasteandTAB1Click(Sender: TObject);
begin
    NewMacro('Paste and TAB','[INDEX=$i][TOCLIPBOARD=$i][PASTEDEFAULT][TAB]');
end;

procedure TFrmConfig.miPasteStayOpen1Click(Sender: TObject);
begin
    NewMacro(
        'Paste Stay Open',
        '[STAYOPEN][INDEX=$i][TOCLIPBOARD=$i][PASTEDEFAULT]'
    );
end;

procedure TFrmConfig.miPastewithTime1Click(Sender: TObject);
begin
    NewMacro(
        'Paste with Time',
        'Time:[DATE="hh:nn:ss ampm"] [INDEX=$i][TOCLIPBOARD=$i][TRIMCLIPBOARD][CLIPBRDCURRENT]'
    );
end;

procedure TFrmConfig.timUpdatePreviewTimer(Sender: TObject);
begin
    timUpdatePreview.Enabled := false;
    if frmPreviewPopup.Visible  then btnPreview.Click;

end;
procedure TFrmConfig.tsClipboardBarShow(Sender: TObject);
begin
    cbEnableClipboardBar.Checked := frmClipboardBar.IsVisible;
end;
procedure TFrmConfig.tsProgramOptionsShow(Sender: TObject);
var sl : TStringList;
    h : THandle;
    s, current : string;
    i : integer;

    li : TListItem;

    procedure AddName( sl : TStringList; src : TListView; DefaultValue : string = ''); overload;
    var i : integer;
        s : string;
        li : TListItem;
    begin
        for i := 0 to sl.count - 1 do begin
            s := sl.Names[i];
            if s <> '' then
                li := src.FindCaption(0,s,false,true,false);
                if li = nil  then begin
                    li := src.Items.Add;
                    li.Caption := s;
                    //li.ImageIndex := -1;
                end;
                if sl.ValueFromIndex[i] <> DefaultValue then
                        li.ImageIndex := 5;

        end;
    end;
begin
    current := '';
    if self.SelectProgramOnce <> '' then begin
        current := lowercase(self.SelectProgramOnce);
        self.SelectProgramOnce := '';
        lvPrograms.Selected := nil;
    end;
    if lvPrograms.Selected <> nil then
        current := lvPrograms.Selected.Caption;

    sl := TStringList.create;
    lvPrograms.Items.Clear;

    Paste.GetEXEPasteList(sl);
    AddName(sl, lvPrograms, '4');

    sl.clear;
    frmSysTrayMenu.GetEXEDisabledList(sl);
    AddName(sl, lvPrograms, '0');

    frmSysTrayMenu.GetEXENoRightClickList(sl);
    AddName(sl, lvPrograms, '0');

    frmSysTrayMenu.GetEXEExplorerCompatList(sl);
    AddName(sl, lvPrograms, '0');



    // check for programs with all default settings
    // and remove them from the list

    with lvPrograms do
        for i := items.count - 1 downto 0 do begin
            if items[i].imageindex = 0 then
                lvPrograms.Items.Delete(i);
        end;

    // Show currently running programs

    h := Windows.GetForegroundWindow;
    while h <> 0 do begin
        s := Lowercase(WindowHandleToEXEName(h));

        if lowercase(s) <> 'arsclip.exe' then begin
            if lvPrograms.FindCaption(0,s,false,true,false) = nil  then begin
                li := lvPrograms.Items.Add;
                li.Caption := s;
                li.ImageIndex := -1;

            end;
        end;
        h := GetNextWindow(h);
    end;

    for i := 0 to lvPrograms.Items.Count-1 do begin
        li := lvPrograms.Items[i];
        if lowercase(li.Caption)=current then begin
            lvPrograms.Selected := li;
            BREAK;
        end;
    end;
    lvProgramsClick(self);
    myfree(sl);
end;
procedure TFrmConfig.cbTriggerWindowClick(Sender: TObject);
begin
	if not Assigned(FrmTriggerWindow) and  cbTriggerWindow.Checked then begin
        FrmTriggerWindow := TFrmTriggerWindow.Create(self);
        //FrmTriggerWindow.Visible := false;
        FrmTriggerWindow.prEnable := cbTriggerWindow.Checked;
    end;


	if Assigned(FrmTriggerWindow) and  not cbTriggerWindow.Checked then begin
    	FrmTriggerWindow.prEnable := false;
        FrmTriggerWindow.Free;
        FrmTriggerWindow := nil;

    end;

    //FrmScratchPad.prFadeTime := 100;
end;
procedure TFrmConfig.cbPopupDoubleclickClick(Sender: TObject);
begin
    if cbPopupDoubleclick.checked then
        cbPopupDoubleclickTray.checked := not cbPopupDoubleclick.checked;
end;
procedure TFrmConfig.cbPopupDoubleclickTrayClick(Sender: TObject);
begin
    if cbPopupDoubleclickTray.checked then
    cbPopupDoubleclick.checked := not cbPopupDoubleclickTray.checked;
end;
procedure TFrmConfig.bntSetFontClick(Sender: TObject);
var ini : TIniFile;
    c : cardinal;
    fs : TFontStyles;
begin
    if FontDialog.Execute then begin
        tempfont := FontDialog.Font;

        ini := TInifile.Create( self.GetINIFileName );

        //
        // Hotkey Panel
        //
        ini.WriteString('Font','Name', FontDialog.Font.Name);
        ini.WriteInteger('Font','CharSet', FontDialog.Font.Charset);
        ini.WriteInteger('Font','Color', FontDialog.Font.Color);
        ini.WriteInteger('Font','Size', FontDialog.Font.Size);

        fs :=FontDialog.Font.style;
        move(fs, c, 4);
        ini.WriteInteger('Font','Style', c);
        tempfont.Style := fs;
    end;
end;
procedure TFrmConfig.XcbShowAllItemsClick(Sender: TObject);
begin
    if cbShowAllItems.Checked then begin
        self.cbShowAllAsSubmenus.Checked := false;
    end;
end;
procedure TFrmConfig.XcbShowAllAsSubmenusClick(Sender: TObject);
begin
    if cbShowAllAsSubmenus.Checked then begin
        self.cbShowAllItems.Checked := false;
    end;
end;
procedure TFrmConfig.btnFormatUpClick(Sender: TObject);
var i : integer;
begin
    if lvFormats.Selected = nil then EXIT;
    i := lvFormats.Selected.Index;
    if i = 0 then EXIT;

    MoveListViewItem(lvFormats, i, i - 1 );

    lvFormats.Selected := lvFormats.Items[i - 1];
    lvFormats.ItemFocused := lvFormats.Selected;
end;
procedure TFrmConfig.btnFormatDownClick(Sender: TObject);
var i : integer;
begin
    if lvFormats.Selected = nil then EXIT;
    i := lvFormats.Selected.Index;
    if i = lvFormats.items.count - 1  then EXIT;

    MoveListViewItem(lvFormats, i, i + 1 );

    lvFormats.Selected := lvFormats.Items[i + 1];
    lvFormats.ItemFocused := lvFormats.Selected;
end;
procedure TFrmConfig.btnMenuUpClick(Sender: TObject);
var i : integer;
begin
    if lvOrder.Selected = nil then EXIT;
    i := lvOrder.Selected.Index;
    if i = 0 then EXIT;

    MoveListViewItem(lvOrder, i, i - 1 );

    lvOrder.Selected := lvOrder.Items[i - 1];
    lvOrder.ItemFocused := lvOrder.Selected;
end;


procedure TFrmConfig.btnMenuDownClick(Sender: TObject);
var i : integer;
begin
    if lvOrder.Selected = nil then EXIT;
    i := lvOrder.Selected.Index;
    if i = lvOrder.items.count - 1  then EXIT;

    MoveListViewItem(lvOrder, i, i + 1 );

    lvOrder.Selected := lvOrder.Items[i + 1];
    lvOrder.ItemFocused := lvOrder.Selected;
end;
procedure TFrmConfig.SpeedButton1Click(Sender: TObject);
var ini : TIniFile;
    c : cardinal;
    fs : TFontStyles;
begin
    if FontDialog.Execute then begin
        tempfont := FontDialog.Font;
        self.UpdateFontLabel(tempfont);


        ini := TInifile.Create( self.GetINIFileName );

        //
        // Hotkey Panel
        //
        ini.WriteString('Font','Name', FontDialog.Font.Name);
        ini.WriteInteger('Font','CharSet', FontDialog.Font.Charset);
        ini.WriteInteger('Font','Color', FontDialog.Font.Color);
        ini.WriteInteger('Font','Size', FontDialog.Font.Size);

        fs :=FontDialog.Font.style;
        move(fs, c, 4);
        ini.WriteInteger('Font','Style', c);
        tempfont.Style := fs;

        self.UpdatePreview;
    end;
end;



//
// Color Scheme
//
type TDumbPanel = class(TPanel)
    public
        property canvas;

end;
procedure TFrmConfig.UpdateColorExample;
var r : TRect;
    startc, endc : TColor;
    txtheight : integer;
const
    SPACER = 6;
    LEFTX = 15;
begin
    txtheight :=   Canvas.TextHeight('ALKFJ');
    with imgPreview do begin
        Canvas.Brush.Color := pnlBackgroundColor.Color;
        Canvas.FillRect(ClientRect);

        Canvas.Brush.Color := pnlTitleColor.Color;
        r.top := 0;
        r.Left := 0;
        r.Bottom := 17;
        r.Width :=  imgPreview.Width;

        Canvas.fillRect(r);

        r.Top := 18;
        r.Left := LEFTX;
        Canvas.Brush.Style := bsClear;
        Canvas.Font.Color := pnlFontColor.color;
        Canvas.TextOut(r.Left, r.top, 'Normal Text');

        inc(r.Top, txtheight + SPACER);
        r.Width := imgPreview.Width;
        r.Height :=  txtheight + 4;



        startc := UnitMisc.Blend(
                     pnlBackgroundColor.Color,
                     pnlHighlightColor.Color,
                    70
                );
        canvas.Brush.Color := startc;
        canvas.Pen.Color := dimColor(startc, 0.90);
        r.Left := 0;
        Canvas.Rectangle(r.Left,r.Top,r.Right,r.bottom);

        canvas.Brush.Style := bsClear;
        canvas.font.Color := pnlFontColor.Color;
        r.Left := LEFTX;
        canvas.TextOut(r.Left, r.top, 'Higlighted Text');

        inc(r.Top, txtheight + SPACER);

        canvas.Brush.Style := bsClear;
        Canvas.Font.Color := pnlClickedColor.Color;
        Canvas.TextOut(r.left, r.top, 'Clicked Text');
    end;

    self.UpdatePreview;
end;

procedure TFrmConfig.btnColorExamplesClick(Sender: TObject);
begin
    UnitMisc.ShowPopupRight(btnColorExamples, pmExampleColors);
end;

procedure TFrmConfig.DefaultScheme1Click(Sender: TObject);
begin
    cbFontColor.Checked := false;
    cbBackgroundColor.Checked := false;
    cbHighlightColor.Checked := false;
    cbClickedColor.Checked := false;
    cbTitleColor.Checked := false;

    pnlBackgroundColor.Color  := clBtnFace;
    pnlHighlightColor.Color := ColorToRGB(clHighlight);
    pnlFontColor.Color := ColorToRGB(clBtnText);
    pnlClickedColor.Color := $00790079;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.JoeJoeSpecial1Click(Sender: TObject);
begin
    cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := 13810111;
    pnlHighlightColor.Color := 8935334;
    pnlFontColor.Color := 0;
    pnlClickedColor.Color := $2935034;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.SuperDark1Click(Sender: TObject);
begin
    cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := $0;;
    pnlHighlightColor.Color := $FFFFFF;
    pnlFontColor.Color := $FFFFFF;
    pnlClickedColor.Color := $808080;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.Greyscale1Click(Sender: TObject);
begin
    cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := 12895428;
    pnlHighlightColor.Color := 10526880;
    pnlFontColor.Color := 0;
    pnlClickedColor.Color := 5592405;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.MetroGreen1Click(Sender: TObject);
begin
    cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := 1550688;
    pnlHighlightColor.Color := 11119360;
    pnlFontColor.Color := $FFFFFF;
    pnlClickedColor.Color := 42623094;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.MetroSteelBlue1Click(Sender: TObject);
begin
cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := 8877668;
    pnlHighlightColor.Color := 173693;
    pnlFontColor.Color := 16777215;
    pnlClickedColor.Color := 10927532;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;
procedure TFrmConfig.Woodgrain1Click(Sender: TObject);
begin
 cbFontColor.Checked := true;
    cbBackgroundColor.Checked := true;
    cbHighlightColor.Checked := true;
    cbClickedColor.Checked := true;
    cbTitleColor.Checked := true;

    pnlBackgroundColor.Color  := 4286603;
    pnlHighlightColor.Color := 1650754;
    pnlFontColor.Color := 1055523;
    pnlClickedColor.Color := 3493478;
    pnlTitleColor.Color := pnlBackgroundColor.Color;

    UpdateColorExample;
end;

initialization
begin
    // The Hand loaded by Delphi is the old one, not the current system cursor
    screen.Cursors[crHandPoint] := LoadCursor(0, IDC_HAND);
end;
end.






