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

📄 qconsole.cpp

📁 qconsole2 qt寫的一個console元件
💻 CPP
字号:
/***************************************************************************                          qconsole.cpp  -  description                             -------------------    begin                : mar mar 15 2005    copyright            : (C) 2005 by Houssem BDIOUI    email                : houssem.bdioui@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 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "qconsole.h"#include <qfile.h>#if QT_VERSION >= 0x040000#include <QMouseEvent>#include <QTextStream>#include <QKeyEvent>#include <Q3PopupMenu>//for Q3TextCursor usage#include "q3richtext_p.h"#define QTEXTCURSOR_CLASSNAME Q3TextCursor#define CONTROL_BUTTON ControlModifier#define WRITE_ONLY QIODevice::WriteOnly#else//for QTextCursor usage#include <private/qrichtext_p.h>#define QTEXTCURSOR_CLASSNAME QTextCursor#define CONTROL_BUTTON ControlButton#define WRITE_ONLY IO_WriteOnly#endif//Clear the consolevoid QConsole::clear(){   QTEXTEDIT_CLASSNAME::clear();}//Reset the consolevoid QConsole::reset(){    clear();    //set the style of the QTextEdit    setTextFormat(Qt::PlainText);    setCurrentFont(QFont("Courier"));    //init attributes    historyIndex = 0;    history.clear();    recordedScript.clear();}//QConsole constructor (init the QTextEdit & the attributes)QConsole::QConsole(QWidget *parent, const char *name, bool initInterceptor) : QTEXTEDIT_CLASSNAME(parent,name),   cmdColor(Qt::black), errColor(Qt::red), outColor(Qt::blue), completionColor(Qt::green),   stdoutInterceptor(NULL), stderrInterceptor(NULL){    //resets the console    reset();    if (initInterceptor)    {	//Initialize the interceptors	stdoutInterceptor = new Interceptor(this);	stdoutInterceptor->initialize(1);	connect(stdoutInterceptor, SIGNAL(received(QTextIStream *)), SLOT(displayPrompt()));	stderrInterceptor = new Interceptor(this);	stderrInterceptor->initialize(2);	connect(stderrInterceptor, SIGNAL(received(QTextIStream *)), SLOT(displayPrompt()));    }}//Sets the prompt and cache the prompt length to optimize the processing speedvoid QConsole::setPrompt(QString newPrompt, bool display){    prompt = newPrompt;    promptLength = prompt.length();    //display the new prompt    if (display)        displayPrompt();}//Displays the prompt and move the cursor to the end of the line.void QConsole::displayPrompt(){    //flush the stdout/stderr before displaying the prompt    if (stdoutInterceptor)    {	setColor(outColor);	stdReceived(stdoutInterceptor->textIStream());    }    if (stderrInterceptor)    {	setColor(errColor);	stdReceived(stderrInterceptor->textIStream());    }    //displays the prompt    setColor(cmdColor);    append(prompt);    QTEXTEDIT_CLASSNAME::moveCursor(QTEXTEDIT_CLASSNAME::MoveEnd, false);    //Saves the paragraph number of the prompt    promptParagraph = paragraphs() - 1;}//displays redirected stdout/stderrvoid QConsole::stdReceived(QTextIStream *s){    QString line;#if QT_VERSION >= 0x040000    line = s->readAll();    append(line);#else    while (!s->atEnd())    {        line = s->readLine();        append(line);    }#endif}//Correctly handle the cursor when moved according to the different actionsvoid QConsole::moveCursor(CursorAction action, bool select){    int para, index;    //save the old cursor position    getCursorPosition(&para, &index );    //if home pressed, move the cursor just after the prompt (if in the first line)    //and select the covered text if needed    if ( (action == QTEXTEDIT_CLASSNAME::MoveLineStart) && (promptParagraph == para) )    {        if (select)            setSelection(para, index, para, promptLength);        else            setCursorPosition(para, promptLength);        return;    }    //Process the up & down keys to navigate into the history (if not empty & if in the first line)    else if ( ( (action == QTEXTEDIT_CLASSNAME::MoveDown) || (action == QTEXTEDIT_CLASSNAME::MoveUp) )        && history.size() && (promptParagraph == para))    {        //update the historyIndex if up or down        if ( (action == QTEXTEDIT_CLASSNAME::MoveDown) && (historyIndex + 1 < history.size()) )            historyIndex ++;        else if ((action == QTEXTEDIT_CLASSNAME::MoveUp) && historyIndex)            historyIndex --;        //replace the current command with the command found in the history        replaceCurrentCommand(history[historyIndex]);    }    else        QTEXTEDIT_CLASSNAME::moveCursor(action, select);    //Undo the new position if it is out of the edition zone and unselect as well    if (!isInEditionZone())    {        setCursorPosition(para, index);        selectAll(false);    }}//Redirect keyboard actions to perform text suppression and validation//of the commandsvoid QConsole::doKeyboardAction(KeyboardAction action){    //Get the current paragraph and the current cursor position    int para, index;    getCursorPosition(&para, &index );    //Get the cursor    QTEXTCURSOR_CLASSNAME *cursor = textCursor();    switch (action)    {        //Don't delete the prompt if backspace is pressed        case QTEXTEDIT_CLASSNAME::ActionBackspace:        {            if ( (promptParagraph == para) && (index == promptLength) )                return;        }        break;        //Don't delete the prompt if ctrl+backspace is pressed        case QTEXTEDIT_CLASSNAME::ActionWordBackspace:        {            //trick to get the new position of the cursor            cursor->gotoPreviousWord();            //exit if the new position is out of the edition zone            bool error = false;            if ( !isInEditionZone())                error = true;            setCursorPosition(para, index);            if (error)                return;        }        break;        // If return pressed, do the evaluation and append the result        case QTEXTEDIT_CLASSNAME::ActionReturn:        {            //Get the command to validate            QString command = getCurrentCommand();            //execute the command and get back its text result and its return value            if (isCommandComplete(command))                execCommand(command, false);            else            {                append("");                QTEXTEDIT_CLASSNAME::moveCursor(QTEXTEDIT_CLASSNAME::MoveEnd, false);            }            return;        }        break;        default:            break;    }    //If we are here, this means that we can perform the action    //by calling the parent implementation    QTEXTEDIT_CLASSNAME::doKeyboardAction(action);}//Don't remove any text if the selection is not inside the edition zonevoid QConsole::removeSelectedText(int selNum){    //get where the current selection starts and where it ends    int paraFrom, indexFrom, paraTo, indexTo;    getSelection( &paraFrom, &indexFrom, &paraTo, &indexTo, selNum);    //check if the selection is inside the selection zone and then delete it    //else unselect    if (isInEditionZone() && ((paraFrom > promptParagraph) ||        ( (paraFrom == promptParagraph) && (indexFrom >= promptLength) )) )        QTEXTEDIT_CLASSNAME::removeSelectedText(selNum);    else        selectAll(false);}//Reimplemented mouse press eventvoid QConsole::contentsMousePressEvent( QMouseEvent *e ){    //Saves the old position of the cursor before any mouse click    getCursorPosition(&oldPara, &oldIndex );    //Call the parent implementation    QTEXTEDIT_CLASSNAME::contentsMousePressEvent( e );    //Saves the new position of the cursor    getCursorPosition(&newPara, &newIndex );}//Reimplemented mouse release eventvoid QConsole::contentsMouseReleaseEvent( QMouseEvent *e ){    //Call the parent implementation    QTEXTEDIT_CLASSNAME::contentsMouseReleaseEvent( e );    //Undo the new cursor position if it is out of the edition zone    if (!isInEditionZone())        setCursorPosition(oldPara, oldIndex );}//Reimplemented mouse dblclk eventvoid QConsole::contentsMouseDoubleClickEvent( QMouseEvent *e ){    setCursorPosition(newPara, newIndex );    //Call the parent implementation    QTEXTEDIT_CLASSNAME::contentsMouseDoubleClickEvent( e );}//give suggestions to autocomplete a command (should be reimplemented)//the return value of the function is the string list of all suggestionsQStringList QConsole::autocompleteCommand(QString){    return QStringList();}  //Reimplemented key press eventvoid QConsole::keyPressEvent( QKeyEvent *e ){    //If Ctrl + C pressed, then undo the current command    if ( (e->key() == Qt::Key_C) && (e->state() == Qt::CONTROL_BUTTON) )        displayPrompt();    //Treat the tab key & autocomplete the current command    else if (e->key() == Qt::Key_Tab)    {        QString command = getCurrentCommand();        QStringList sl = autocompleteCommand(command);        QString str = sl.join(" ");        if (sl.count() == 1)            replaceCurrentCommand(sl[0] + " ");        else if (sl.count() > 1)        {            setColor(completionColor);            append(sl.join(" "));            setColor(cmdColor);            displayPrompt();            QTEXTEDIT_CLASSNAME::insert(command);        }    }    else        QTEXTEDIT_CLASSNAME::keyPressEvent( e );}//Get the current commandQString QConsole::getCurrentCommand(){    //Get the current command: we just remove the prompt    setSelection(promptParagraph, promptLength, paragraphs()-1, paragraphLength(paragraphs()-1));    QString command = selectedText();    selectAll(false);    return command;}//Replace current command with a new onevoid QConsole::replaceCurrentCommand(QString newCommand){    setSelection(promptParagraph, promptLength, paragraphs()-1, paragraphLength(paragraphs()-1));    QTEXTEDIT_CLASSNAME::insert(newCommand);}//default implementation: command always completebool QConsole::isCommandComplete(QString ){    return true;}//Tests whether the cursor is in th edition zone or not (after the prompt//or in the next lines (in case of multi-line mode)bool QConsole::isInEditionZone(){    int para, index;    getCursorPosition(&para, &index );    return (para > promptParagraph) || ( (para == promptParagraph) && (index >= promptLength) );}//Basically, puts the command into the history list//And emits a signal (should be called by reimplementations)QString QConsole::interpretCommand(QString command, int *res){    //Add the command to the recordedScript list    if (!*res)        recordedScript.append(command);    //update the history and its index    history.append(command.replace("\n", "\\n"));    historyIndex = history.size();    //emit the commandExecuted signal    emit commandExecuted(command);    return "";}//execCommand(QString) executes the command and displays back its resultvoid QConsole::execCommand(QString command, bool writeCommand, bool showPrompt){    //Display the prompt with the command first    if (writeCommand)    {        if (getCurrentCommand() != "")            displayPrompt();        QTEXTEDIT_CLASSNAME::insert(command);    }    //execute the command and get back its text result and its return value    int res;    QString strRes = interpretCommand(command, &res);    //According to the return value, display the result either in red or in blue    if (res == 0)        setColor(outColor);    else        setColor(errColor);    append(strRes);    //Display the prompt again    if (showPrompt)        displayPrompt();}//saves a file scriptint QConsole::saveScript(QString fileName){    QFile f(fileName);    if (!f.open(WRITE_ONLY))        return -1;    QTextStream ts(&f);    for ( QStringList::Iterator it = recordedScript.begin(); it != recordedScript.end(); ++it)        ts << *it << "\n";    f.close();    return 0;}//loads a file scriptint QConsole::loadScript(QString fileName){    QFile f(fileName);    if (!f.open(IO_ReadOnly))        return -1;    QTextStream ts(&f);    QString command;    while(true)    {        command=ts.readLine();        if (command.isNull())           break; //done        execCommand(command, true, false);    }    f.close();    return 0;}//redefined insert() slot to avoid inserting text outside of the//edition zone: Fixes a bug that happens when holding the mouse button//pressed outside the edition zone and typing somethingvoid QConsole::insert(const QString & text, bool indent, bool checkNewLine, bool removeSelected){    if (isInEditionZone())        QTEXTEDIT_CLASSNAME::insert(text, indent, checkNewLine, removeSelected);}//Just disable the popup menuQPOPUPMENU_CLASSNAME * QConsole::createPopupMenu (const QPoint &){    return NULL;}//Allows pasting with middle mouse button (x window)//when clicking outside of the edition zonevoid QConsole::paste(){    setCursorPosition(oldPara, oldIndex );    QTEXTEDIT_CLASSNAME::paste();}

⌨️ 快捷键说明

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