1
// This module implements the QsciMacro class.
3
// Copyright (c) 2008 Riverbank Computing Limited <info@riverbankcomputing.com>
5
// This file is part of QScintilla.
7
// This file may be used under the terms of the GNU General Public
8
// License versions 2.0 or 3.0 as published by the Free Software
9
// Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
10
// included in the packaging of this file. Alternatively you may (at
11
// your option) use any later version of the GNU General Public
12
// License if such license has been publicly approved by Riverbank
13
// Computing Limited (or its successors, if any) and the KDE Free Qt
14
// Foundation. In addition, as a special exception, Riverbank gives you
15
// certain additional rights. These rights are described in the Riverbank
16
// GPL Exception version 1.1, which can be found in the file
17
// GPL_EXCEPTION.txt in this package.
19
// Please review the following information to ensure GNU General
20
// Public Licensing requirements will be met:
21
// http://trolltech.com/products/qt/licenses/licensing/opensource/. If
22
// you are unsure which license is appropriate for your use, please
23
// review the following information:
24
// http://trolltech.com/products/qt/licenses/licensing/licensingoverview
25
// or contact the sales department at sales@riverbankcomputing.com.
27
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
28
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
29
// A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
32
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
33
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
36
#include "Qsci/qscimacro.h"
38
#include <qstringlist.h>
40
#include "Qsci/qsciscintilla.h"
43
static int fromHex(unsigned char ch);
48
QsciMacro::QsciMacro(QsciScintilla *parent)
49
: QObject(parent), qsci(parent)
54
// The ctor that initialises the macro.
55
QsciMacro::QsciMacro(const QString &asc, QsciScintilla *parent)
56
: QObject(parent), qsci(parent)
63
QsciMacro::~QsciMacro()
68
// Clear the contents of the macro.
69
void QsciMacro::clear()
75
// Read a macro from a string.
76
bool QsciMacro::load(const QString &asc)
82
QStringList fields = asc.split(' ');
86
while (f < fields.size())
91
// Extract the 3 fixed fields.
92
if (f + 3 > fields.size())
98
cmd.msg = fields[f++].toUInt(&ok);
103
cmd.wParam = fields[f++].toULong(&ok);
108
len = fields[f++].toUInt(&ok);
116
if (f + 1 > fields.size())
122
cmd.text.resize(len - 1);
124
QByteArray ba = fields[f++].toAscii();
125
const char *sp = ba.data();
127
char *dp = cmd.text.data();
141
if (ch == '"' || ch <= ' ' || ch >= 0x7f)
151
if ((b1 = fromHex(*sp++)) < 0 ||
152
(b2 = fromHex(*sp++)) < 0)
178
// Write a macro to a string.
179
QString QsciMacro::save() const
183
QList<Macro>::const_iterator it;
185
for (it = macro.begin(); it != macro.end(); ++it)
190
unsigned len = (*it).text.size();
193
ms += m.sprintf("%u %lu %u", (*it).msg, (*it).wParam, len);
197
// In Qt v3, if the length is greater than zero then it also
198
// includes the '\0', so we need to make sure that Qt v4 writes the
199
// '\0'. (That the '\0' is written at all is probably a historical
200
// bug - using size() instead of length() - which we don't fix so
201
// as not to break old macros.)
206
const char *cp = (*it).text.data();
210
unsigned char ch = *cp++;
212
if (ch == '\\' || ch == '"' || ch <= ' ' || ch >= 0x7f)
216
ms += buf.sprintf("\\%02x", ch);
229
void QsciMacro::play()
234
QList<Macro>::const_iterator it;
236
for (it = macro.begin(); it != macro.end(); ++it)
237
qsci->SendScintilla((*it).msg, (*it).wParam, (*it).text.data());
242
void QsciMacro::startRecording()
249
connect(qsci, SIGNAL(SCN_MACRORECORD(unsigned int, unsigned long, void *)),
250
SLOT(record(unsigned int, unsigned long, void *)));
252
qsci->SendScintilla(QsciScintillaBase::SCI_STARTRECORD);
257
void QsciMacro::endRecording()
262
qsci->SendScintilla(QsciScintillaBase::SCI_STOPRECORD);
263
qsci->disconnect(this);
268
void QsciMacro::record(unsigned int msg, unsigned long wParam, void *lParam)
275
// Determine commands which need special handling of the parameters.
278
case QsciScintillaBase::SCI_ADDTEXT:
279
m.text = QByteArray(reinterpret_cast<const char *>(lParam), wParam);
282
case QsciScintillaBase::SCI_REPLACESEL:
283
if (!macro.isEmpty() && macro.last().msg == QsciScintillaBase::SCI_REPLACESEL)
285
// This is the command used for ordinary user input so it's a
286
// significant space reduction to append it to the previous
289
macro.last().text.append(reinterpret_cast<const char *>(lParam));
295
case QsciScintillaBase::SCI_INSERTTEXT:
296
case QsciScintillaBase::SCI_APPENDTEXT:
297
case QsciScintillaBase::SCI_SEARCHNEXT:
298
case QsciScintillaBase::SCI_SEARCHPREV:
299
m.text.append(reinterpret_cast<const char *>(lParam));
307
// Return the given hex character as a binary.
308
static int fromHex(unsigned char ch)
310
if (ch >= '0' && ch <= '9')
313
if (ch >= 'a' && ch <= 'f')
314
return ch - 'a' + 10;