1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #include "inputtab.h" |
5 | |
6 | #include "inputlistview.h" |
7 | #include "settingstab.h" |
8 | |
9 | #include <QFileDialog> |
10 | #include <QGridLayout> |
11 | #include <QLabel> |
12 | #include <QLineEdit> |
13 | #include <QPlainTextEdit> |
14 | #include <QPushButton> |
15 | #include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h> |
16 | |
17 | InputTab::InputTab(SettingsTab *settings, QWidget *parent) : QWidget(parent), settingsTab(settings) |
18 | { |
19 | QLabel *fileNameLabel = new QLabel(tr(s: "Input files:" )); |
20 | lastInputPath = QDir::currentPath(); |
21 | inputFilesListBox = new InputListView; |
22 | |
23 | convertButton = new QPushButton("Convert" , this); |
24 | connect(sender: convertButton, signal: &QAbstractButton::clicked, context: this, slot: [&]() { convert(); }); |
25 | |
26 | statusText = new QPlainTextEdit; |
27 | statusText->setReadOnly(true); |
28 | |
29 | QObject::connect(sender: &converterThread, signal: &ConverterThread::convertDone, context: this, slot: &InputTab::convertDone); |
30 | QObject::connect(sender: &converterThread, signal: &ConverterThread::convertStart, context: this, slot: &InputTab::convertStart); |
31 | QObject::connect(sender: &converterThread, signal: &ConverterThread::convertUpdate, context: this, slot: &InputTab::convertUpdate); |
32 | |
33 | QPushButton *browseInputButton = new QPushButton(tr(s: "Browse..." ), this); |
34 | connect(sender: browseInputButton, signal: &QAbstractButton::clicked, context: this, slot: &InputTab::browseInput); |
35 | |
36 | QPushButton *removeSelectedButton = new QPushButton(tr(s: "Remove selected" ), this); |
37 | connect(sender: removeSelectedButton, signal: &QAbstractButton::clicked, context: this, slot: &InputTab::removeSelected); |
38 | QPushButton *selectAllButton = new QPushButton(tr(s: "Select all" ), this); |
39 | connect(sender: selectAllButton, signal: &QAbstractButton::clicked, context: this, slot: &InputTab::selectAll); |
40 | |
41 | QLabel *pathLabel = new QLabel(tr(s: "Output folder:" )); |
42 | outputPathEdit = new QLineEdit(QDir::currentPath()); |
43 | QPushButton *browseOutputButton = new QPushButton(tr(s: "Browse..." ), this); |
44 | connect(sender: browseOutputButton, signal: &QAbstractButton::clicked, context: this, slot: &InputTab::browseOutput); |
45 | |
46 | QLabel *emptyLabel = new QLabel(); |
47 | |
48 | QGridLayout *mainLayout = new QGridLayout; |
49 | |
50 | constexpr int rowFileNameLabel = 0; |
51 | constexpr int rowinputFiles = 1; |
52 | constexpr int rowOutputPathLabel = 5; |
53 | constexpr int rowOutputPathEdit = 6; |
54 | constexpr int rowStatusLabel = 7; |
55 | |
56 | mainLayout->addWidget(fileNameLabel, row: rowFileNameLabel, column: 0, rowSpan: 1, columnSpan: 2); |
57 | mainLayout->addWidget(inputFilesListBox, row: rowinputFiles, column: 0, rowSpan: 4, columnSpan: 1); |
58 | mainLayout->addWidget(browseInputButton, row: rowinputFiles, column: 1); |
59 | mainLayout->addWidget(removeSelectedButton, row: rowinputFiles + 1, column: 1); |
60 | mainLayout->addWidget(selectAllButton, row: rowinputFiles + 2, column: 1); |
61 | mainLayout->addWidget(emptyLabel, row: rowinputFiles + 3, column: 1); |
62 | mainLayout->setRowStretch(row: rowinputFiles + 3, stretch: 1); |
63 | |
64 | mainLayout->addWidget(pathLabel, row: rowOutputPathLabel, column: 0, rowSpan: 1, columnSpan: 2); |
65 | |
66 | mainLayout->addWidget(outputPathEdit, row: rowOutputPathEdit, column: 0); |
67 | mainLayout->addWidget(browseOutputButton, row: rowOutputPathEdit, column: 1); |
68 | |
69 | mainLayout->addWidget(new QLabel("Status:" ), row: rowStatusLabel, column: 0, rowSpan: 1, columnSpan: 2); |
70 | mainLayout->addWidget(statusText, row: rowStatusLabel + 1, column: 0, rowSpan: 1, columnSpan: 2); |
71 | mainLayout->addWidget(convertButton, row: rowStatusLabel + 2, column: 0, rowSpan: 1, columnSpan: 2); |
72 | |
73 | setLayout(mainLayout); |
74 | } |
75 | |
76 | void InputTab::convert() |
77 | { |
78 | QStringList filenames = getInputFiles(); |
79 | QDir outputPath = getOutputPath(); |
80 | |
81 | const auto options = settingsTab->getOptions(); |
82 | |
83 | converterThread.convert(filenames, outputPath, options); |
84 | } |
85 | |
86 | void InputTab::convertStart(const QString &text) |
87 | { |
88 | statusText->setPlainText(text); |
89 | convertButton->setText(QString("Converting..." )); |
90 | convertButton->setDisabled(true); |
91 | } |
92 | |
93 | void InputTab::convertUpdate(const QString &text) |
94 | { |
95 | statusText->appendPlainText(text); |
96 | } |
97 | |
98 | void InputTab::convertDone(const QString &text) |
99 | { |
100 | statusText->appendPlainText(text); |
101 | convertButton->setText(QString("Convert" )); |
102 | convertButton->setDisabled(false); |
103 | } |
104 | |
105 | QStringList InputTab::getInputFiles() const |
106 | { |
107 | QStringList files; |
108 | for (int i = 0; i < inputFilesListBox->count(); ++i) |
109 | files.push_back(t: inputFilesListBox->item(row: i)->text()); |
110 | return files; |
111 | } |
112 | |
113 | QString InputTab::getOutputPath() const |
114 | { |
115 | return outputPathEdit->text(); |
116 | } |
117 | |
118 | void InputTab::browseInput() |
119 | { |
120 | QFileDialog dialog(this); |
121 | dialog.setFileMode(QFileDialog::ExistingFiles); |
122 | dialog.setDirectory(lastInputPath); |
123 | |
124 | const auto allDescs = QSSGAssetImportManager().getImporterPluginInfos(); |
125 | |
126 | QStringList nameFilters; |
127 | for (const auto &plugin : allDescs) { |
128 | nameFilters.append(t: tr(s: "%1 files (*.%2)" ).arg(args: plugin.typeDescription, args: plugin.inputExtensions.join(QStringLiteral(" *." )))); |
129 | } |
130 | nameFilters.append(t: tr(s: "Any files (*)" )); |
131 | dialog.setNameFilters(nameFilters); |
132 | |
133 | if (!dialog.exec()) |
134 | return; |
135 | |
136 | const auto selectedFiles = dialog.selectedFiles(); |
137 | for (const auto &file : selectedFiles) |
138 | inputFilesListBox->tryAddItem(label: QDir::toNativeSeparators(pathName: file)); |
139 | |
140 | if (!selectedFiles.empty()) |
141 | lastInputPath = QFileInfo(selectedFiles.first()).absoluteDir().absolutePath(); |
142 | } |
143 | |
144 | void InputTab::browseOutput() |
145 | { |
146 | QString dir = QFileDialog::getExistingDirectory(parent: this, |
147 | caption: tr(s: "Open Directory" ), |
148 | dir: outputPathEdit->text(), |
149 | options: QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); |
150 | if (!dir.isEmpty()) { |
151 | outputPathEdit->setText(dir); |
152 | } |
153 | } |
154 | |
155 | void InputTab::removeSelected() |
156 | { |
157 | QList<QListWidgetItem *> selectedItems = inputFilesListBox->selectedItems(); |
158 | for (int i = 0; i < inputFilesListBox->count(); ++i) { |
159 | auto item = inputFilesListBox->item(row: i); |
160 | if (selectedItems.contains(t: item)) { |
161 | inputFilesListBox->takeItem(row: i); |
162 | selectedItems.removeAll(t: item); |
163 | i--; |
164 | } |
165 | } |
166 | } |
167 | |
168 | void InputTab::selectAll() |
169 | { |
170 | for (int i = 0; i < inputFilesListBox->count(); ++i) { |
171 | auto item = inputFilesListBox->item(row: i); |
172 | item->setSelected(true); |
173 | } |
174 | } |
175 | |