RedPanda-CPP/RedPandaIDE/qsynedit/MiscProcs.cpp

229 lines
5.8 KiB
C++

/*
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
*
* 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 3 of the License, 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, see <https://www.gnu.org/licenses/>.
*/
#include "MiscProcs.h"
#include <QFile>
#include <QPainter>
#include <QTextStream>
#include <algorithm>
int minMax(int x, int mi, int ma)
{
x = std::min(x, ma );
return std::max( x, mi );
}
bool IsPowerOfTwo(int TabWidth) {
if (TabWidth<2)
return false;
int nW = 2;
do {
if (nW >= TabWidth)
break;
nW <<= 1;
} while (nW<0x10000);
return (nW == TabWidth);
}
bool GetHasTabs(const QString &line, int &CharsBefore)
{
bool result = false;
CharsBefore = 0;
if (!line.isEmpty()) {
for (const QChar& ch:line) {
if (ch == '\t') {
result = true;
break;
}
CharsBefore ++;
}
}
return result;
}
int getEOL(const QString &Line, int start)
{
if (start<0 || start>=Line.size()) {
return start;
}
for (int i=start;i<Line.size();i++) {
if (Line[i] == '\n' || Line[i] == '\r') {
return i;
}
}
return Line.size();
}
bool InternalEnumHighlighterAttris(PSynHighlighter Highlighter,
bool SkipDuplicates,
HighlighterAttriProc highlighterAttriProc,
std::initializer_list<void *>& Params,
SynHighlighterList& HighlighterList) {
bool Result = true;
if (HighlighterList.indexOf(Highlighter)>0) {
if (SkipDuplicates)
return Result;
} else {
HighlighterList.append(Highlighter);
}
if (Highlighter->getClass() == SynHighlighterClass::Composition) {
//todo: handle composition highlighter
} else if (Highlighter) {
for (PSynHighlighterAttribute pAttr: Highlighter->attributes()){
QString UniqueAttriName = Highlighter->getName()
+ QString("%1").arg(HighlighterList.indexOf(Highlighter)) + '.'
+ pAttr->name();
Result = highlighterAttriProc(Highlighter, pAttr,
UniqueAttriName, Params);
if (!Result)
break;
}
}
return Result;
}
bool enumHighlighterAttributes(PSynHighlighter Highlighter, bool SkipDuplicates,
HighlighterAttriProc highlighterAttriProc,
std::initializer_list<void *> Params)
{
if (!Highlighter || !highlighterAttriProc) {
return false;
}
SynHighlighterList HighlighterList;
return InternalEnumHighlighterAttris(Highlighter, SkipDuplicates,
highlighterAttriProc, Params, HighlighterList);
}
int mulDiv(int a, int b, int c)
{
//todo: handle overflow?
return a*b/c;
}
SynFontStyles getFontStyles(const QFont &font)
{
SynFontStyles styles;
styles.setFlag(SynFontStyle::fsBold, font.bold());
styles.setFlag(SynFontStyle::fsItalic, font.italic());
styles.setFlag(SynFontStyle::fsUnderline, font.underline());
styles.setFlag(SynFontStyle::fsStrikeOut, font.strikeOut());
return styles;
}
bool isWordChar(const QChar& ch) {
return (ch == '_') || ch.isLetterOrNumber();
}
int findWordChar(const QString &s, int startPos)
{
for (int i=startPos-1;i<s.length();i++) {
if (isWordChar(s[i])) {
return i+1;
}
}
return 0;
}
int findNonWordChar(const QString &s, int startPos)
{
for (int i=startPos-1;i<s.length();i++) {
if (!isWordChar(s[i])) {
return i+1;
}
}
return 0;
}
int findLastWordChar(const QString &s, int startPos)
{
int i = startPos-1;
while (i>=0) {
if (isWordChar(s[i]))
return i+1;
i--;
}
return 0;
}
int findLastNonWordChar(const QString &s, int startPos)
{
int i = startPos-1;
while (i>=0) {
if (!isWordChar(s[i]))
return i+1;
i--;
}
return 0;
}
void ensureNotAfter(BufferCoord &cord1, BufferCoord &cord2)
{
if((cord1.line > cord2.line) || (
cord1.line == cord2.line &&
cord1.ch > cord2.ch)) {
std::swap(cord1,cord2);
}
}
BufferCoord minBufferCoord(const BufferCoord &P1, const BufferCoord &P2)
{
if ( (P2.line < P1.line) || ( (P2.line == P1.line) && (P2.ch < P1.ch)) ) {
return P2;
} else {
return P1;
}
}
BufferCoord maxBufferCoord(const BufferCoord &P1, const BufferCoord &P2)
{
if ( (P2.line > P1.line) || ( (P2.line == P1.line) && (P2.ch > P1.ch)) ) {
return P2;
} else {
return P1;
}
}
QStringList splitStrings(const QString &text)
{
QStringList list;
int start=0,i=0;
while(i<text.length()) {
if (text[i]=='\n' || text[i]=='\r') {
list.append(text.mid(start,i-start));
if (text[i]=='\r') {
i++;
if (i<text.length() && text[i]=='\n')
i++;
} else {
i++;
}
start=i;
} else {
i++;
}
}
if (i>=start)
list.append(text.mid(start,i));
return list;
}
int calSpanLines(const BufferCoord &startPos, const BufferCoord &endPos)
{
return std::abs(endPos.line - startPos.line+1);
}