# CutBox.app

## Coverage Report

#### Created: 2024-03-12 03:40

    .../Source/App/JSFuncSearchPreview/JSFuncSearchViewController.swift

    Line

    Count

    Source (jump to first uncovered line)

    1

    //

    2

    //  JSFuncSearchViewController.swift

    3

    //  CutBox

    4

    //

    5

    //  Created by Jason Milkins on 17/5/18.

    6

    //  Copyright © 2018-2023 ocodo. All rights reserved.

    7

    //

    8

    9

    import RxSwift

    10

    11

    class JSFuncSearchViewController: NSObject {

    12

    13

        var js: JSFuncService

    14

    66

        var selectedClips: [String] = []

    15

        var jsFuncView: JSFuncSearchAndPreviewView

    16

        var prefs: CutBoxPreferencesService

    17

        var fakeKey: FakeKey

    18

        var jsFuncPopup: PopupController

    19

        var pasteboard: PasteboardWrapperType

    20

    21

    1

        var hasFuncs: Bool {

    22

    1

            return !self.js.isEmpty

    23

    1

        }

    24

    25

    1

        var count: Int {

    26

    1

            return self.js.count

    27

    1

        }

    28

    29

    1

        var funcList: [String] {

    30

    1

            return self.js.funcList

    31

    1

        }

    32

    33

    70

        var events: PublishSubject<SearchJSFuncViewEvents> {

    34

    70

            return self.jsFuncView.events

    35

    70

        }

    36

    37

    66

        let disposeBag = DisposeBag()

    38

    39

        init(js: JSFuncService = JSFuncService(),

    40

             cutBoxPreferences: CutBoxPreferencesService = CutBoxPreferencesService.shared,

    41

             fakeKey: FakeKey = FakeKey(),

    42

             jsFuncView: JSFuncSearchAndPreviewView = JSFuncSearchAndPreviewView.fromNib()!,

    43

    66

             pasteboard: PasteboardWrapperType = PasteboardWrapper()) {

    44

    66

    45

    66

            self.js = js

    46

    66

            self.prefs = cutBoxPreferences

    47

    66

            self.fakeKey = fakeKey

    48

    66

            self.jsFuncView = jsFuncView

    49

    66

            self.jsFuncPopup = PopupController(content: self.jsFuncView)

    50

    66

            self.pasteboard = pasteboard

    51

    66

            super.init()

    52

    66

            self.setup()

    53

    66

        }

    54

    55

    66

        func setup() {

    56

    66

            self.configureJSPopupAndView()

    57

    66

            self.setupSearchTextEventBindings()

    58

    66

            self.setupSearchViewAndFilterBinding()

    59

    66

        }

    60

    61

    66

        private func setupSearchViewAndFilterBinding() {

    62

    66

            self.jsFuncView.itemsList?.dataSource = self

    63

    66

            self.jsFuncView.itemsList?.delegate = self

    64

    66

    65

    66

            self.jsFuncView.filterTextPublisher

    66

    66

                .subscribe(onNext: {

    67

    2

                    self.js.filterText = $0

    68

    2

                    self.jsFuncView.itemsList?.reloadData()

    69

    2

                })

    70

    66

                .disposed(by: self.disposeBag)

    71

    66

        }

    72

    73

    66

        private func setupSearchTextEventBindings() {

    74

    66

            self.events

    75

    66

                .subscribe(onNext: { event in

    76

    3

                    switch event {

    77

    3

                    case .closeAndPaste:

    78

    1

                        self.closeAndPaste()

    79

    3

    80

    3

                    case .justClose:

    81

    1

                        self.justClose()

    82

    3

    83

    3

                    default:

    84

    1

                        break

    85

    3

                    }

    86

    3

                })

    87

    66

                .disposed(by: disposeBag)

    88

    66

        }

    89

    90

    2

        private func resetJSFuncSearchText() {

    91

    2

            self.jsFuncView.searchText?.string = ""

    92

    2

            self.jsFuncView.filterTextPublisher.onNext("")

    93

    2

            self.jsFuncView.itemsList?.reloadData()

    94

    2

        }

    95

    96

    1

        @objc func fakePaste() {

    97

    1

            fakeKey.send(fakeKey: "V", useCommandFlag: true)

    98

    1

        }

    99

    100

    2

        @objc func hideApp() {

    101

    2

            NSApp.hide(self)

    102

    2

        }

    103

    104

    1

        private func justClose() {

    105

    1

            self.jsFuncPopup.closePopup()

    106

    1

            perform(#selector(hideApp), with: self, afterDelay: 0.1)

    107

    1

        }

    108

    109

    1

        private func closeAndPaste() {

    110

    1

            self.pasteSelectedClips()

    111

    1

            self.jsFuncPopup.closePopup()

    112

    1

            perform(#selector(hideApp), with: self, afterDelay: 0.1)

    113

    1

            perform(#selector(fakePaste), with: self, afterDelay: 0.25)

    114

    1

        }

    115

    116

    3

        func pasteSelectedClips() {

    117

    3

            guard !self.selectedClips.isEmpty else {

    118

    1

                return

    119

    2

            }

    120

    2

    121

    2

            let row = self.jsFuncView.itemsList.selectedRow

    122

    2

            var clip: String

    123

    2

    124

    2

            if let name = js.funcList[safe: row] {

    125

    1

                clip = js.process(name, items: self.selectedClips)

    126

    2

            } else {

    127

    1

                clip = prefs.prepareClips(self.selectedClips)

    128

    2

            }

    129

    2

    130

    2

            pasteboard.clearContents()

    131

    2

            pasteboard.setString(string: clip)

    132

    2

        }

    133

    134

    66

        private func configureJSPopupAndView() {

    135

    66

            self.jsFuncView.placeHolderTextString = "js_func_search_placeholder".l7n

    136

    66

            self.jsFuncPopup.proportionalTopPadding = 0.15

    137

    66

            self.jsFuncPopup.proportionalWidth = 0.6

    138

    66

            self.jsFuncPopup.proportionalHeight = 0.6

    139

    66

            self.jsFuncPopup.willOpenPopup = self.jsFuncPopup.proportionalResizePopup

    $s15CutBoxUnitTests26JSFuncSearchViewControllerC019configureJSPopupAndG0018_ED20B3A220ACEF2F7P13E1A95413B84ECLLyyFyycAA05PopupH0Ccfu_

    Line

    Count

    Source

    139

    66

            self.jsFuncPopup.willOpenPopup = self.jsFuncPopup.proportionalResizePopup

    Unexecuted instantiation: $s15CutBoxUnitTests26JSFuncSearchViewControllerC019configureJSPopupAndG0018_ED20B3A220ACEF2F7P13E1A95413B84ECLLyyFyycAA05PopupH0Ccfu_yycfu0_

    140

    66

            self.jsFuncPopup.didOpenPopup = {

    141

    0

                guard let window = self.jsFuncView.window

    142

    0

                    else { fatalError("No window found for popup") }

    143

    0

    144

    0

                self.resetJSFuncSearchText()

    145

    0

                // Focus search text

    146

    0

                window.makeFirstResponder(self.jsFuncView.searchText)

    147

    0

            }

    148

    66

    149

    68

            self.jsFuncPopup.willClosePopup = self.resetJSFuncSearchText

    $s15CutBoxUnitTests26JSFuncSearchViewControllerC019configureJSPopupAndG0018_ED20B3A220ACEF2F7P13E1A95413B84ECLLyyFyycACcfu1_

    Line

    Count

    Source

    149

    66

            self.jsFuncPopup.willClosePopup = self.resetJSFuncSearchText

    $s15CutBoxUnitTests26JSFuncSearchViewControllerC019configureJSPopupAndG0018_ED20B3A220ACEF2F7P13E1A95413B84ECLLyyFyycACcfu1_yycfu2_

    Line

    Count

    Source

    149

    2

            self.jsFuncPopup.willClosePopup = self.resetJSFuncSearchText

    150

    66

            self.jsFuncView.setupClipItemsContextMenu()

    151

    66

        }

    152

    }