1 #include "sendinghandler.h"
2 #include "utils.h"
3 #include "emuthread.h"
4 #include "../../core/link.h"
5 #include "archive/extractor.h"
6
7 #include <QtWidgets/QMessageBox>
8 #include <QtWidgets/QApplication>
9 #include <QtWidgets/QToolButton>
10 #include <QtCore/QFileInfo>
11 #include <QtCore/QMimeData>
12 #include <QtGui/QDragEnterEvent>
13
14 SendingHandler *sendingHandler = Q_NULLPTR;
15
16 static const QStringList valid_suffixes = { QStringLiteral("8xp"),
17 QStringLiteral("8xv"),
18 QStringLiteral("8xl"),
19 QStringLiteral("8xn"),
20 QStringLiteral("8xm"),
21 QStringLiteral("8xy"),
22 QStringLiteral("8xg"),
23 QStringLiteral("8xs"),
24 QStringLiteral("8xd"),
25 QStringLiteral("8xw"),
26 QStringLiteral("8xc"),
27 QStringLiteral("8xz"),
28 QStringLiteral("8xt"),
29 QStringLiteral("8ca"),
30 QStringLiteral("8cg"),
31 QStringLiteral("8ci"), };
32
pathHasBundleExtension(const QString & filepath)33 static inline bool pathHasBundleExtension(const QString& filepath) {
34 return filepath.endsWith("b84", Qt::CaseInsensitive) || filepath.endsWith("b83", Qt::CaseInsensitive);
35 }
36
37 static QStringList bundleList;
checkValidFile(const char * path)38 static bool checkValidFile(const char *path) {
39 QString npath(path);
40 foreach (const QString &str, valid_suffixes) {
41 if (npath.endsWith(str, Qt::CaseInsensitive)) {
42 bundleList.append(path);
43 return true;
44 }
45 }
46 return false;
47 }
48
getValidFilesFromArchive(const QString & archivePath)49 QStringList SendingHandler::getValidFilesFromArchive(const QString& archivePath) {
50 if (!m_tempDir.isValid()) {
51 QMessageBox::critical(Q_NULLPTR, tr("Transfer error"), tr("Could not create the temporary directory to extract the archive.\nFile: ") + archivePath);
52 return {};
53 }
54
55 bundleList.clear();
56 extractor(archivePath.toStdString().c_str(), m_tempDir.path().toStdString().c_str(), checkValidFile);
57 return bundleList;
58 }
59
SendingHandler(QObject * parent,QProgressBar * bar,QTableWidget * table)60 SendingHandler::SendingHandler(QObject *parent, QProgressBar *bar, QTableWidget *table) : QObject{parent} {
61 m_progressBar = bar;
62 m_table = table;
63
64 bar->setMinimum(0);
65 bar->setMinimumWidth(0);
66 bar->setMaximumWidth(200);
67 bar->setTextVisible(false);
68 bar->setValue(0);
69 bar->setVisible(false);
70 m_iconSend.addPixmap(QPixmap(":/icons/resources/icons/variables.png"));
71 m_iconCheck.addPixmap(QPixmap(":/icons/resources/icons/check.png"));
72 m_iconCheckGray.addPixmap(QPixmap(":/icons/resources/icons/checkgray.png"));
73 }
74
dropOccured(QDropEvent * e,int location)75 void SendingHandler::dropOccured(QDropEvent *e, int location) {
76 if (guiSend || guiReceive || guiDebug) {
77 e->ignore();
78 return;
79 }
80
81 const QMimeData* mime_data = e->mimeData();
82 if (!mime_data->hasUrls()) {
83 return;
84 }
85
86 QStringList files;
87 for(auto &&url : mime_data->urls()) {
88 const QString filePath = url.toLocalFile();
89 files.append(filePath);
90 }
91
92 sendFiles(files, location);
93 }
94
resendSelected()95 void SendingHandler::resendSelected() {
96 QStringList files;
97
98 for (int row = 0; row < m_table->rowCount(); row++) {
99 if (static_cast<QAbstractButton *>(m_table->cellWidget(row, RECENT_SELECT_COL))->isChecked()) {
100 files.append(m_table->item(row, RECENT_PATH_COL)->text());
101 }
102 }
103
104 sendFiles(files, LINK_FILE);
105 }
106
resendPressed()107 void SendingHandler::resendPressed() {
108 QStringList files;
109
110 for (int row = 0; row < m_table->rowCount(); row++){
111 if (sender() == m_table->cellWidget(row, RECENT_RESEND_COL)) {
112 files.append(m_table->item(row, RECENT_PATH_COL)->text());
113 break;
114 }
115 }
116
117 sendFiles(files, LINK_FILE);
118 }
119
removeRow()120 void SendingHandler::removeRow() {
121 for (int row = 0; row < m_table->rowCount(); row++){
122 if (sender() == m_table->cellWidget(row, RECENT_REMOVE_COL)) {
123 m_table->removeRow(row);
124 break;
125 }
126 }
127 }
128
dragOccured(QDragEnterEvent * e)129 bool SendingHandler::dragOccured(QDragEnterEvent *e) {
130 if (guiSend || guiReceive || guiDebug) {
131 e->ignore();
132 return false;
133 }
134
135 for (QUrl &url : e->mimeData()->urls()) {
136 QFileInfo file(url.fileName());
137 QString fileExtension = file.suffix().toLower();
138 if (!pathHasBundleExtension(fileExtension) && !valid_suffixes.contains(fileExtension)) {
139 e->ignore();
140 return false;
141 }
142 }
143
144 e->accept();
145 return true;
146 }
147
sentFile(const QString & file,int ok)148 void SendingHandler::sentFile(const QString &file, int ok) {
149
150 static int result = LINK_GOOD;
151 result |= ok;
152
153 // Send null to complete sending
154 if (file.isEmpty()) {
155 if (result & LINK_ERR) {
156 QMessageBox::critical(Q_NULLPTR, QObject::tr("Transfer error"), QObject::tr("Transfer Error, see console for information."));
157 }
158 else if (result & LINK_WARN) {
159 QMessageBox::warning(Q_NULLPTR, QObject::tr("Transfer warning"), QObject::tr("Transfer Warning, see console for information."));
160 }
161 result = LINK_GOOD;
162 m_progressBar->setValue(m_progressBar->maximum());
163 guiDelay(100);
164 if (m_progressBar) {
165 m_progressBar->setVisible(false);
166 m_progressBar->setValue(0);
167 }
168 guiSend = false;
169 return;
170 }
171
172 QFileInfo fi(file);
173 QString directory = fi.absolutePath();
174
175 // check for sending of equate file
176 if (m_sendEquates) {
177 if (!m_dirs.contains(directory)) {
178 m_dirs.append(directory);
179 checkDirForEquateFiles(directory);
180 }
181 }
182
183 // don't add temp files (created by bundles)
184 if (directory != m_tempDir.path()) {
185 addFile(file, true);
186 }
187
188 if (m_progressBar) {
189 m_progressBar->setValue(m_progressBar->value() + 1);
190 }
191 }
192
193
addFile(const QString & file,bool select)194 void SendingHandler::addFile(const QString &file, bool select) {
195 int j, rows = m_table->rowCount();
196
197 for (j = 0; j < rows; j++) {
198 if (!m_table->item(j, RECENT_PATH_COL)->text().compare(file, Qt::CaseInsensitive)) {
199 return;
200 }
201 }
202
203 m_table->setSortingEnabled(false);
204
205 m_table->setRowCount(rows + 1);
206 QTableWidgetItem *remove = new QTableWidgetItem;
207 QTableWidgetItem *resend = new QTableWidgetItem;
208 QTableWidgetItem *selected = new QTableWidgetItem;
209 QTableWidgetItem *path = new QTableWidgetItem(file);
210
211 QIcon removeIcon(QPixmap(QStringLiteral(":/icons/resources/icons/exit.png")));
212 QToolButton *btnRemove = new QToolButton;
213 btnRemove->setIcon(removeIcon);
214
215 QToolButton *btnResend = new QToolButton;
216 btnResend->setIcon(m_iconSend);
217
218 QToolButton *btnSelect = new QToolButton;
219 btnSelect->setIcon(select ? m_iconCheck : m_iconCheckGray);
220 btnSelect->setCheckable(true);
221 btnSelect->setChecked(select);
222
223 connect(btnResend, &QToolButton::clicked, this, &SendingHandler::resendPressed);
224 connect(btnRemove, &QToolButton::clicked, this, &SendingHandler::removeRow);
225 connect(btnSelect, &QToolButton::clicked, [this, btnSelect](bool checked) { btnSelect->setIcon(checked ? m_iconCheck : m_iconCheckGray); });
226
227 m_table->setItem(rows, RECENT_REMOVE_COL, remove);
228 m_table->setItem(rows, RECENT_RESEND_COL, resend);
229 m_table->setItem(rows, RECENT_SELECT_COL, selected);
230 m_table->setItem(rows, RECENT_PATH_COL, path);
231 m_table->setCellWidget(rows, RECENT_REMOVE_COL, btnRemove);
232 m_table->setCellWidget(rows, RECENT_RESEND_COL, btnResend);
233 m_table->setCellWidget(rows, RECENT_SELECT_COL, btnSelect);
234
235 m_table->setVisible(false);
236 m_table->resizeColumnsToContents();
237 m_table->setVisible(true);
238 m_table->setSortingEnabled(true);
239 }
240
sendFiles(const QStringList & fileNames,int location)241 void SendingHandler::sendFiles(const QStringList &fileNames, int location) {
242 QStringList list = fileNames;
243
244 if (guiSend || guiReceive || guiDebug || !list.size()) {
245 return;
246 }
247
248 guiSend = true;
249 m_dirs.clear();
250
251 foreach(const QString &str, fileNames) {
252 if (pathHasBundleExtension(str)) {
253 list.removeOne(str);
254 list.append(getValidFilesFromArchive(str));
255 addFile(str, true);
256 }
257 }
258
259 if (m_progressBar) {
260 m_progressBar->setVisible(true);
261 m_progressBar->setMaximum(list.size());
262 }
263
264 emit send(list, location);
265 }
266
setLoadEquates(bool state)267 void SendingHandler::setLoadEquates(bool state) {
268 m_sendEquates = state;
269 }
270
checkDirForEquateFiles(QString & dirPath)271 void SendingHandler::checkDirForEquateFiles(QString &dirPath) {
272 QDirIterator dirIt(dirPath, QDirIterator::NoIteratorFlags);
273 while (dirIt.hasNext()) {
274 dirIt.next();
275 QString dirItFile = dirIt.filePath();
276 if (QFileInfo(dirItFile).isFile()) {
277 QString suffix = QFileInfo(dirItFile).suffix();
278 if (suffix == QStringLiteral("map") ||
279 suffix == QStringLiteral("inc") ||
280 suffix == QStringLiteral("lab")) {
281 emit loadEquateFile(dirItFile);
282 }
283 }
284 }
285 }
286