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

📄 editor.cpp

📁 kscope
💻 CPP
字号:
/*************************************************************************** *   Copyright (C) 2007-2009 by Elad Lahav *   elad_lahav@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 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. ***************************************************************************/#include <QMessageBox>#include <QCloseEvent>#include <QDebug>#include <qscilexercpp.h>#include "editor.h"#include "fileiothread.h"#include "findtextdialog.h"namespace KScope{namespace App{/** * Class constructor. * @param  parent  Owner object */Editor::Editor(QWidget* parent) : QsciScintilla(parent),	isLoading_(false),	onLoadLine_(0),	onLoadColumn_(0),	onLoadFocus_(false){}/** * Class destructor. */Editor::~Editor(){}/** * Asynchronously loads the contents of the given file into the editor. * Launches a thread that reads the file contents. When done, the thread signals * the editor with the read text. * During the loading process, the editor widget is disabled. Any calls to * setCursorPosition() or setFocus() are delayed until loading finishes. * @param  path  The path of the file to load * @return true if the loading process started successfully, false otherwise */bool Editor::load(const QString& path){	// Indicate that loading is in progress.	isLoading_ = true;	setEnabled(false);	setText(tr("Loading..."));	// TODO:	// Set up the correct lexer based on the file's MIME type.	setLexer(new QsciLexerCPP(this));	// Create and start the loading thread.	FileIoThread* thread = new FileIoThread(this);	connect(thread, SIGNAL(done(const QString&)), this,	        SLOT(loadDone(const QString&)));	connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));	if (!thread->load(path)) {		setText(tr("Loading failed"));		return false;	}	// Store the path.	path_ = path;	return true;}/** * Writes the contents of the editor back to the file. * @note The current implementation is synchronous, which may cause KScope to *       hang if the saving process takes too long (e.g., for NFS-mounted *       files). This should be fixed at some point. * @return true if successful, false otherwise */bool Editor::save(){	// Nothing to do if the contents did not change since the last save.	if (!isModified())		return true;	// TODO: Provide an asynchronous implementation.	QFile file(path_);	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {		QString msg = tr("Failed to save '%1'").arg(path_);		QMessageBox::critical(this, tr("File Error"), msg);		return false;	}	// Save the file's contents.	QTextStream strm(&file);	strm << text();	return true;}/** * Determines whether the editor can be safely closed. * This is the case if the contents are not modified, the user saves the changes * or the user decides that the contents should not be saved. * @return true if the editor can be closed, false otherwise */bool Editor::canClose(){	if (isModified()) {		// Prompt the user for unsaved changes.		QString msg = tr("The file '%1' was modified.\n"		                 "Would you like to save it?")		              .arg(path_);		QMessageBox::StandardButtons buttons = QMessageBox::Yes		                                       | QMessageBox::No		                                       | QMessageBox::Cancel;		switch (QMessageBox::question(0, tr("Unsaved Changes"), msg,		                              buttons)) {		case QMessageBox::Yes:			// Save the contents of the editor.			if (!save())				return false;			break;		case QMessageBox::No:			// Ignore changes.			setModified(false);			break;		default:			// Stop the close operation.			return false;		}	}	return true;}/** * Moves the cursor to the requested position in the document. * This function translates 1-based line and column indexes into the 0-based * values used by Scintilla. We use 0 values as "don't cares", that do not * change the current value of the respective dimension (line or column). * @param  line    1-based line number, 0 to keep the current line * @param  column  1-based column number, 0 to keep the current column */void Editor::setCursorPosition(uint line, uint column){	int curLine, curColumn;	// Wait for file loading to complete before setting a new position.	if (isLoading_) {		onLoadLine_ = line;		onLoadColumn_ = column;		return;	}	// Get current values.	getCursorPosition(&curLine, &curColumn);	// Determine the new line position.	if (line == 0)		line = curLine;	else		line--;	// Determine the new column position.	if (column == 0)		column = curColumn;	else		column--;	// Set the new cursor position.	QsciScintilla::setCursorPosition(line, column);}/** * Returns a symbol for automatic selection. * If any text is selected in the editor, it is returned. Otherwise, the method * returns the word on which the cursor is currently positioned. * @return The current text */QString Editor::currentSymbol() const{	// Return any selected text.	// TODO: Should we test for a valid symbol here to?	if (hasSelectedText())		return QsciScintilla::selectedText();	// No selected text.	// Get the boundaries of the word from the current cursor position.	long pos, start, end;	pos = SendScintilla(SCI_GETCURRENTPOS);	start = SendScintilla(SCI_WORDSTARTPOSITION, pos, 0L);	end = SendScintilla(SCI_WORDENDPOSITION, pos, 0L);	// Return an empty string if no word is found.	if (start >= end)		return QString();	// Extract the word's text using its position boundaries.	QByteArray curText;	curText.resize(end - start );	SendScintilla(SCI_GETTEXTRANGE, start, end, curText.data());	// NOTE: Scintilla's definition of a "word" does not correspond to a	// "symbol". Make sure the result contains only alpha-numeric characters	// or an underscore.	QString symbol(curText);	if (!QRegExp("\\w+").exactMatch(symbol))		return QString();	return symbol;}/** * Sets the input focus to the editor. * If the editor is currently loading a file, the focus will be set when the * process finishes. */void Editor::setFocus(){	if (isLoading_)		onLoadFocus_ = true;	else		QsciScintilla::setFocus();}/** * Updates the editor widget to use a new set of configuration parameters. * @param  config  The configuration parameters */void Editor::applyConfig(const Config& config){	QsciLexer* lex = lexer();	if (lex)		lex->setFont(config.font_);	else		setFont(config.font_);	setIndentationsUseTabs(config.indentTabs_);	setTabWidth(config.tabWidth_);	setCaretLineVisible(config.hlCurLine_);}/** * Fills a Config structure with the current configuration options. * Used to get QScintilla's default values. * @param config */void Editor::getConfig(Config& config){	QsciLexer* lex = lexer();	if (lex)		config.font_ = lex->defaultFont();	else		config.font_ = font();	config.indentTabs_ = indentationsUseTabs();	config.tabWidth_ = tabWidth();	config.hlCurLine_ = false;}/** * Fills a Location structure with information on the current file name, line * and column. * @param  loc  The structure to fill */void Editor::getCurrentLocation(Core::Location& loc){	int line, col;	// Get the current cursor position.	getCursorPosition(&line, &col);	// Fill the structure.	loc.file_ = path_;	loc.line_ = line + 1;	loc.column_ = col + 1;	loc.text_ = text(line).trimmed();}/** * Searches for text inside the document. * Prompts the user for the text to find. */void Editor::search(){	// Prompt for text to find.	QString pattern = currentSymbol();	SearchOptions options;	if (FindTextDialog::promptPattern(pattern, options, this)	    != QDialog::Accepted) {		return;	}	// Find the first occurrence of the searched text.	if (!QsciScintilla::findFirst(pattern, options.regExp_,	                              options.caseSensitive_,	                              options.wholeWordsOnly_,	                              options.wrap_, !options.backward_)) {		QString msg = tr("'%1' could not be found in the document")		              .arg(pattern);		QMessageBox::warning(this, tr("Pattern not found"), msg);	}}/** * Searches for the next occurrence of the previously-selected text inside the * document. */void Editor::searchNext(){	if (!QsciScintilla::findNext()) {		QString msg = tr("No more matches.");		QMessageBox::warning(this, tr("Pattern not found"), msg);	}}/** * Called before the editor window is closed. * Checks whether the editor can be closed, and if so, accepts the event. * @param  event  The close event */void Editor::closeEvent(QCloseEvent* event){	if (canClose()) {		emit closed(path_);		event->accept();	}	else {		event->ignore();	}}/** * Loads editor configuration parameters. * @param  settings  The QSettings object to use for loading */void Editor::Config::load(QSettings& settings){	Editor::Config config;	Editor().getConfig(config);	font_ = settings.value("Font", config.font_).value<QFont>();	hlCurLine_		= settings.value("HighlightCurrentLine", config.hlCurLine_).toBool();	indentTabs_ = settings.value("IndentWithTabs", config.indentTabs_).toBool();	tabWidth_ = settings.value("TabWidth", config.tabWidth_).toInt();}/** * Stores editor configuration parameters. * @param  settings  The QSettings object to use for storing */void Editor::Config::store(QSettings& settings){	settings.setValue("Font", font_);	settings.setValue("HighlightCurrentLine", hlCurLine_);	settings.setValue("IndentWithTabs", indentTabs_);	settings.setValue("TabWidth", tabWidth_);}/** * Called when the thread loading the file for the editor terminates. * Invokes any methods that were deferred while the file was loading. * @param  text  The contents of the file */void Editor::loadDone(const QString& text){	setText(text);	setModified(false);	isLoading_ = false;	setCursorPosition(onLoadLine_, onLoadColumn_);	setEnabled(true);	if (onLoadFocus_) {		setFocus();		onLoadFocus_ = false;	}}} // namespace App} // namespace KScope

⌨️ 快捷键说明

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