class create_elem(QGroupBox):
    def __init__(self, name, type, data=""):
        QGroupBox.__init__(self)

        if name.find(": ") != -1: name = name.split(": ")[0]
        self.name, self.type = name, type
        self.data = data

        self.defaultElement = QGroupBox()
        mainElementLayout = QVBoxLayout()
        elementLayout = QHBoxLayout()
        if self.data == "": self.lName = QLabel(str(name))
        else: self.lName = QLabel(str(name) + ": " + str(self.data))
        self.lName.setMinimumSize(10, 10)
        duplicate = QPushButton("❐")
        duplicate.clicked.connect(lambda: self.duplicateElement())
        edit = QPushButton("✎")
        edit.clicked.connect(lambda: self.editText())
        remove = QPushButton("×")
        remove.clicked.connect(lambda: self.delElement())
        elementLayout.addWidget(self.lName)
        elementLayout.addWidget(duplicate)
        elementLayout.addWidget(edit)
        elementLayout.addWidget(remove)
        elementLayout.setStretch(0, 2)
        mainElementLayout.addLayout(elementLayout)
        mainElementLayout.addSpacing(10)
        self.defaultElement.setLayout(mainElementLayout)
        self.defaultElement.setFixedHeight(80)

    def editText(self):
        if self.type == "Comment":
            if self.data != "": text = CommentPopup(self.data)
            else: text = CommentPopup()
            self.data = text.saveElement()
            if self.data == "": self.lName.setText(self.name)
            else: self.lName.setText(self.name + ": " + self.data)

    def getElem(self):
        return self.defaultElement

    def duplicateElement(self):
        index = widget.elems_list.index(self.defaultElement)
        if self.type == "Comment":
            widget.add_element(self.name, self.type, True, index, self.data)

    def delElement(self):
        self.defaultElement.deleteLater()
        widget.elems -= 1
        widget.layout.removeWidget(self.defaultElement)
        widget.elems_list.remove(self.defaultElement)
        widget.update()
Exemple #2
0
class Ui_FE14CharacterEditor(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.search_bar = QLineEdit()
        self.search_bar.setPlaceholderText("Search...")
        self.search_bar.setFixedWidth(225)
        self.characters_list_view = QListView()
        self.characters_list_view.setContextMenuPolicy(
            QtCore.Qt.CustomContextMenu)
        self.characters_list_view.setFixedWidth(225)
        self.characters_list_layout = QVBoxLayout()
        self.characters_list_layout.addWidget(self.search_bar)
        self.characters_list_layout.addWidget(self.characters_list_view)

        self.character_details_box = QGroupBox(title="Character Details")
        self.portrait_display = QGraphicsView()
        self.portrait_display.setFixedSize(140, 140)
        self.character_details_form_contents_1 = QWidget()
        self.character_details_form_contents_2 = QWidget()
        self.character_details_layout = QHBoxLayout()
        self.character_details_layout.addWidget(self.portrait_display)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_1)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_2)
        self.character_details_box.setLayout(self.character_details_layout)
        self.character_details_box.setFixedHeight(200)

        self.tab_widget = QTabWidget()
        self.ids_tab = QWidget()
        self.classes_tab = QWidget()
        self.stats_tab = QScrollArea()
        self.skills_tab = QScrollArea()
        self.misc_tab = QScrollArea()
        self.portraits_tab = PortraitViewer()

        self.stats_contents = QWidget()
        self.stats_tab.setWidget(self.stats_contents)
        self.stats_tab.setWidgetResizable(True)
        self.stats_layout = QVBoxLayout()
        self.stats_layout.setAlignment(QtCore.Qt.AlignTop)
        self.stats_contents.setLayout(self.stats_layout)

        self.skills_contents = QWidget()
        self.skills_tab.setWidget(self.skills_contents)
        self.skills_tab.setWidgetResizable(True)

        self.misc_contents = QWidget()
        self.misc_tab.setWidget(self.misc_contents)
        self.misc_tab.setWidgetResizable(True)
        self.misc_layout = QVBoxLayout()
        self.misc_layout.setAlignment(QtCore.Qt.AlignTop)
        self.misc_contents.setLayout(self.misc_layout)

        self.tab_widget.addTab(self.ids_tab, "IDs")
        self.tab_widget.addTab(self.classes_tab, "Classes")
        self.tab_widget.addTab(self.stats_tab, "Stats")
        self.tab_widget.addTab(self.skills_tab, "Skills")
        self.tab_widget.addTab(self.misc_tab, "Misc.")
        self.tab_widget.addTab(self.portraits_tab, "Portraits")

        self.editor_layout = QVBoxLayout()
        self.editor_layout.addWidget(self.character_details_box)
        self.editor_layout.addWidget(self.tab_widget)

        self.main_layout = QHBoxLayout()
        self.main_layout.addLayout(self.characters_list_layout)
        self.visual_splitter = QFrame()
        self.visual_splitter.setFrameShape(QFrame.VLine)
        self.visual_splitter.setFrameShadow(QFrame.Sunken)
        self.main_layout.addWidget(self.visual_splitter)
        self.main_layout.addLayout(self.editor_layout)

        self.tool_bar = QToolBar()
        self.action_add = QAction(text="Add")
        self.action_remove = QAction(text="Remove")
        self.action_copy_to = QAction(text="Copy To")
        self.tool_bar.addActions(
            [self.action_add, self.action_remove, self.action_copy_to])

        self.addToolBar(self.tool_bar)

        self.resize(1000, 600)
        central_widget = QWidget()
        central_widget.setLayout(self.main_layout)
        self.setWindowTitle("Character Editor")
        self.setWindowIcon(QIcon("paragon.ico"))
        self.setCentralWidget(central_widget)
class AddNew(QWidget):
    def __init__(self, main_table):
        super(AddNew, self).__init__()
        self.table = main_table
        self.headers = main_table.model_c.metadata_c.metadata["headers"]
        self.title = f'Add New - {self.table.model_c.path_c.get_file_name()}'

        # DESCRIPTION
        self.setWindowTitle(self.title)
        self.setWindowState(Qt.WindowMaximized)
        self.setStyleSheet(styles.main_dark)
        # MAIN LAYOUT
        self.main_v_layout = QVBoxLayout()

        # SPLITTER
        self.splitter = QSplitter(self)

        # MAIN TOOL BAR
        self.toolbar = QGroupBox(self)
        self.set_up_toolbar()

        # SIDE WORKSPACE
        self.side_widget = None

        # MAIN WORKSPACE
        main_workspace_layout = QVBoxLayout()
        self.main_widget = QWidget(self)
        self.headers_inputs = HeadersInput(self, self.headers)

        # MAIN WORKSPACE BUTTONS
        button_h_layout = QHBoxLayout()

        self.button_add = QPushButton("ADD", self)
        self.button_add.clicked.connect(self.add_new)

        self.button_clear = QPushButton("Clear", self)
        self.button_clear.clicked.connect(self.clear)

        button_h_layout.addWidget(self.button_add)
        button_h_layout.addWidget(self.button_clear)

        # SET UP
        main_workspace_layout.addWidget(self.headers_inputs)
        main_workspace_layout.addLayout(button_h_layout)

        self.main_widget.setLayout(main_workspace_layout)

        self.splitter.addWidget(self.main_widget)

        self.main_v_layout.addWidget(self.toolbar)
        self.main_v_layout.addWidget(self.splitter)

        self.setLayout(self.main_v_layout)

        self.show()

    def add_new(self):
        item = self.headers_inputs.get_values()
        if not item:
            return
        _, contains_in_self = self.table.add(item)

        self.open_home_table()

    def clear(self):
        self.headers_inputs.clear()

    def open_home_table(self):
        if self.side_widget is not None:
            self.side_widget.close()

        self.side_widget = SideTable(self, self.table.model_c)

        self.splitter.insertWidget(-1, self.side_widget)

    def set_up_toolbar(self):
        vbox = QHBoxLayout()

        self.toolbar.setStyleSheet(styles.tool_bar_groupbox_dark)
        vbox.setAlignment(Qt.AlignLeft)
        vbox.setContentsMargins(10, 0, 0, 0)
        self.toolbar.setLayout(vbox)
        self.toolbar.setFixedHeight(40)

        home_table = QPushButton(QIcon(icon.HOME_SCREEN_I()), "", self.toolbar)

        vbox.addWidget(home_table)

        parent_relation_option = (list(
            map(
                lambda relation: {
                    "text": relation["name_of_child_table"],
                    "parm": relation["path_of_child_table"],
                    "icon": icon.MULTICAST_I(),
                    "callback": self.open_parent,
                    "tooltip": relation["name_of_relation"]
                }, self.table.model_c.metadata_c.metadata["sequential_info"]
                ["parent_relation"])))

        if len(parent_relation_option) > 0:
            select_parent = ButtonOptions(self.toolbar, parent_relation_option,
                                          icon.MULTICAST_I())

            vbox.addWidget(select_parent)

        child_relations_options = (list(
            map(
                lambda relation: {
                    "text": relation["name_of_child_table"],
                    "parm": relation["path_of_child_table"],
                    "icon": icon.MULTICAST_I(),
                    "callback": self.open_parent,
                    "tooltip": relation["name_of_relation"]
                }, self.table.model_c.metadata_c.metadata["sequential_info"]
                ["child_relation"])))

        if len(child_relations_options) > 0:
            add_child = ButtonOptions(self.toolbar, child_relations_options,
                                      icon.DOWN_BUTTON_I())

            vbox.addWidget(add_child)

        home_table.setStatusTip(f"Open '{self.table.model_c.path_c.path}'")
        home_table.clicked.connect(self.open_home_table)

    def open_parent(self, path):
        if self.side_widget is not None:
            self.side_widget.close()

        self.side_widget = SideTableSelectParent(
            self, SQFile(Path(path), True), self.headers_inputs.set_parent,
            self.table.model_c.path_c)

        self.splitter.insertWidget(-1, self.side_widget)

    def open_child(self, path):
        ...
Exemple #4
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.attach_event()
        self.setAcceptDrops(True)
        
    def init_ui(self):
        # Define & Configure Components
        normal_button_size = QSize(80, 24)
        icon_button_size = QSize(24, 24)
        icon_size = QSize(18, 18)
        
        self.central_widget = QWidget()
        self.central_layout = QGridLayout()
        self.central_widget.setLayout(self.central_layout)

        self.tab_group_widget = QTabWidget()
        self.tab_group_widget.setMinimumSize(400, 0)
        self.tab_group_widget.setFixedHeight(150)
        self.tab1_name = '스폰서 변환'
        self.tab2_name = '싱크 조절(초)'
        self.tab3_name = '싱크 조절(%)'

        self.tab_page_1 = QWidget()
        self.tab_grid_1 = QGridLayout()
        self.tab1_search_label = QLabel('검색 텍스트')
        self.tab1_search = QLineEdit()
        self.tab1_sponsor = QWidget()
        self.tab1_sponsor_layout = QHBoxLayout()
        self.tab1_sponsor_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_sponsor_label = QLabel('스폰서 영상 길이')
        self.tab1_sponsor_value = QDoubleSpinBox()
        self.tab1_sponsor_value.setFixedWidth(60)
        self.tab1_sponsor_value.setMinimum(-1000000000)
        self.tab1_sponsor_value.setValue(10)
        self.tab1_offset = QWidget()
        self.tab1_offset_layout = QHBoxLayout()
        self.tab1_offset_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_offset_label = QLabel('라인 오프셋')
        self.tab1_offset_value = QSpinBox()
        self.tab1_offset_value.setMinimum(-1000000000)
        self.tab1_offset_value.setValue(2)
        self.tab1_offset_value.setFixedWidth(50)
        self.tab1_ignore = QWidget()
        self.tab1_ignore_layout = QHBoxLayout()
        self.tab1_ignore_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_ignore_label1 = QLabel('시작부터')
        self.tab1_ignore_value = QSpinBox()
        self.tab1_ignore_value.setFixedWidth(50)
        self.tab1_ignore_value.setValue(5)
        self.tab1_ignore_label2 = QLabel('줄 ')
        self.tab1_ignore_sec = QSpinBox()
        self.tab1_ignore_sec.setFixedWidth(60)
        self.tab1_ignore_sec.setMaximum(1000)
        self.tab1_ignore_sec.setValue(90)
        self.tab1_ignore_label3 = QLabel('초 무시하기')
        self.tab1_add_button = QPushButton('추가하기')

        self.tab_page_2 = QWidget()
        self.tab_grid_2 = QGridLayout()
        self.tab2_shift = QWidget()
        self.tab2_shift_layout = QHBoxLayout()
        self.tab2_shift_layout.setContentsMargins(0, 0, 0, 0)
        self.tab2_shift_label1 = QLabel('자막 싱크')
        self.tab2_shift_value = QDoubleSpinBox()
        self.tab2_shift_value.setFixedWidth(60)
        self.tab2_shift_label2 = QLabel('초 ')
        self.tab2_slow_radio = QRadioButton('느리게')
        self.tab2_slow_radio.setChecked(True)
        self.tab2_fast_radio = QRadioButton('빠르게')
        self.tab2_add_button = QPushButton('추가하기')

        self.tab_page_3 = QWidget()
        self.tab_grid_3 = QGridLayout()
        self.tab3_speed_label1 = QLabel('자막 싱크')
        self.tab3_speed_value = QSpinBox()
        self.tab3_speed_value.setFixedWidth(70)
        self.tab3_speed_value.setRange(1, 1000)
        self.tab3_speed_value.setValue(100)
        self.tab3_speed_label2 = QLabel('%')
        self.tab3_add_button = QPushButton('추가하기')

        self.que_label = QLabel('작업 목록')
        self.que_label.setFixedHeight(24)
        self.que_widget = QWidget()
        self.que_widget.setFixedHeight(114)
        self.que_layout = QGridLayout()
        self.que_layout.setContentsMargins(0, 0, 0, 0)
        self.que_list = QTreeWidget()
        self.que_list.setHeaderLabels(['작업', '옵션'])
        self.que_delete_button = QPushButton(QIcon(':/remove.png'), '')
        self.que_delete_button.setFixedSize(icon_button_size)
        self.que_delete_button.setIconSize(icon_size)
        self.que_delete_button.setToolTip('목록 삭제')
        self.que_up_button = QPushButton(QIcon(':/up.png'), '')
        self.que_up_button.setIconSize(icon_size)
        self.que_up_button.setFixedSize(icon_button_size)
        self.que_up_button.setToolTip('위로')
        self.que_down_button = QPushButton(QIcon(':/down.png'), '')
        self.que_down_button.setIconSize(icon_size)
        self.que_down_button.setFixedSize(icon_button_size)
        self.que_down_button.setToolTip('아래로')
        self.que_clear_button = QPushButton(QIcon(':/clear.png'), '')
        self.que_clear_button.setIconSize(icon_size)
        self.que_clear_button.setFixedSize(icon_button_size)
        self.que_clear_button.setToolTip('비우기')

        self.file_label = QLabel('파일 목록')
        self.file_label.setFixedHeight(24)
        self.file_widget = QWidget()
        self.file_layout = QGridLayout()
        self.file_layout.setContentsMargins(0, 0, 0, 0)
        self.file_list = QTreeWidget()
        self.file_list.setAcceptDrops(True)
        self.file_list.setHeaderLabels(['이름', '경로'])
        self.file_file_open = QPushButton(QIcon(':/file.png'), '')
        self.file_file_open.setFixedSize(icon_button_size)
        self.file_file_open.setIconSize(icon_size)
        self.file_file_open.setToolTip('파일 열기')
        self.file_dir_open = QPushButton(QIcon(':/folder.png'), '')
        self.file_dir_open.setFixedSize(icon_button_size)
        self.file_dir_open.setIconSize(icon_size)
        self.file_dir_open.setToolTip('폴더 열기')
        self.file_delete = QPushButton(QIcon(':/remove.png'), '')
        self.file_delete.setFixedSize(icon_button_size)
        self.file_delete.setIconSize(icon_size)
        self.file_delete.setToolTip('목록 삭제')
        self.file_clear = QPushButton(QIcon(':/clear.png'), '')
        self.file_clear.setFixedSize(icon_button_size)
        self.file_clear.setIconSize(icon_size)
        self.file_clear.setToolTip('비우기')
        self.file_encode = QPushButton(QIcon(':/encode.png'), '')
        self.file_encode.setFixedSize(icon_button_size)
        self.file_encode.setIconSize(icon_size)
        self.file_encode.setToolTip('인코딩 설정')

        self.save_widget = QGroupBox('저장 옵션')
        self.save_widget.setMinimumSize(400, 0)
        self.save_widget.setFixedHeight(82)
        self.save_layout = QGridLayout()
        self.save_orig_radio = QRadioButton('원본 위치에 저장')
        self.save_orig_radio.setChecked(True)
        self.save_strip = QCheckBox('싱크 꼬임 무시')
        self.save_strip.setToolTip('싱크 꼬임을 무시하고 모든 자막을 보존합니다.')
        self.save_dir_radio = QRadioButton('다른 위치에 저장')
        self.save_dir_line = QLineEdit()
        self.save_dir_find = QPushButton('...')
        self.save_dir_find.setFixedWidth(40)

        self.ok_button = QPushButton('적용')
        self.ok_button.setFixedSize(normal_button_size)
        self.cancel_button = QPushButton('취소')
        self.cancel_button.setFixedSize(normal_button_size)

        # Display GUI Components
        self.central_layout.addWidget(self.tab_group_widget, 0, 0, 1, 3)
        self.central_layout.addWidget(self.que_label, 1, 0, 1, 3)
        self.central_layout.addWidget(self.que_widget, 2, 0, 1, 3)
        self.central_layout.addWidget(self.file_label, 3, 0, 1, 3)
        self.central_layout.addWidget(self.file_widget, 4, 0, 1, 3)
        self.central_layout.addWidget(self.save_widget, 5, 0, 1, 3)
        self.central_layout.addWidget(self.ok_button, 6, 1, 1, 1)
        self.central_layout.addWidget(self.cancel_button, 6, 2, 1, 1)

        self.tab_group_widget.addTab(self.tab_page_1, QIcon(), self.tab1_name)
        self.tab_group_widget.addTab(self.tab_page_2, QIcon(), self.tab2_name)
        self.tab_group_widget.addTab(self.tab_page_3, QIcon(), self.tab3_name)

        self.tab_page_1.setLayout(self.tab_grid_1)
        self.tab_grid_1.addWidget(self.tab1_search_label, 0, 0, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_search, 0, 1, 1, 2)
        self.tab_grid_1.addWidget(self.tab1_sponsor, 1, 1, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_offset, 1, 2, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_ignore, 2, 1, 1, 2)
        self.tab_grid_1.addWidget(self.tab1_add_button, 3, 0, 1, 3)
        self.tab1_sponsor.setLayout(self.tab1_sponsor_layout)
        self.tab1_sponsor_layout.addWidget(self.tab1_sponsor_label)
        self.tab1_sponsor_layout.addWidget(self.tab1_sponsor_value)
        self.tab1_sponsor_layout.addStretch(1)
        self.tab1_offset.setLayout(self.tab1_offset_layout)
        self.tab1_offset_layout.addWidget(self.tab1_offset_label)
        self.tab1_offset_layout.addWidget(self.tab1_offset_value)
        self.tab1_offset_layout.addStretch(1)
        self.tab1_ignore.setLayout(self.tab1_ignore_layout)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label1)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_value)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label2)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_sec)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label3)
        self.tab1_ignore_layout.addStretch(1)

        self.tab_page_2.setLayout(self.tab_grid_2)
        self.tab_grid_2.setRowStretch(0, 1)
        self.tab_grid_2.addWidget(self.tab2_shift, 1, 0, 2, 1)
        self.tab_grid_2.addWidget(self.tab2_slow_radio, 1, 1, 1, 1)
        self.tab_grid_2.addWidget(self.tab2_fast_radio, 2, 1, 1, 1)
        self.tab_grid_2.setColumnStretch(2, 1)
        self.tab_grid_2.setRowStretch(3, 1)
        self.tab_grid_2.addWidget(self.tab2_add_button, 4, 0, 1, 3)
        self.tab2_shift.setLayout(self.tab2_shift_layout)
        self.tab2_shift_layout.addWidget(self.tab2_shift_label1)
        self.tab2_shift_layout.addWidget(self.tab2_shift_value)
        self.tab2_shift_layout.addWidget(self.tab2_shift_label2)

        self.tab_page_3.setLayout(self.tab_grid_3)
        self.tab_grid_3.setRowStretch(0, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_label1, 1, 0, 1, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_value, 1, 1, 1, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_label2, 1, 2, 1, 1)
        self.tab_grid_3.setColumnStretch(3, 1)
        self.tab_grid_3.setRowStretch(2, 1)
        self.tab_grid_3.addWidget(self.tab3_add_button, 3, 0, 1, 4)

        self.que_widget.setLayout(self.que_layout)
        self.que_layout.addWidget(self.que_list, 0, 0, 4, 1)
        self.que_layout.addWidget(self.que_delete_button, 0, 1, 1, 1)
        self.que_layout.addWidget(self.que_up_button, 1, 1, 1, 1)
        self.que_layout.addWidget(self.que_down_button, 2, 1, 1, 1)
        self.que_layout.addWidget(self.que_clear_button, 3, 1, 1, 1)

        self.file_widget.setLayout(self.file_layout)
        self.file_layout.addWidget(self.file_list, 0, 0, 6, 1)
        self.file_layout.addWidget(self.file_file_open, 0, 1, 1, 1)
        self.file_layout.addWidget(self.file_dir_open, 1, 1, 1, 1)
        self.file_layout.addWidget(self.file_delete, 2, 1, 1, 1)
        self.file_layout.addWidget(self.file_clear, 3, 1, 1, 1)
        self.file_layout.addWidget(self.file_encode, 5, 1, 1, 1)

        self.save_widget.setLayout(self.save_layout)
        self.save_layout.addWidget(self.save_orig_radio, 0, 0, 1, 1)
        self.save_layout.setColumnStretch(1, 1)
        self.save_layout.addWidget(self.save_strip, 0, 2, 1, 2)
        self.save_layout.addWidget(self.save_dir_radio, 1, 0, 1, 1)
        self.save_layout.addWidget(self.save_dir_line, 1, 1, 1, 2)
        self.save_layout.addWidget(self.save_dir_find, 1, 3, 1, 1)

        self.setWindowTitle('Batch SAMI Sync v0.2')
        self.setCentralWidget(self.central_widget)
        self.adjustSize()

    def attach_event(self):
        # Default encoding hack
        self.encoding = '자동'

        # Define and Connect event handlers
        def tab1_add():
            sponsor_text = self.tab1_search.text()
            sponsor_time = self.tab1_sponsor_value.value()
            line_offset = self.tab1_offset_value.value()
            line_ignore = self.tab1_ignore_value.value()
            time_ignore = self.tab1_ignore_sec.value()
            data = [1, sponsor_time, sponsor_text, line_offset, line_ignore, time_ignore]
            item = QTreeWidgetItem(self.que_list, [self.tab1_name, '스폰서 영상 시간 : ' + str(sponsor_time) + '초, 오프셋 : ' + str(line_offset) + '줄, 시작부터 ' + str(line_ignore) + '번째 줄, ' + str(time_ignore) + '초 무시 - 검색어 : ' + sponsor_text])
            item.setData(2, 2, data)

        def tab2_add():
            shift_time = self.tab2_shift_value.value()
            shift_direction = self.tab2_fast_radio.isChecked()
            direction_text = '빠르게' if shift_direction else '느리게'
            data = [2, shift_time, shift_direction]
            item = QTreeWidgetItem(self.que_list, [self.tab2_name, '자막 싱크 ' + str(shift_time) + '초 ' + direction_text])
            item.setData(2, 2, data)

        def tab3_add():
            speed_rate = self.tab3_speed_value.value()
            data = [3, speed_rate]
            item = QTreeWidgetItem(self.que_list, [self.tab3_name, '자막 속도 ' + str(speed_rate) + '%'])
            item.setData(2, 2, data)

        def file_open():
            selected = QFileDialog.getOpenFileNames(self, "자막 파일 선택", "", "SAMI Files (*.smi);;All Files (*)")
            for file in selected[0]:
                name = ntpath.basename(file)
                Utils.insert_list(self.file_list, name, file)

        def dir_open():
            selected = QFileDialog.getExistingDirectory(self, "자막 폴더 선택")
            for paths, subdirs, files in os.walk(selected):
                for file in files:
                    if fnmatch(file, '*.smi'):
                        name = ntpath.basename(file)
                        Utils.insert_list(self.file_list, name, file)

        def open_encode_dialog():
            self.dialog = QInputDialog(self)
            self.dialog.setWindowTitle('인코딩 설정')
            self.dialog.setLabelText('텍스트 인코딩 설정')
            self.dialog.setComboBoxItems(['자동', 'EUC-KR', 'UTF-8', 'UTF-16LE', 'UTF-16BE', '직접 입력'])
            self.dialog.show()

            self.dialog.textValueChanged.connect(type_encode)
            self.dialog.textValueSelected.connect(set_encode)

        def type_encode(text):
            if text == '직접 입력':
                self.dialog.setComboBoxItems([])
                self.dialog.setComboBoxEditable(True)

        def set_encode(text):
            self.encoding = text

        def save_dir():
            selected = QFileDialog.getExistingDirectory(self, "저장 위치 선택")
            self.save_dir_line.setText(selected)

        def apply():
            self.ok_button.setEnabled(False)
            ques = Utils.read_list(self.que_list, False)
            files = Utils.read_list(self.file_list, False)
            strip = False if self.save_strip.isChecked() else True
            log = []
            for file in files:
                try:
                    text = Utils.launch_que(file[1], ques, self.encoding, strip)
                    if len(text):
                        if self.save_orig_radio.isChecked():
                            savepath = file[1]
                        else:
                            savepath = self.save_dir_line.text() + '/' + file[0]
                        Utils.save_file(savepath, text)
                except Exception as e:
                    log.append(file[0] + ' 처리 오류 : ' + str(e))
            if log:
                ScrollMessageBox(QMessageBox.Warning, 'Batch SAMI Sync', "\n".join(log))

            else:
                QMessageBox.information(self, 'Batch SAMI Sync', '변환 완료!')
            self.ok_button.setEnabled(True)

        self.tab1_add_button.clicked.connect(tab1_add)
        self.tab2_add_button.clicked.connect(tab2_add)
        self.tab3_add_button.clicked.connect(tab3_add)
        self.que_delete_button.clicked.connect(lambda: Utils.delete_list(self.que_list))
        self.que_clear_button.clicked.connect(lambda: Utils.clear_list(self.que_list))
        self.que_up_button.clicked.connect(lambda: Utils.up_list(self.que_list))
        self.que_down_button.clicked.connect(lambda: Utils.down_list(self.que_list))
        self.file_file_open.clicked.connect(file_open)
        self.file_dir_open.clicked.connect(dir_open)
        self.file_delete.clicked.connect(lambda: Utils.delete_list(self.file_list))
        self.file_clear.clicked.connect(lambda: Utils.clear_list(self.file_list))
        self.file_encode.clicked.connect(open_encode_dialog)
        self.save_dir_find.clicked.connect(save_dir)
        self.ok_button.clicked.connect(apply)
        self.cancel_button.clicked.connect(sys.exit)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
            for url in event.mimeData().urls():
                if url.isLocalFile():
                    file = str(url.toLocalFile())
                    if fnmatch(file, '*.smi'):
                        name = ntpath.basename(file)
                        Utils.insert_list(self.file_list, name, file)
                    elif not fnmatch(file, '*.*'):
                        for paths, subdirs, files in os.walk(file):
                            for file in files:
                                if fnmatch(file, '*.smi'):
                                    name = ntpath.basename(file)
                                    Utils.insert_list(self.file_list, name, file)

        else:
            event.ignore()