8#include <QtGui/QGuiApplication>
9#include <QtGui/QClipboard>
14 : QStringListModel(parent)
17 qCDebug(MAVLinkConsoleControllerLog) <<
this;
21 _setActiveVehicle(MultiVehicleManager::instance()->activeVehicle());
28 _sendSerialData(msg,
true);
31 qCDebug(MAVLinkConsoleControllerLog) <<
this;
36 QString output = command;
39 const QStringList lines = output.split(
'\n');
40 for (
const QString &line : lines) {
41 if (!line.isEmpty()) {
42 _history.append(line);
46 (void) output.append(
"\n");
47 _sendSerialData(qPrintable(output));
53 QString clipboardData = command_pre + QGuiApplication::clipboard()->text();
55 const int lastLinePos = clipboardData.lastIndexOf(
'\n');
56 if (lastLinePos != -1) {
57 const QString commands = clipboardData.mid(0, lastLinePos);
59 clipboardData = clipboardData.mid(lastLinePos + 1);
65void MAVLinkConsoleController::_setActiveVehicle(
Vehicle *vehicle)
67 for (QMetaObject::Connection &con : _connections) {
68 (void) disconnect(con);
74 _incomingBuffer.clear();
76 setStringList(QStringList());
84void MAVLinkConsoleController::_receiveData(uint8_t device, uint8_t flags, uint16_t timeout, uint32_t baudrate,
const QByteArray &data)
86 Q_UNUSED(flags); Q_UNUSED(timeout); Q_UNUSED(baudrate);
88 if (device != SERIAL_CONTROL_DEV_SHELL) {
93 (void) _incomingBuffer.append(data);
95 while (!_incomingBuffer.isEmpty()) {
98 int idx = _incomingBuffer.indexOf(
'\n');
101 idx = _incomingBuffer.size();
106 QByteArray fragment = _incomingBuffer.mid(0, idx);
107 if (!_processANSItext(fragment)) {
112 _writeLine(_cursorY, fragment);
117 const int rc = rowCount();
118 if (_cursorY >= rc) {
119 (void) insertRows(rc, 1 + _cursorY - rc);
123 (void) _incomingBuffer.remove(0, idx + (newline ? 1 : 0));
127void MAVLinkConsoleController::_sendSerialData(
const QByteArray &data,
bool close)
130 qCWarning(MAVLinkConsoleControllerLog) <<
"Internal error";
140 QByteArray output(data);
141 while (output.size()) {
142 QByteArray chunk(output.left(MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN));
143 const int dataSize = chunk.size();
146 (void) chunk.append(MAVLINK_MSG_SERIAL_CONTROL_FIELD_DATA_LEN - chunk.size(),
'\0');
148 const uint8_t flags =
close ? 0 : SERIAL_CONTROL_FLAG_EXCLUSIVE | SERIAL_CONTROL_FLAG_RESPOND | SERIAL_CONTROL_FLAG_MULTI;
151 (void) mavlink_msg_serial_control_pack_chan(
154 sharedLink->mavlinkChannel(),
156 SERIAL_CONTROL_DEV_SHELL,
161 reinterpret_cast<uint8_t*
>(chunk.data()),
167 (void) output.remove(0, chunk.size());
171bool MAVLinkConsoleController::_processANSItext(QByteArray &line)
174 for (
int i = 0; i < line.size(); i++) {
175 if (line[i] !=
'\x1B') {
180 if ((i >= (line.size() - 2)) || (line[i + 1] !=
'[')) {
186 switch (line[i + 2]) {
188 if (_cursorHomePos == -1) {
190 _cursorHomePos = _cursorY;
193 _cursorY = _cursorHomePos;
199 if (_cursorY < rowCount()) {
200 const QModelIndex idx = index(_cursorY);
201 QString updated = data(idx, Qt::DisplayRole).toString();
202 const int eraseIdx = _cursorX + i;
203 if (eraseIdx < updated.length()) {
204 (void) setData(idx, updated.remove(eraseIdx, updated.length()));
210 if (i >= (line.size() - 3)) {
214 if ((line[i + 3] ==
'J') && (_cursorHomePos != -1)) {
216 const bool blocked = blockSignals(
true);
217 for (
int j = _cursorHomePos; j < rowCount(); j++) {
218 (void) setData(index(j),
"");
220 (void) blockSignals(blocked);
222 const QVector<int> roles({Qt::DisplayRole, Qt::EditRole});
223 emit dataChanged(index(_cursorY), index(rowCount()), roles);
227 (void) line.remove(i + 3,1);
234 (void) line.remove(i, 3);
241QString MAVLinkConsoleController::_transformLineForRichText(
const QString &line)
const
243 QString ret = line.toHtmlEscaped().replace(
" ",
" ").replace(
"\t",
" ");
245 if (ret.startsWith(
"WARN", Qt::CaseSensitive)) {
246 (void) ret.replace(0, 4,
"<font color=\"" + _palette->colorOrange().name() +
"\">WARN</font>");
247 }
else if (ret.startsWith(
"ERROR", Qt::CaseSensitive)) {
248 (void) ret.replace(0, 5,
"<font color=\"" + _palette->colorRed().name() +
"\">ERROR</font>");
254QString MAVLinkConsoleController::_getText()
const
257 if (rowCount() > 0) {
258 ret = _transformLineForRichText(data(index(0), Qt::DisplayRole).toString());
261 for (
int i = 1; i < rowCount(); ++i) {
262 ret += (
"<br>" + _transformLineForRichText(data(index(i), Qt::DisplayRole).toString()));
268void MAVLinkConsoleController::_writeLine(
int line,
const QByteArray &text)
270 const int rc = rowCount();
272 (void) insertRows(rc, 1 + line - rc);
275 if (rowCount() > kMaxNumLines) {
276 const int count = rowCount() - kMaxNumLines;
277 (void) removeRows(0, count);
280 _cursorHomePos -= count;
281 if (_cursorHomePos < 0) {
286 const QModelIndex idx = index(line);
287 QString updated = data(idx, Qt::DisplayRole).toString();
288 (void) updated.replace(_cursorX, text.size(), text);
289 (void) setData(idx, updated);
290 _cursorX += text.size();
293void MAVLinkConsoleController::CommandHistory::append(
const QString &command)
295 if (!command.isEmpty()) {
297 if ((_history.isEmpty()) || (_history.last() != command)) {
298 if (_history.length() >= CommandHistory::kMaxHistoryLength) {
299 _history.removeFirst();
301 _history.append(command);
305 _index = _history.length();
308QString MAVLinkConsoleController::CommandHistory::up(
const QString ¤t)
315 if (_index < _history.length()) {
316 return _history[_index];
319 return QStringLiteral(
"");
322QString MAVLinkConsoleController::CommandHistory::down(
const QString ¤t)
324 if (_index >= _history.length()) {
329 if (_index < _history.length()) {
330 return _history[_index];
333 return QStringLiteral(
"");
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void sendCommand(const QString &command)
~MAVLinkConsoleController()
QString handleClipboard(const QString &command_pre)
static int getComponentId()
Get the component id of this application.
static MAVLinkProtocol * instance()
int getSystemId() const
Get the system id of this application.
void activeVehicleChanged(Vehicle *activeVehicle)
WeakLinkInterfacePtr primaryLink() const
VehicleLinkManager * vehicleLinkManager()
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
int defaultComponentId() const
void mavlinkSerialControl(uint8_t device, uint8_t flags, uint16_t timeout, uint32_t baudrate, QByteArray data)