⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qeditor.cpp

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************  qeditor.cpp  (c) 2000-2003 Beno� Minisini <gambas@users.sourceforge.net>  This 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.  This 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 this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************//************************************************************************ $Id: qt/src/widgets/qeditor.cpp   2.3.1   edited 2001-03-30 $**** Implementation of QEditor widget class**** Created : 961005**** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for**   information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <qeditor.h>#include <qpainter.h>#include <qscrollbar.h>#include <qclipboard.h>#include <qpixmap.h>#include <qregexp.h>#include <qapplication.h>#include <qdragobject.h>#include <qpopupmenu.h>#include <qtimer.h>#include <qdict.h>#include <qcursor.h>#include <qstyle.h>#include <ctype.h>#include "main.h"/* I want windows shortcuts */#define _WS_WIN_#define xOffset() contentsX()#define yOffset() contentsY()#define viewWidth() visibleWidth()#define viewHeight() visibleHeight()#define totalHeight() contentsHeight()//#define updateContents() viewport()->repaint()#undef QMAX#undef QMINstatic int QMAX(int a, int b){  return a >= b ? a : b;}static int QMIN(int a, int b){  return a <= b ? a : b;}int QEditor::topCell() const{  return rowAt(contentsY());}void QEditor::setTopCell(int row){  updateScrollBars();  setContentsPos(contentsX(), row * cellHeight());  emit scrolled();}void QEditor::setBottomCell(int row){  updateScrollBars();  setContentsPos(contentsX(), QMAX(0, (row  + 1) * cellHeight() - visibleHeight()));  emit scrolled();}void QEditor::ensureLineVisible(int row){  //setContentsPos(contentsX(), QMAX(0, row * cellHeight() + (cellHeight() - visibleHeight()) / 2));  ensureVisible(0, row * cellHeight() + cellHeight() / 2, 0, 100);}void QEditor::setXOffset(int x){  setContentsPos(x, contentsY());}void QEditor::setYOffset(int y){  //qDebug("setYOffset(%d) -> topCell = %d", y, topCell());  setContentsPos(contentsX(), y);}bool QEditor::rowIsVisible(int row) const{  return (row >= rowAt(contentsY()) && row <= rowAt(contentsY() + visibleHeight() - 1));}int QEditor::lastRowVisible() const{  return rowAt(contentsY() + visibleHeight() - cellHeight());}bool QEditor::rowYPos(int row, int *yPos) const{  int y = row * cellHeight() - contentsY();  *yPos = y;  return !(y < 0 || y >= (visibleHeight() - cellHeight()));}int QEditor::findRow(int y) const{  if (y < 0 || y >= visibleHeight())    return -1;  else    return rowAt(contentsY() + y);}QRect QEditor::viewRect() const{  return QRect(0, 0, visibleWidth(), visibleHeight());}int QEditor::posX(int x, int y) const{  if (x < 0)    x = cursorX;  if (y < 0)    y = cursorY;  return mapToView(x, y) - contentsX();}int QEditor::posY(int x, int y) const{  if (y < 0)    y = cursorY;  return y * cellHeight() - contentsY();}void QEditor::setY(int newY){  if (newY < 0)    newY = 0;  if (newY >= numLines())    newY = numLines() - 1;  if (cursorY != newY)    colorize(cursorY);  cursorY = newY;}static void addData(ColorDataArray *data, int state, bool nocompress = false){  unsigned int pos;  pos = data->count();  if (nocompress || data->isNull() || (*data)[pos - 1].state != (unsigned int)state || (*data)[pos - 1].len == 4095)  {    data->resize(pos + 1);    (*data)[pos].state = state;    (*data)[pos].len = 1;  }  else  {    (*data)[pos - 1].len = (*data)[pos - 1].len + 1;  }  //qDebug("addData: data->count() = %d", data->count());}static void changeData(ColorDataArray *data, int state){  if (data->isNull())    return;  (*data)[data->count() - 1].state = state;}bool QEditorRow::isProc(QString &s){  uint i;  QChar c;  QString symbol;  for (i = 0; i < s.length(); i++)  {    c = s[i];    if (!c.isLetter() && symbol.length() > 0)    {      symbol = symbol.upper();      if (symbol == "PRIVATE" || symbol == "PUBLIC" || symbol == "STATIC")      {        symbol = "";        continue;      }      else        break;    }    if (c.isLetter())      symbol += c;    else if (!c.isSpace())      return false;  }  return (symbol == "SUB" || symbol == "PROCEDURE" || symbol == "FUNCTION");}void QEditorRow::analyze(QString &s, ColorDataArray &data){  enum  { Decimal, Binary, Hexa };  unsigned int i;  QChar c, cn;  QString sc;  int state = Normal;  int prev_state = Normal;  int sub_type = 0;  QChar last_op;  unsigned int start = 0;  bool first_symbol = true;  bool esc = false;  bool nocompress;  bool first_keyword = false;  bool last_decl = false;  bool decl_keyword = false;  data.resize(0);  for (i = 0; i < s.length(); i++)  {    if (i == 0)      c = s[0];    else      c = cn;    if (i < s.length())      cn = s[i + 1];    else      cn = '\n';    prev_state = state;    nocompress = false;    if (state == Normal && !c.isSpace())    {      if (c.isLetter() || c == '$' || c == '_')      {        state = Symbol;        start = i;      }      else if (c == '"')      {        state = String;      }      else if (c == '\'')        state = Commentary;      else if (c == '&')      {        if (cn.lower() == 'x')        {          state = Number;          sub_type = Binary;        }        else if (cn.lower() == 'h' || cn.isDigit()                 || (cn.lower() >= 'a' && cn.lower() <= 'f'))        {          state = Number;          sub_type = Hexa;        }        else          state = Operator;      }      else if (c.isDigit())      {        state = Number;        sub_type = Decimal;      }      else if ((c == '+' || c == '-') && cn.isDigit())      {        state = Number;        sub_type = Decimal;      }      else if (c == '?')      {        sc = "PRINT";        if (cn != ' ')          sc = sc + ' ';        s = s.replace(i, 1, sc);        start = i;        state = Symbol;        cn = 'R';      }      else      {        state = Operator;        last_op = c;        nocompress = (c != '>' && c != '/' && c != '=');      }    }    addData(&data, state, nocompress);    switch (state)    {      case Symbol:        if (cn.isLetter() || cn.isDigit() || cn == '_' || cn == '?'            || cn == '$')        {          // continue        }        else        {          unsigned int len = i - start + 1;          sc = s.mid(start, len).lower();          const char *look = sc.latin1();          const char *repl = NULL;          //qDebug("Symbol = '%s'", (s.mid(start, len)).latin1(););          if (last_decl)          {            last_decl = false;          }          else if (last_op != "." && last_op != "!")          {            if (cn != '(')            {              if (!first_keyword)              {                repl = QEditor::firstDict[look];                if (repl)                {                  last_decl = true;                  state = Keyword;                }              }              if (!repl)              {                repl = QEditor::keywordDict[look];                if (repl)                {                  if ((cn != '.' && cn != '[') || qstrcmp(repl, "ME") == 0 || qstrcmp(repl, "LAST") == 0)                  {                    state = Keyword;                    decl_keyword = qstrcmp(repl, "AS") == 0 || qstrcmp(repl, "NEW") == 0;                  }                  else                    repl = NULL;                }              }            }            if (!repl && decl_keyword)            {              repl = QEditor::typeDict[look];              if (repl && (i < (s.length() - 2)) && (cn == '[') && (s[i + 2] == ']'))              {                //qDebug("repl = %s", repl);                addData(&data, state);                addData(&data, state);                len += 2;                sc = s.mid(start, len);                look = sc.latin1();                repl = QEditor::typeDict[look];                i += 2;              }              state = Datatype;            }            if (!repl && decl_keyword)              decl_keyword = false;            if (!repl)            {              repl = QEditor::subrDict[look];              state = Subr;            }            if (repl)            {              s = s.replace(start, len, repl);              changeData(&data, state);              first_keyword = true;            }          }          first_symbol = false;          state = Normal;          last_op = 0;        }        break;      case Number:        if (sub_type != Decimal && c == '&' && prev_state != Normal)          state = Normal;        else if (!(cn.isLetter() || cn.isDigit()                   || (sub_type == Decimal                       && (cn == '.' || cn.lower() == 'e' || cn == '+' || cn == '-'))                   || (sub_type != Decimal                       && cn == '&')))          state = Normal;        break;      case String:        if ((prev_state == String) && c == '"' && !esc)          state = Normal;        else if (esc)          esc = false;        else          esc = (c == '\\');        break;      case Commentary:        break;      default:        state = Normal;        break;    }  }}void QEditorRow::colorize(void){  unsigned int i;  QChar c;  if (!modify)    return;  modify = false;  for (i = s.length() - 1; i >= 0; i--)  {    if (!s[i].isSpace())      break;  }  //if (i >= 0)  //  s = s.left(i + 1);  /*for (i = 0; i < s.length(); i++)  {    c = s[i];    if (!c.isSpace())    {      if (c == '?')        s.replace(i, 1, "PRINT ");      break;    }  }*/  analyze(s, data);  line = isProc(s);  //qDebug("colorize, data.count() = %d", data.count());}void QEditorRow::drawBack(QPainter & p, int x, int y, int w, int h,                          QColor *color, bool current){  if (type)  {    if (type == TypeCurrent)      p.fillRect(x, y, w, h, color[Current]);    else if (type == TypeBreakpoint)      p.fillRect(x, y, w, h, color[Breakpoint]);    else    {      p.fillRect(x, y, w, h,        QColor((color[Current].red() + color[Breakpoint].red()) / 2,               (color[Current].green() + color[Breakpoint].green()) / 2,               (color[Current].blue() + color[Breakpoint].blue()) / 2));    }  }  else if (current)    p.fillRect(x, y, w, h, color[Line]);}void QEditorRow::draw(QPainter & p, int x, int y, int w, int h,                      QColor color[], bool useRelief){  unsigned int i, pos;  int len, wd, style;  QString sd;  y += p.fontMetrics().ascent();  if (type)  {    if (useRelief)    {      p.setPen(color[Normal]);      p.drawText(x + 1, y + 1, s);    }    p.setPen(color[Background]);    p.drawText(x, y, s);    return;  }  if (modify)  {    p.setPen(color[Normal]);    p.drawText(x, y, s);    return;  }  pos = 0;  for (i = 0; i < data.count(); i ++)  {    style = data[i].state;    len = data[i].len;    sd = s.mid(pos, len);    //if (style == Keyword)    //  sd = sd.upper();    //p.drawText(x, y, w, h, Qt::ExpandTabs, sd);    if (style == Keyword && useRelief)    {      p.setPen(color[Normal]);      p.drawText(x + 1, y + 1, sd);      p.setPen(color[style]);      p.drawText(x, y, sd);    }    else    {      p.setPen(color[style]);      p.drawText(x, y, sd);    }    pos += len;    wd = p.fontMetrics().width(sd);     //p.boundingRect(x, y, w, h, Qt::ExpandTabs, sd).width();    x += wd;    w -= wd;  }  if (pos < s.length())  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -