Logo Search packages:      
Sourcecode: gambas version File versions  Download package

CEditor.cpp

/***************************************************************************

  CEditor.cpp

  (c) 2000-2003 Benoît Minisini <gambas@users.sourceforge.net>

  WIDGET program 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 1, or (at your option)
  any later version.

  WIDGET program is distributed 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 WIDGET program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

***************************************************************************/


#define __CEDITOR_CPP

#include "main.h"

#include <qobject.h>
#include <qpalette.h>
#include "qeditor.h"

#include "CEditor.h"

static long EVENT_Change;    /* text has changed */
static long EVENT_Cursor;    /* cursor has moved */
DECLARE_EVENT(EVENT_Scroll);


static void look_pos(QEditor *wid, int *line, int *col)
{
  if (*line == -1)
    *line = wid->numLines();

  if (*col == -1)
    *col = wid->lineLength(*line);
}



static QString purge(QString & s)
{
  QString r;
  QChar c;
  uint i;
  bool space = false;
  char wait = 0;

  for (i = 0; i < s.length(); i++)
  {
    c = s[i];

    switch(wait)
    {
      case 0:

        if (space)
          c = ' ';
        else if (c == '"')
          wait = '"';
        else if (c == '\'')
          space = true;

        break;

      case '"':
        if (c == '"')
          wait = 0;
        else
          c = ' ';
        break;
    }

    r += c;
  }

  s = r;
  return s;
}


static void *analyze_symbol = 0;
static void *analyze_type = 0;
static void *analyze_pos = 0;

static void analyze(QString &s)
{
  ColorDataArray data;
  GB_ARRAY garray, tarray, parray;
  uint i, n, pos, len, p;
  char *str;

  QEditorRow::analyze(s, data);

  n = 0;
  for (i = 0; i < data.count(); i++)
  {
    if (data[i].state != QEditorRow::Normal)
      n++;
  }

  //n = data.count() >> 1;
  GB.Array.New(&garray, GB_T_STRING, n);
  GB.Array.New(&tarray, GB_T_INTEGER, n);
  GB.Array.New(&parray, GB_T_INTEGER, n);

  pos = 0;
  i = 0;
  for (p = 0; p < data.count(); p++)
  {
    len = data[p].len;

    if (data[p].state != QEditorRow::Normal)
    {
      GB.NewString(&str, TO_UTF8(s.mid(pos, len)), 0);
      *((char **)GB.Array.Get(garray, i)) = str;
      *((int *)GB.Array.Get(tarray, i)) = data[p].state;
      *((int *)GB.Array.Get(parray, i)) = pos;
      i++;
    }

    pos += len;
  }

  GB.Unref(&analyze_symbol);
  analyze_symbol = garray;
  GB.Ref(garray);
  
  GB.Unref(&analyze_type);
  analyze_type = tarray;
  GB.Ref(tarray);
  
  GB.Unref(&analyze_pos);
  analyze_pos = parray;
  GB.Ref(parray);
}


BEGIN_METHOD(CEDITOR_new, GB_OBJECT parent)

  QEditor *wid = new QEditor(QT.GetContainer(VARG(parent)));

  QObject::connect(wid, SIGNAL(textChanged()), &CEditor::manager, SLOT(changed()));
  QObject::connect(wid, SIGNAL(cursorMoved()), &CEditor::manager, SLOT(moved()));
  QObject::connect(wid, SIGNAL(contentsMoving(int, int)), &CEditor::manager, SLOT(scrolled(int, int)));

  QT.InitWidget(wid, _object);

  wid->show();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_exit)

  GB.Unref(&analyze_symbol);
  GB.Unref(&analyze_type);
  GB.Unref(&analyze_pos);

END_METHOD


BEGIN_PROPERTY(CEDITOR_text)

  if (READ_PROPERTY)
    GB.ReturnNewZeroString(TO_UTF8(WIDGET->text()));
  else
  {
    WIDGET->setText(QSTRING_PROP());
    WIDGET->setEdited(false);
  }

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_length)

  GB.ReturnInteger(WIDGET->length());

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_line)

  int line, col;

  WIDGET->cursorPosition(&line, &col);

  if (READ_PROPERTY)
    GB.ReturnInteger(line);
  else
  {
    line = VPROP(GB_INTEGER);
    look_pos(WIDGET, &line, &col);

    WIDGET->setCursorPosition(line, col);
  }

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_column)

  int line, col;

  WIDGET->getCursorPosition(&line, &col);

  if (READ_PROPERTY)
    GB.ReturnInteger(col);
  else
  {
    col = VPROP(GB_INTEGER);
    look_pos(WIDGET, &line, &col);

    WIDGET->setCursorPosition(line, col);
  }

END_PROPERTY


BEGIN_METHOD(CEDITOR_goto, GB_INTEGER line; GB_INTEGER col)

  WIDGET->setCursorPosition(VARG(line), VARG(col));

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_ensure_visible)

  int line, col;

  WIDGET->getCursorPosition(&line, &col);
  WIDGET->ensureLineVisible(line);

END_METHOD


BEGIN_PROPERTY(CEDITOR_pos)

  int line, col;

  if (READ_PROPERTY)
  {
    WIDGET->getCursorPosition(&line, &col);
    GB.ReturnInteger(WIDGET->toPos(line, col));
  }
  else
  {
    WIDGET->fromPos(VPROP(GB_INTEGER), &line, &col);
    WIDGET->setCursorPosition(line, col);
  }

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_lines)

  RETURN_SELF();

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_line_count)

  GB.ReturnInteger((long)WIDGET->numLines());

END_PROPERTY


BEGIN_METHOD(CEDITOR_line_get, GB_INTEGER line)

  long line = VARG(line);

  if (line < 0 || line >= WIDGET->numLines())
    GB.ReturnNull();
  else
    GB.ReturnNewZeroString(TO_UTF8(WIDGET->textLine(line)));

END_METHOD


BEGIN_METHOD(CEDITOR_line_put, GB_STRING text; GB_INTEGER line)

  long line = VARG(line);
  QString s;

  if (line >= 0 && line < WIDGET->numLines())
  {
    s = QSTRING_PROP();
    WIDGET->setTextLine(line, s);
  }

END_METHOD


BEGIN_METHOD(CEDITOR_purge_line, GB_INTEGER line)

  long line = VARG(line);
  QString s;

  if (line < 0 || line >= WIDGET->numLines())
    GB.ReturnNull();
  else
  {
    s = WIDGET->textLine(line);
    GB.ReturnNewZeroString(TO_UTF8(purge(s)));
  }

END_METHOD


BEGIN_METHOD(CEDITOR_analyze, GB_STRING text)

  QString s = QSTRING_ARG(text);

  analyze(s);
  GB.ReturnObject(analyze_symbol);

END_METHOD


BEGIN_PROPERTY(CEDITOR_analyze_symbols)

  GB.ReturnObject(analyze_symbol);

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_analyze_types)

  GB.ReturnObject(analyze_type);

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_analyze_positions)

  GB.ReturnObject(analyze_pos);

END_PROPERTY


BEGIN_METHOD(CEDITOR_line_get_flag, GB_INTEGER line; GB_INTEGER flag)

  long line = VARG(line);

  if (line >= 0 && line < WIDGET->numLines())
    GB.ReturnBoolean(WIDGET->lineType(line) & (1 << VARG(flag)));
  else
    GB.ReturnBoolean(false);

END_METHOD


BEGIN_METHOD(CEDITOR_line_set_flag, GB_INTEGER line; GB_INTEGER flag; GB_BOOLEAN value)

  long line = VARG(line);

  if (line >= 0 && line < WIDGET->numLines())
  {
    long flag = WIDGET->lineType(line);
    if (VARG(value))
      WIDGET->setLineType(line, flag | (1 << VARG(flag)) );
    else
      WIDGET->setLineType(line, flag & ~(1 << VARG(flag)) );
  }

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_clear)

  WIDGET->clear();

END_METHOD


BEGIN_METHOD(CEDITOR_insert, GB_STRING text)

  WIDGET->insert(QSTRING_ARG(text));

END_METHOD


/***************************************************************************

  .GambasEditor.Selection

***************************************************************************/

BEGIN_PROPERTY(CEDITOR_sel_text)

  if (READ_PROPERTY)
    GB.ReturnNewZeroString(TO_UTF8(WIDGET->markedText()));
  else
    WIDGET->insert(QSTRING_PROP());

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_sel_length)

  long start, length;

  WIDGET->getSelection(&start, &length);
  GB.ReturnInteger(length);

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_sel_start)

  long start, length;

  WIDGET->getSelection(&start, &length);
  GB.ReturnInteger(start);

END_PROPERTY


BEGIN_METHOD_VOID(CEDITOR_sel_clear)

  WIDGET->deselect();

END_METHOD


// BEGIN_METHOD_VOID(CEDITOR_sel_all)
//
//  WIDGET->selectAll();
//
// END_METHOD


BEGIN_METHOD(CEDITOR_sel_select, GB_INTEGER start; GB_INTEGER length)

  if (MISSING(start) && MISSING(length))
    WIDGET->selectAll();
  else if (!MISSING(start) && !MISSING(length))
    WIDGET->setSelection(VARG(start), VARG(length));

END_METHOD


BEGIN_METHOD(CEDITOR_to_pos, GB_INTEGER line; GB_INTEGER column)

  GB.ReturnInteger(WIDGET->toPos(VARG(line), VARG(column)));

END_METHOD


BEGIN_METHOD(CEDITOR_to_line, GB_INTEGER pos)

  int line, col;

  WIDGET->fromPos(VARG(pos), &line, &col);

  GB.ReturnInteger(line);

END_METHOD


BEGIN_METHOD(CEDITOR_to_col, GB_INTEGER pos)

  int line, col;

  WIDGET->fromPos(VARG(pos), &line, &col);

  GB.ReturnInteger(col);

END_METHOD



BEGIN_METHOD(CEDITOR_find_next_breakpoint, GB_INTEGER line)

  GB.ReturnInteger(WIDGET->findNextBreakpoint(VARG(line)));

END_METHOD


BEGIN_METHOD(CEDITOR_color_get, GB_INTEGER index)

  int index = VARG(index);

  if (index < 0 || index >= NUM_COLORS)
  {
    GB.Error("Bad index");
    return;
  }

  GB.ReturnInteger(WIDGET->getColor(index).rgb() & 0xFFFFFF);

END_METHOD


BEGIN_METHOD(CEDITOR_color_set, GB_INTEGER color; GB_INTEGER index)

  int index = VARG(index);

  if (index < 0 || index >= NUM_COLORS)
  {
    GB.Error("Bad index");
    return;
  }

  WIDGET->setColor(index, QColor((QRgb)VARG(color)));

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_copy)

  WIDGET->copy();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_cut)

  WIDGET->cut();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_paste)

  WIDGET->paste();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_undo)

  WIDGET->undo();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_redo)

  WIDGET->redo();

END_METHOD


BEGIN_METHOD(CEDITOR_indent, GB_BOOLEAN back)

  WIDGET->indent(VARGOPT(back, false));

END_METHOD


BEGIN_PROPERTY(CEDITOR_read_only)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isReadOnly());
  else
    WIDGET->setReadOnly(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_highlight)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isUseColor());
  else
    WIDGET->setUseColor(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_show_proc)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isShowProc());
  else
    WIDGET->setShowProc(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_use_relief)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isUseRelief());
  else
    WIDGET->setUseRelief(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_show_current)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isShowCurrent());
  else
    WIDGET->setShowCurrent(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_show_change)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->isShowChange());
  else
    WIDGET->setShowChange(VPROP(GB_BOOLEAN));

END_PROPERTY

BEGIN_PROPERTY(CEDITOR_frozen)

  if (READ_PROPERTY)
    GB.ReturnBoolean(!WIDGET->autoUpdate());
  else
  {
    bool a = VPROP(GB_BOOLEAN) == 0;
    //if (!a)
    //  WIDGET->stopBlink();

    if (a)
      WIDGET->endUndo();
    else
      WIDGET->startUndo();

    WIDGET->setAutoUpdate(a);
    if (a)
    {
      WIDGET->updateContents();
      //WIDGET->startBlink();
    }
  }

END_PROPERTY


BEGIN_METHOD_VOID(CEDITOR_refresh)

  WIDGET->repaintContents();
  //WIDGET->updateContents();

END_METHOD


BEGIN_METHOD_VOID(CEDITOR_reset)

  WIDGET->resetChangedLines();
  //WIDGET->updateContents();

END_METHOD


BEGIN_PROPERTY(CEDITOR_tab_length)

  if (READ_PROPERTY)
    GB.ReturnInteger(WIDGET->tabSpace());
  else
    WIDGET->setTabSpace(VPROP(GB_INTEGER));

END_PROPERTY


/*
BEGIN_PROPERTY(CEDITOR_syntax)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->syntax);
  else
    WIDGET->syntax = VPROP(GB_BOOLEAN);

END_PROPERTY
*/

BEGIN_PROPERTY(CEDITOR_cursor_x)

  GB.ReturnInteger(WIDGET->posX(-1, -1));

END_PROPERTY


BEGIN_PROPERTY(CEDITOR_cursor_y)

  GB.ReturnInteger(WIDGET->posY(-1, -1));

END_PROPERTY


BEGIN_METHOD(CEDITOR_to_pos_x, GB_INTEGER x)

  GB.ReturnInteger(WIDGET->posX(VARG(x), -1));

END_METHOD


BEGIN_PROPERTY(CEDITOR_line_height)

  GB.ReturnInteger(WIDGET->cellHeight());

END_PROPERTY


GB_DESC CEditorSelectionDesc[] =
{
  GB_DECLARE(".GambasEditor.Selection", 0), GB_VIRTUAL_CLASS(),

  GB_PROPERTY("Text", "s", CEDITOR_sel_text),
  GB_PROPERTY_READ("Length", "i", CEDITOR_sel_length),
  GB_PROPERTY_READ("Start", "i", CEDITOR_sel_start),

  GB_METHOD("Clear", NULL, CEDITOR_sel_clear, NULL),
  GB_METHOD("Set", NULL, CEDITOR_sel_select, "[(Start)i(Length)i]"),
  GB_METHOD("_call", NULL, CEDITOR_sel_select, "[(Start)i(Length)i]"),

  GB_END_DECLARE
};



GB_DESC CEditorLinesDesc[] =
{
  GB_DECLARE(".GambasEditor.Lines", 0), GB_VIRTUAL_CLASS(),

  GB_METHOD("_get", "s", CEDITOR_line_get, "(Line)i"),
  GB_METHOD("_put", NULL, CEDITOR_line_put, "(Text)s(Line)i"),
  GB_METHOD("SetFlag", NULL, CEDITOR_line_set_flag, "(Line)i(Flag)i(Value)b"),
  GB_METHOD("GetFlag", "b", CEDITOR_line_get_flag, "(Line)i(Flag)i"),
  GB_PROPERTY_READ("Count", "i", CEDITOR_line_count),

  GB_END_DECLARE
};


GB_DESC CEditorColorsDesc[] =
{
  GB_DECLARE(".GambasEditor.Colors", 0), GB_VIRTUAL_CLASS(),

  GB_METHOD("_get", "i", CEDITOR_color_get, "(Style)i"),
  GB_METHOD("_put", NULL, CEDITOR_color_set, "(Color)i(Style)i"),

  GB_CONSTANT("Background", "i", QEditorRow::Background),
  GB_CONSTANT("Normal", "i", QEditorRow::Normal),
  GB_CONSTANT("Keyword", "i", QEditorRow::Keyword),
  GB_CONSTANT("Function", "i", QEditorRow::Subr),
  GB_CONSTANT("Operator", "i", QEditorRow::Operator),
  GB_CONSTANT("Symbol", "i", QEditorRow::Symbol),
  GB_CONSTANT("Number", "i", QEditorRow::Number),
  GB_CONSTANT("String", "i", QEditorRow::String),
  GB_CONSTANT("Comment", "i", QEditorRow::Commentary),
  GB_CONSTANT("Breakpoint", "i", QEditorRow::Breakpoint),
  GB_CONSTANT("Current", "i", QEditorRow::Current),
  GB_CONSTANT("DataType", "i", QEditorRow::Datatype),
  GB_CONSTANT("Selection", "i", QEditorRow::Selection),
  GB_CONSTANT("Highlight", "i", QEditorRow::Highlight),
  GB_CONSTANT("Line", "i", QEditorRow::Line),

  GB_END_DECLARE
};



GB_DESC CEditorDesc[] =
{
  GB_DECLARE("GambasEditor", sizeof(CEDITOR)), GB_INHERITS("Control"),

  GB_CONSTANT("Current", "i", 0),
  GB_CONSTANT("Breakpoint", "i", 1),

  GB_METHOD("_new", NULL, CEDITOR_new, "(Parent)Container;"),
  GB_STATIC_METHOD("_exit", NULL, CEDITOR_exit, NULL),

  GB_PROPERTY("Text", "s", CEDITOR_text),
  GB_PROPERTY_READ("Length", "i", CEDITOR_length),

  GB_PROPERTY("Line", "i", CEDITOR_line),
  GB_PROPERTY("Column", "i", CEDITOR_column),
  GB_PROPERTY("Pos", "i", CEDITOR_pos),
  
  GB_METHOD("Goto", NULL, CEDITOR_goto, "(Line)i(Column)i"),
  GB_METHOD("EnsureVisible", NULL, CEDITOR_ensure_visible, NULL),
  
  GB_PROPERTY("Frozen", "b", CEDITOR_frozen),
  GB_PROPERTY("TabLength", "i", CEDITOR_tab_length),
  GB_METHOD("Reset", NULL, CEDITOR_reset, NULL),
  
  //GB_METHOD("CenterOn", NULL, CEDITOR_center_on, "(Line)i");
  //GB_PROPERTY("Syntax", "b", CEDITOR_syntax),

  GB_PROPERTY("ReadOnly", "b", CEDITOR_read_only),
  GB_PROPERTY("Highlight", "b", CEDITOR_highlight),
  GB_PROPERTY("ShowProc", "b", CEDITOR_show_proc),
  GB_PROPERTY("UseRelief", "b", CEDITOR_use_relief),
  GB_PROPERTY("ShowCurrent", "b", CEDITOR_show_current),
  GB_PROPERTY("ShowChange", "b", CEDITOR_show_change),

  GB_METHOD("Refresh", NULL, CEDITOR_refresh, NULL),
  GB_METHOD("Clear", NULL, CEDITOR_clear, NULL),
  GB_METHOD("Insert", NULL, CEDITOR_insert, "(Text)s"),
  GB_METHOD("Indent", NULL, CEDITOR_indent, "[(Back)b]"),

  GB_METHOD("Copy", NULL, CEDITOR_copy, NULL),
  GB_METHOD("Cut", NULL, CEDITOR_cut, NULL),
  GB_METHOD("Paste", NULL, CEDITOR_paste, NULL),
  GB_METHOD("Undo", NULL, CEDITOR_undo, NULL),
  GB_METHOD("Redo", NULL, CEDITOR_redo, NULL),

  GB_METHOD("ToPos", "i", CEDITOR_to_pos, "(Line)i(Column)i"),
  GB_METHOD("ToLine", "i", CEDITOR_to_line, "(Pos)i"),
  GB_METHOD("ToColumn", "i", CEDITOR_to_col, "(Pos)i"),
  
  GB_METHOD("ToPosX", "i", CEDITOR_to_pos_x, "(Column)i"),

  GB_PROPERTY_READ("Lines", ".GambasEditor.Lines", CEDITOR_lines),
  GB_PROPERTY_READ("Selection", ".GambasEditor.Selection", CEDITOR_lines),
  GB_PROPERTY_READ("Colors", ".GambasEditor.Colors", CEDITOR_lines),

  GB_METHOD("Select", NULL, CEDITOR_sel_select, "[(Start)i(Length)i]"),

  GB_METHOD("FindNextBreakpoint", "i", CEDITOR_find_next_breakpoint, "(Line)i"),
  GB_METHOD("PurgeLine", "s", CEDITOR_purge_line, "(Line)i"),

  GB_STATIC_METHOD("Analyze", "String[]", CEDITOR_analyze, "(Text)s"),
  GB_STATIC_PROPERTY_READ("Symbols", "String[]", CEDITOR_analyze_symbols),
  GB_STATIC_PROPERTY_READ("Types", "Integer[]", CEDITOR_analyze_types),
  GB_STATIC_PROPERTY_READ("Positions", "Integer[]", CEDITOR_analyze_positions),

  GB_PROPERTY_READ("CursorX", "i", CEDITOR_cursor_x),
  GB_PROPERTY_READ("CursorY", "i", CEDITOR_cursor_y),
  GB_PROPERTY_READ("LineHeight", "i", CEDITOR_line_height),

  GB_EVENT("Change", NULL, NULL, &EVENT_Change),
  GB_EVENT("Cursor", NULL, NULL, &EVENT_Cursor),
  GB_EVENT("Scroll", NULL, NULL, &EVENT_Scroll),

  GB_CONSTANT("_DefaultEvent", "s", "KeyPress"),
  GB_CONSTANT("_Properties", "s", CEDITOR_PROPERTIES),

  GB_END_DECLARE
};


CEditor CEditor::manager;

void CEditor::changed(void)
{
  void *object = QT.GetObject((QWidget *)sender());
  GB.Raise(object, EVENT_Change, 0);
}

void CEditor::moved(void)
{
  void *object = QT.GetObject((QWidget *)sender());
  GB.Raise(object, EVENT_Cursor, 0);
}

void CEditor::scrolled(int, int)
{
  void *object = QT.GetObject((QWidget *)sender());
  GB.Raise(object, EVENT_Scroll, 0);
}

/*
void CGridView::activated(void)
{
  RAISE_EVENT(EVENT_Activate, NULL);
}

void CGridView::clicked(void)
{
  RAISE_EVENT(EVENT_Click, NULL);
}

*/

Generated by  Doxygen 1.6.0   Back to index