📄 textedit.cpp
字号:
/** This file is part of QDevelop, an open-source cross-platform IDE* Copyright (C) 2006 Jean-Luc Biord** 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 2 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, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA** Contact e-mail: Jean-Luc Biord <jl.biord@free.fr>* Program URL : http://qdevelop.org**///#include "textEdit.h"#include "editor.h"#include "linenumbers.h"#include "selectionborder.h"#include "cpphighlighter.h"#include "ui_gotoline.h"#include "pluginsinterfaces.h"#include "treeclasses.h"#include "InitCompletion.h"//#include <QTextCursor>#include <QDialog>#include <QKeyEvent>#include <QFile>#include <QTextStream>#include <QMessageBox>#include <QMenu>#include <QTextDocumentFragment>#include <QScrollBar>#include <QPainter>#include <QDebug>#include <QListWidget>#include <QProcess>#include <QClipboard>#include <QFileInfo>#include <QPrintDialog>#include <QTime>#include <QPrinter>#include <QTextLayout>#include <QTextCodec>#include <QDir>#define QD qDebug() << __FILE__ << __LINE__ << ":"extern QString simplifiedText( QString );//static const char * tabPixmap_img[] = {/* width height ncolors cpp [x_hot y_hot] */ "8 8 3 2 0 0",/* colors */ " s none m none c none", "O s iconColor1 m black c black", "X s iconColor2 m black c #D0D0D0",/* pixels */ " X X ", " X X ", " X X ", " X X ", " X X ", " X X ", " X X ", " ",};static const char * spacePixmap_img[] = {/* width height ncolors cpp [x_hot y_hot] */ "8 8 3 2 0 0",/* colors */ " s none m none c none", "O s iconColor1 m black c black", "X s iconColor2 m black c #D0D0D0",/* pixels */ " ", " ", " ", " ", " ", " X ", " X X ", " ",};TextEdit::TextEdit(Editor * parent, MainImpl *mainimpl, InitCompletion *completion) : QTextEdit(parent), m_editor(parent), m_mainImpl(mainimpl), m_completion(completion), m_mouseHidden(false){ setObjectName( "editorZone" ); m_lineNumbers = 0; m_selectionBorder = 0; cpphighlighter = 0; m_autoindent = true; m_autobrackets = true; setAcceptRichText( false ); setLineWrapMode( QTextEdit::FixedPixelWidth ); setLineWrapColumnOrWidth( 65535 ); m_findOptions = 0; m_findExp = ""; m_findImpl = 0; m_match = true; m_highlightCurrentLine = true; m_matchingBegin = -1; m_matchingEnd = -1; m_endLine = MainImpl::Default; m_tabPixmap = QPixmap( tabPixmap_img ); m_spacePixmap = QPixmap( spacePixmap_img ); m_showWhiteSpaces = true; connect(document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(editorModified(bool))); connect( this, SIGNAL( cursorPositionChanged() ), this, SLOT( slotCursorPositionChanged())); connect(this, SIGNAL(initParse(InitCompletion::Request, QString, QString, bool, bool, bool, QString)), m_completion, SLOT(slotInitParse(InitCompletion::Request, QString, QString, bool, bool, bool, QString)) ); actionToggleBreakpoint = new QAction(this); actionToggleBreakpoint->setShortcut( Qt::Key_F9 ); connect(actionToggleBreakpoint, SIGNAL(triggered()), this, SLOT(slotToggleBreakpoint()) ); // m_completionList = new QListWidget(this); m_completionList->setSelectionMode( QAbstractItemView::SingleSelection ); m_completionList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); m_completionList->hide(); m_completionList->setSortingEnabled( true );#ifdef Q_WS_MAC m_completionList->setFont(QFont(m_completionList->font().family(), 12) );#else m_completionList->setFont( QFont(m_completionList->font().family(), 8) );#endif connect(m_completionList, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(slotWordCompletion(QListWidgetItem *)) ); setBackgroundColor( m_backgroundColor );}//void TextEdit::setBackgroundColor( QColor c ){ if ( c == m_backgroundColor ) return; m_backgroundColor = c; QPalette pal = palette(); pal.setColor(QPalette::Base, m_backgroundColor); setPalette( pal ); viewport()->update();}//void TextEdit::setCurrentLineColor( QColor c ){ if ( c == m_currentLineColor ) return; m_currentLineColor = c; viewport()->update();}//void TextEdit::print(){ QPrinter printer(QPrinter::HighResolution); printer.setFullPage(true); QPrintDialog dlg(&printer, this); if (dlg.exec() == QDialog::Accepted) { document()->print(&printer); }}void TextEdit::printWhiteSpacesAndMatching( QPainter &p ){ const int contentsY = verticalScrollBar()->value(); const qreal pageBottom = contentsY + viewport()->height(); const QFontMetrics fm = QFontMetrics( currentFont() ); for ( QTextBlock block = document()->begin(); block.isValid(); block = block.next() ) { QTextLayout* layout = block.layout(); const QRectF boundingRect = layout->boundingRect(); QPointF position = layout->position(); if ( position.y() +boundingRect.height() < contentsY ) continue; if ( position.y() > pageBottom ) break; const QString txt = block.text(); const int len = txt.length(); for ( int i=0; i<len; i++) { QTextCursor cursor = textCursor(); cursor.setPosition( block.position() + i, QTextCursor::MoveAnchor); QRect r = cursorRect( cursor ); if( block.position() + i == m_matchingBegin || block.position() + i == m_matchingEnd ) { QTextCursor cursor = textCursor(); cursor.setPosition( block.position() + i, QTextCursor::MoveAnchor); QRect r2 = cursorRect( cursor ); if( QString("({[").contains( m_plainText.at( block.position() + i ) ) ) r2.adjust(r2.width()/3, r2.height()-1, r2.width()/3, 0); else r2.adjust(r2.width()/4, r2.height()-1, r2.width()/4, 0); r2.adjust(2, 0, -2, 0); p.setPen( m_matchingColor ); //int x = r2.x() + 4; //int y = r2.y();// + fm.height();// / 2 - 5; p.drawRect(r2); } if( m_showWhiteSpaces ) { // pixmaps are of size 8x8 pixels QPixmap *p1 = 0; if (txt[i] == ' ' ) p1 = &m_spacePixmap; else if (txt[i] == '\t' ) p1 = &m_tabPixmap; else continue; int x = r.x() + 4; int y = r.y() + fm.height() / 2 - 5; p.drawPixmap( x, y, *p1 ); } } }}//void TextEdit::completeCode(){ if ( m_mainImpl->buildQtDatabase() ) { QMessageBox::warning(m_mainImpl, "QDevelop", tr("The Qt database building is in progress.\nTry to complete code later.")); return; } if ( !m_completion ) return; QString c = m_plainText.left(textCursor().position()); if( c.simplified().right(1) == "(" ) { completionHelp(); return; } bool addThis = true; QString word; int i; for(i = c.length()-1; i>0; i--) { if( c.at(i) == QChar('\n') || c.at(i) == QChar(';') ) { i++; word = c.mid( i ); c = c.left( i ); break; } if( QString(":.>(").contains( c.at(i) ) ) { addThis = false; break; } } if( addThis ) { c += "this->" + word; } emit initParse(InitCompletion::Completion, m_editor->filename(), c, true, true, false, QString());}void TextEdit::slotCompletionList(TagList tagList ){ if ( tagList.count() ) { int w = 0; int h = 0; m_completionList->clear(); foreach(Tag tag, tagList) { w = qMax(w, fontMetrics().width( tag.name+tag.parameters )); QListWidgetItem *item = new QListWidgetItem( m_completionList ); item->setText(tag.name+tag.parameters ); h += 15; QVariant v; v.setValue( tag ); item->setData(Qt::UserRole, v ); //item->setData(Qt::UserRole, QVariant(tag.name) ); if( tag.access.isEmpty() ) tag.access = "public"; if ( tag.kind == "function" || tag.kind == "prototype") item->setIcon(QIcon(":/CV/images/CV"+tag.access+"_meth.png")); else if ( tag.kind == "member" ) item->setIcon(QIcon(":/CV/images/CV"+tag.access+"_var.png")); else if ( tag.kind == "struct" ) item->setIcon(QIcon(":/CV/images/CVstruct.png")); else if ( tag.kind == "class" ) item->setIcon(QIcon(":/CV/images/CVclass.png")); m_completionList->addItem(item); //m_completionList->addItem( tag.name ); } m_completionList->setSelectionMode( QAbstractItemView::SingleSelection ); QPalette palette; QBrush brush(QColor(255, 255, 255, 255)); brush.setStyle(Qt::SolidPattern); palette.setBrush(QPalette::Active, QPalette::Base, brush); m_completionList->setPalette(palette); w = qMin(w+20, 550); w = qMax(w, 150); int posX = qMax(cursorRect().x(), 80); //if ( posX+w > width() ) //posX = width()-220; if ( cursorRect().y() > viewport()->height()/2 ) { h = qMin( qMin(h+20, cursorRect().y()), 250); m_completionList->setGeometry(posX, cursorRect().y()-h, w, h); } else { h = qMin( qMin(h+20, viewport()->height()-22-cursorRect().y()), 250); m_completionList->setGeometry(posX, cursorRect().y()+fontMetrics().height(), w, h); } m_completionList->show(); m_completionList->setCurrentRow( 0 ); // QString s = wordUnderCursor(); QList<QListWidgetItem *> listeItems = m_completionList->findItems(s, Qt::MatchExactly); listeItems = m_completionList->findItems(s, Qt::MatchStartsWith); if ( listeItems.count()>1 ) m_completionList->setCurrentItem( listeItems.first() ); // } else m_completionList->hide();}//void TextEdit::slotCompletionHelpList(TagList tagList){ if ( tagList.count() ) { int w = 0; int h = 0; m_completionList->clear(); foreach(Tag tag, tagList) { w = qMax(w, fontMetrics().width( tag.name+tag.parameters )); QListWidgetItem *item = new QListWidgetItem( m_completionList ); item->setText( tag.name+tag.parameters ); h += 15; if( tag.access.isEmpty() ) tag.access = "public"; if ( tag.kind == "function" || tag.kind == "prototype") item->setIcon(QIcon(":/CV/images/CV"+tag.access+"_meth.png")); else if ( tag.kind == "member" ) item->setIcon(QIcon(":/CV/images/CV"+tag.access+"_var.png")); m_completionList->addItem( item ); } m_completionList->setSelectionMode( QAbstractItemView::NoSelection ); QPalette palette; QBrush brush(QColor(255, 255, 127, 255)); brush.setStyle(Qt::SolidPattern); palette.setBrush(QPalette::Active, QPalette::Base, brush); m_completionList->setPalette(palette); w = qMin(w+20, 550); w = qMax(w, 150); int posX = qMax(cursorRect().x(), 80); if ( posX+w > width() ) posX = width()-220; if ( cursorRect().y() > viewport()->height()/2 ) { h = qMin( qMin(h+20, cursorRect().y()), 250); m_completionList->setGeometry(posX, cursorRect().y()-h, w, h); } else { h = qMin( qMin(h+20, viewport()->height()-22-cursorRect().y()), 250); m_completionList->setGeometry(posX, cursorRect().y()+fontMetrics().height(), w, h); } m_completionList->show(); // } else m_completionList->hide();}//void TextEdit::setFocus(Qt::FocusReason reason){ m_completionList->hide(); QTextEdit::setFocus(reason);}//void TextEdit::mousePressEvent ( QMouseEvent * event ){ m_completionList->hide(); QTextEdit::mousePressEvent ( event );}//TextEdit::~TextEdit(){ delete lineNumbers();}//void TextEdit::setTabStopWidth(int taille){ bool m = document()->isModified(); int posScrollbar = verticalScrollBar()->value(); QTextEdit::setTabStopWidth(fontMetrics().width( " " ) * taille); setPlainText( toPlainText() ); verticalScrollBar()->setValue( posScrollbar ); document()->setModified( m );}//bool TextEdit::open(bool silentMode, QString filename, QDateTime &lastModified){ if ( cpphighlighter && !QString(":c:cc:cpp:h:hpp").contains( ":"+filename.section(".", -1, -1).toLower()+":" ) ) { delete cpphighlighter; cpphighlighter = 0; } QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { if ( !silentMode ) QMessageBox::critical(0, "QDevelop", tr("The file \"%1\" could not be loaded.").arg(filename),tr("Cancel") ); return false; } QByteArray data = file.readAll(); QTextStream in(&data); QApplication::setOverrideCursor(Qt::WaitCursor); int mib = m_mainImpl->mibCodec(); QTextCodec *codec = QTextCodec::codecForMib(mib); in.setAutoDetectUnicode(false); in.setCodec(codec); QString decodedStr = in.readAll(); setPlainText(decodedStr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -