diff options
Diffstat (limited to 'tqt/tqextscintillamacro.cpp')
-rw-r--r-- | tqt/tqextscintillamacro.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/tqt/tqextscintillamacro.cpp b/tqt/tqextscintillamacro.cpp new file mode 100644 index 0000000..8fc1a72 --- /dev/null +++ b/tqt/tqextscintillamacro.cpp @@ -0,0 +1,334 @@ +// This module implements the TQextScintillaMacro class. +// +// Copyright (c) 2006 +// Riverbank Computing Limited <info@riverbankcomputing.co.uk> +// +// This file is part of TQScintilla. +// +// This copy of TQScintilla is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) any +// later version. +// +// TQScintilla is supplied in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// TQScintilla; see the file LICENSE. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <string.h> + +#include <tqstring.h> + +#include "tqextscintillamacro.h" +#include "tqextscintilla.h" + + +static TQCString extract(const TQCString &asc,int &start); +static int fromHex(unsigned char ch); + + +// The ctor. +TQextScintillaMacro::TQextScintillaMacro(TQextScintilla *parent,const char *name) + : TQObject(parent,name), tqsci(parent) +{ +} + + +// The ctor that initialises the macro. +TQextScintillaMacro::TQextScintillaMacro(const TQCString &asc, + TQextScintilla *parent,const char *name) + : TQObject(parent,name), tqsci(parent) +{ + load(asc); +} + + +// The dtor. +TQextScintillaMacro::~TQextScintillaMacro() +{ +} + + +// Clear the contents of the macro. +void TQextScintillaMacro::clear() +{ + macro.clear(); +} + + +// Read a macro from a string. +bool TQextScintillaMacro::load(const TQCString &asc) +{ + bool rc = TRUE; + + macro.clear(); + + int pos = 0; + + while (pos < asc.length()) + { + TQCString fld; + Macro cmd; + unsigned len; + + // Extract the 3 fixed fields. + fld = extract(asc,pos); + cmd.msg = fld.toUInt(&rc); + + if (!rc) + break; + + fld = extract(asc,pos); + cmd.wParam = fld.toULong(&rc); + + if (!rc) + break; + + fld = extract(asc,pos); + len = fld.toUInt(&rc); + + if (!rc) + break; + + // Extract any text. + if (len) + { + cmd.text.resize(len); + fld = extract(asc,pos); + + char *dp = cmd.text.data(); + const char *sp = fld; + + if (!sp) + { + rc = FALSE; + break; + } + + while (len--) + { + unsigned char ch; + + ch = *sp++; + + if (ch == '"' || ch <= ' ' || ch >= 0x7f) + { + rc = FALSE; + break; + } + + if (ch == '\\') + { + int b1, b2; + + if ((b1 = fromHex(*sp++)) < 0 || + (b2 = fromHex(*sp++)) < 0) + { + rc = FALSE; + break; + } + + ch = (b1 << 4) + b2; + } + + *dp++ = ch; + } + + if (!rc) + break; + } + + macro.append(cmd); + } + + if (!rc) + macro.clear(); + + return rc; +} + + +// Write a macro to a string. +TQCString TQextScintillaMacro::save() const +{ + TQCString ms; + + for (TQValueList<Macro>::const_iterator it = macro.begin(); it != macro.end(); ++it) + { + if (!ms.isEmpty()) + ms += ' '; + + unsigned len = (*it).text.size(); + TQCString m; + + m.sprintf("%u %lu %u",(*it).msg,(*it).wParam,len); + + if (len) + { + m += ' '; + + const char *cp = (*it).text.data(); + + while (len--) + { + unsigned char ch = *cp++; + + if (ch == '\\' || ch == '"' || ch <= ' ' || ch >= 0x7f) + { + char buf[4]; + + sprintf(buf,"\\%02x",ch); + m += buf; + } + else + m += ch; + } + } + + ms += m; + } + + return ms; +} + + +// Play the macro. +void TQextScintillaMacro::play() +{ + if (!tqsci) + return; + + for (TQValueList<Macro>::const_iterator it = macro.begin(); it != macro.end(); ++it) + tqsci -> SendScintilla((*it).msg,(*it).wParam,(*it).text.data()); +} + + +// Start recording. +void TQextScintillaMacro::startRecording() +{ + if (!tqsci) + return; + + macro.clear(); + + connect(tqsci, + TQT_SIGNAL(SCN_MACRORECORD(unsigned int,unsigned long,long)), + TQT_SLOT(record(unsigned int,unsigned long,long))); + + tqsci -> SendScintilla(TQextScintillaBase::SCI_STARTRECORD); +} + + +// End recording. +void TQextScintillaMacro::endRecording() +{ + if (!tqsci) + return; + + tqsci -> SendScintilla(TQextScintillaBase::SCI_STOPRECORD); + tqsci -> disconnect(this); +} + + +// Record a command. +void TQextScintillaMacro::record(unsigned int msg,unsigned long wParam, + long lParam) +{ + Macro m; + + m.msg = msg; + m.wParam = wParam; + + // Determine commands which need special handling of the parameters. + switch (msg) + { + case TQextScintillaBase::SCI_ADDTEXT: + m.text.duplicate(reinterpret_cast<const char *>(lParam),wParam); + break; + + case TQextScintillaBase::SCI_REPLACESEL: + if (!macro.isEmpty() && macro.last().msg == TQextScintillaBase::SCI_REPLACESEL) + { + const char *text = reinterpret_cast<const char *>(lParam); + + // This is the command used for ordinary user input so + // it's a signifacant space reduction to append it to + // the previous command. + + TQByteArray &ba = macro.last().text; + + unsigned pos = ba.size() - 1; + + // Make room for the new text. + ba.resize(ba.size() + strlen(text)); + + // Copy it in. + strcpy(ba.data() + pos,text); + + return; + } + + /* Drop through. */ + + case TQextScintillaBase::SCI_INSERTTEXT: + case TQextScintillaBase::SCI_APPENDTEXT: + case TQextScintillaBase::SCI_SEARCHNEXT: + case TQextScintillaBase::SCI_SEARCHPREV: + { + const char *text = reinterpret_cast<const char *>(lParam); + + m.text.duplicate(text,strlen(text) + 1); + break; + } + } + + macro.append(m); +} + + +// Extract a macro field starting at the given position. +static TQCString extract(const TQCString &asc,int &fstart) +{ + TQCString f; + + if (fstart < asc.length()) + { + int fend = asc.find(' ',fstart); + + if (fend < 0) + { + f = asc.mid(fstart); + fstart = asc.length(); + } + else + { + f = asc.mid(fstart,fend - fstart); + fstart = fend + 1; + } + } + + return f; +} + + +// Return the given hex character as a binary. +static int fromHex(unsigned char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + + if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + + return -1; +} + +#include "tqextscintillamacro.moc" |