summaryrefslogtreecommitdiffstats
path: root/tqt/tqextscintillamacro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqt/tqextscintillamacro.cpp')
-rw-r--r--tqt/tqextscintillamacro.cpp334
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"