diff --git a/.gitignore b/.gitignore index 10b570bb..6a151d98 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ deps/libssh/src/Makefile deps/libssh/src/stamp-h1 build-tests-*/* tests/Makefile +deps/jsoncpp/buildscons/* diff --git a/redis-desktop-manager/include/widgets/qconsole.h b/redis-desktop-manager/include/widgets/qconsole.h new file mode 100644 index 00000000..099060d2 --- /dev/null +++ b/redis-desktop-manager/include/widgets/qconsole.h @@ -0,0 +1,221 @@ +/* -*- mode: c++ -*- */ +/*************************************************************************** + qconsole.h - description + ------------------- + begin : mar mar 15 2005 + copyright : (C) 2005 by Houssem BDIOUI + email : houssem.bdioui@gmail.com + ***************************************************************************/ + +// migrated to Qt4 by YoungTaek Oh. date: Nov 29, 2010 + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef QCONSOLE_H +#define QCONSOLE_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +/** + * Subclasssing QListWidget + * + * @author YoungTaek Oh + */ +class PopupListWidget : public QListWidget +{ + Q_OBJECT + +public: + PopupListWidget(QWidget *parent = 0): QListWidget(parent) { + setUniformItemSizes(true); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + virtual ~PopupListWidget() { } + +protected: + virtual QSize sizeHint() const; + virtual void keyPressEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Tab || + e->key() == Qt::Key_Return) + Q_EMIT itemActivated(currentItem()); + else + QListWidget::keyPressEvent(e); + } +}; + +/** + * Popup Completer class + * + * @author YoungTaek Oh + * @todo 1. beautifying + * 2. icons for classifying words (eg. functions, properties...) + * 3. bugs? + * @note still experimental + */ +class PopupCompleter : public QDialog +{ + Q_OBJECT + +public: + PopupCompleter(const QStringList&, QWidget *parent = 0); + virtual ~PopupCompleter(); + +public: + QString selected(void) { return selected_; } + int exec(QTextEdit*); + +protected: + virtual void showEvent(QShowEvent*); + +private Q_SLOTS: + void onItemActivated(QListWidgetItem*); + +public: + QListWidget *listWidget_; + QString selected_; +}; + +/** + * An abstract Qt console + * @author Houssem BDIOUI + */ +class QConsole : public QTextEdit +{ + Q_OBJECT +public: + //constructor + QConsole(QWidget *parent = NULL, const QString &welcomeText = ""); + //set the prompt of the console + void setPrompt(const QString &prompt, bool display = true); + //execCommand(QString) executes the command and displays back its result + bool execCommand(const QString &command, bool writeCommand = true, + bool showPrompt = true, QString *result = NULL); + + //clear & reset the console (useful sometimes) + void clear(); + void reset(const QString &welcomeText = ""); + + //cosmetic methods ! + + // @{ + /// get/set command color + QColor cmdColor() const { return cmdColor_; } + void setCmdColor(QColor c) {cmdColor_ = c;} + // @} + + // @{ + /// get/set error color + QColor errColor() const { return errColor_; } + void setErrColor(QColor c) {errColor_ = c;} + // @} + + // @{ + /// get/set output color + QColor outColor() const { return outColor_; } + void setOutColor(QColor c) {outColor_ = c;} + // @} + void setCompletionColor(QColor c) {completionColor = c;} + + // @{ + /// get set font + void setFont(const QFont& f); + QFont font() const { return currentFont(); } + // @} + + void correctPathName(QString& pathName); + +private: + void dropEvent( QDropEvent * event); + void dragMoveEvent( QDragMoveEvent * event); + + void keyPressEvent(QKeyEvent * e); + void contextMenuEvent( QContextMenuEvent * event); + + //Return false if the command is incomplete (e.g. unmatched braces) + virtual bool isCommandComplete(const QString &command); + //Get the command to validate + QString getCurrentCommand(); + + //Replace current command with a new one + void replaceCurrentCommand(const QString &newCommand); + + //Test whether the cursor is in the edition zone + bool isInEditionZone(); + bool isInEditionZone(const int& pos); + + //Test whether the selection is in the edition zone + bool isSelectionInEditionZone(); + //Change paste behaviour + void insertFromMimeData(const QMimeData *); + + +//protected attributes +protected: + //colors + QColor cmdColor_, errColor_, outColor_, completionColor; + + int oldPosition; + // cached prompt length + int promptLength; + // The prompt string + QString prompt; + // The commands history + QStringList history; + //Contains the commands that has succeeded + QStringList recordedScript; + // Current history index (needed because afaik QStringList does not have such an index) + int historyIndex; + //Holds the paragraph number of the prompt (useful for multi-line command handling) + int promptParagraph; + +protected: + //Implement paste with middle mouse button + void mousePressEvent(QMouseEvent*); + + //execute a validated command (should be reimplemented and called at the end) + //the return value of the function is the string result + //res must hold back the return value of the command (0: passed; else: error) + virtual QString interpretCommand(const QString &command, int *res); + //give suggestions to autocomplete a command (should be reimplemented) + //the return value of the function is the string list of all suggestions + //the returned prefix is useful to complete "sub-commands" + virtual QStringList suggestCommand(const QString &cmd, QString &prefix); + + +public Q_SLOTS: + //Contextual menu slots + void cut(); + //void paste(); + void del(); + //displays the prompt + void displayPrompt(); + +Q_SIGNALS: + //Signal emitted after that a command is executed + void commandExecuted(const QString &command); + +private: + void handleTabKeyPress(); + void handleReturnKeyPress(); + bool handleBackspaceKeyPress(); + void handleUpKeyPress(); + void handleDownKeyPress(); + void setHome(bool); +}; + +#endif diff --git a/redis-desktop-manager/redis-desktop-manager.vcxproj b/redis-desktop-manager/redis-desktop-manager.vcxproj index 9e2f93a3..093d185f 100644 --- a/redis-desktop-manager/redis-desktop-manager.vcxproj +++ b/redis-desktop-manager/redis-desktop-manager.vcxproj @@ -38,6 +38,9 @@ true + + true + true @@ -113,6 +116,9 @@ true + + true + true @@ -190,6 +196,7 @@ + @@ -381,6 +388,16 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -DQT_CONCURRENT_LIB "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I$(QTDIR)\include\QtConcurrent" "-I$(SolutionDir)\deps\json-cpp\include" "-I$(SolutionDir)\deps\libssh\include" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing qconsole.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -DQT_CONCURRENT_LIB "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I$(QTDIR)\include\QtConcurrent" "-I$(SolutionDir)\deps\jsoncpp\include" "-I$(SolutionDir)\deps\libssh\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing qconsole.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -DQT_CONCURRENT_LIB "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I$(QTDIR)\include\QtConcurrent" "-I$(SolutionDir)\deps\jsoncpp\include" "-I$(SolutionDir)\deps\libssh\include" + diff --git a/redis-desktop-manager/redis-desktop-manager.vcxproj.filters b/redis-desktop-manager/redis-desktop-manager.vcxproj.filters index 63fe077b..9b19a93c 100644 --- a/redis-desktop-manager/redis-desktop-manager.vcxproj.filters +++ b/redis-desktop-manager/redis-desktop-manager.vcxproj.filters @@ -332,6 +332,15 @@ Source Files\models\value-view-formatters + + Source Files\widgets + + + Generated Files\Debug + + + Generated Files\Release + @@ -418,6 +427,9 @@ Header Files\widgets + + Header Files\widgets + diff --git a/redis-desktop-manager/source/widgets/qconsole.cpp b/redis-desktop-manager/source/widgets/qconsole.cpp new file mode 100644 index 00000000..6bb8a194 --- /dev/null +++ b/redis-desktop-manager/source/widgets/qconsole.cpp @@ -0,0 +1,798 @@ +/*************************************************************************** + qconsole.cpp - description + ------------------- + begin : mar mar 15 2005 + copyright : (C) 2005 by Houssem BDIOUI + email : houssem.bdioui@gmail.com + ***************************************************************************/ + +// migrated to Qt4 by YoungTaek Oh. date: Nov 29, 2010 + +/*************************************************************************** + * * + * 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 +#include +#include +#include +#include +#include +#include + +//#define USE_POPUP_COMPLETER +#define WRITE_ONLY QIODevice::WriteOnly + +QSize PopupListWidget::sizeHint() const +{ + QAbstractItemModel *model = this->model(); + QAbstractItemDelegate *delegate = this->itemDelegate(); + const QStyleOptionViewItem sovi; + int left, top, right, bottom = 0; + + QMargins margin = this->contentsMargins(); + + top = margin.top(); + bottom = margin.bottom(); + left = margin.left(); + right = margin.right(); + + const int vOffset = top + bottom; + const int hOffset = left + right; + + + + bool vScrollOn = false; + int height = 0; + int width = 0; + for (int i=0; icount(); ++i) { + QModelIndex index = model->index(i, 0); + QSize itemSizeHint = delegate->sizeHint(sovi, index); + if (itemSizeHint.width() > width) + width = itemSizeHint.width(); + + // height + const int nextHeight = height + itemSizeHint.height(); + if (nextHeight + vOffset < this->maximumHeight()) + height = nextHeight; + else { + // early termination + vScrollOn = true; + break; + } + } + + QSize sizeHint(width + hOffset, 0); + sizeHint.setHeight(height + vOffset); + if (vScrollOn) { + int scrollWidth = this->verticalScrollBar()->sizeHint().width(); + sizeHint.setWidth(sizeHint.width() + scrollWidth); + } + return sizeHint; +} + +PopupCompleter::PopupCompleter(const QStringList& sl, QWidget *parent) + : QDialog(parent, Qt::Popup) +{ + setModal(true); + + listWidget_ = new PopupListWidget(); + listWidget_->setMaximumHeight(200); + qDebug() << "sizeHint(): " << listWidget_->sizeHint(); + Q_FOREACH(QString str, sl) { + QListWidgetItem *item = new QListWidgetItem; + item->setText(str); + listWidget_->addItem(item); + } + qDebug() << "sizeHint(): " << listWidget_->sizeHint(); + listWidget_->setFixedSize(listWidget_->sizeHint()); + + + QLayout *layout = new QVBoxLayout(); + layout->setSizeConstraint(QLayout::SetFixedSize); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(listWidget_); + + setLayout(layout); + + // connect signal + connect(listWidget_, SIGNAL(itemActivated(QListWidgetItem *)), + SLOT(onItemActivated(QListWidgetItem*))); +} + +PopupCompleter::~PopupCompleter() +{ +} + +void PopupCompleter::showEvent(QShowEvent *event) +{ + listWidget_->setFocus(); +} + +void PopupCompleter::onItemActivated(QListWidgetItem *event) +{ + selected_ = event->text(); + done(QDialog::Accepted); +} + +/** + * @brief execute PopupCompleter at appropriate position. + * + * @param parent Parent of this popup completer. usually QConsole. + * @return see QDialog::exec + * @see QDialog::exec + */ +int PopupCompleter::exec(QTextEdit *parent) +{ + QSize popupSizeHint = this->sizeHint(); + QRect cursorRect = parent->cursorRect(); + QPoint globalPt = parent->mapToGlobal(cursorRect.bottomRight()); + QDesktopWidget *dsk = QApplication::desktop(); + QRect screenGeom = dsk->screenGeometry(dsk->screenNumber(this)); + if (globalPt.y() + popupSizeHint.height() > screenGeom.height()) { + globalPt = parent->mapToGlobal(cursorRect.topRight()); + globalPt.setY(globalPt.y() - popupSizeHint.height()); + } + this->move(globalPt); + this->setFocus(); + return QDialog::exec(); +} + +/** + * returns a common word of the given list + * + * @param list String list + * + * @return common word in the given string. + */ +static +QString getCommonWord(QStringList& list) +{ + QChar ch; + QVector strarray = list.toVector(); + QString common; + int col = 0, min_len; + bool cont = true; + + // get minimum length + min_len = strarray.at(0).size(); + for (int i=1; iexec(this) == QDialog::Accepted) + replaceCurrentCommand(commandPrefix + popup->selected()); + delete popup; + + } + } +} + +// If return pressed, do the evaluation and append the result +void QConsole::handleReturnKeyPress() +{ + //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(""); + moveCursor(QTextCursor::EndOfLine); + } +} + +bool QConsole::handleBackspaceKeyPress() +{ + QTextCursor cur = textCursor(); + const int col = cur.columnNumber(); + const int blk = cur.blockNumber(); + if (blk == promptParagraph && col == promptLength) + return true; + return false; +} + +void QConsole::handleUpKeyPress() +{ + if (history.count()) + { + QString command = getCurrentCommand(); + do + { + if (historyIndex) + historyIndex--; + else + { + break; + } + } while(history[historyIndex] == command); + replaceCurrentCommand(history[historyIndex]); + } +} + +void QConsole::handleDownKeyPress() +{ + if (history.count()) + { + QString command = getCurrentCommand(); + do + { + if (++historyIndex >= history.size()) + { + historyIndex = history.size() - 1; + break; + } + } while(history[historyIndex] == command); + replaceCurrentCommand(history[historyIndex]); + } +} + + +void QConsole::setHome(bool select) +{ + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, select ? QTextCursor::KeepAnchor : + QTextCursor::MoveAnchor); + if(textCursor().blockNumber() == promptParagraph) + { + cursor.movePosition(QTextCursor::Right, select ? QTextCursor::KeepAnchor : + QTextCursor::MoveAnchor, + promptLength); + } + setTextCursor(cursor); +} + +//Reimplemented key press event +void QConsole::keyPressEvent( QKeyEvent *e ) +{ + //If the user wants to copy or cut outside + //the editing area we perform a copy + if(textCursor().hasSelection()) + { + if(e->modifiers() == Qt::CTRL) + { + if( e->matches(QKeySequence::Cut) ) + { + e->accept(); + if(!isInEditionZone()) + { + copy(); + } + else + { + cut(); + } + return; + } + else if(e->matches(QKeySequence::Copy) ) + { + e->accept(); + copy(); + } + else + { + QTextEdit::keyPressEvent( e ); + return; + } + } + } +/* + // if the cursor out of editing zone put it back first + if(!isInEditionZone()) + { + QTextCursor editCursor = textCursor(); + editCursor.setPosition(oldEditPosition); + setTextCursor(editCursor); + } +*/ + // control is pressed + if ( (e->modifiers() & Qt::ControlModifier) && (e->key() == Qt::Key_C) ) + { + if ( isSelectionInEditionZone()) + { + //If Ctrl + C pressed, then undo the current commant + //append(""); + //displayPrompt(); + + //(Thierry Belair:)I humbly suggest that ctrl+C copies the text, as is expected, + //and indicated in the contextual menu + copy(); + return; + } + + } + else { + switch (e->key()) { + case Qt::Key_Tab: + if(isSelectionInEditionZone()) + { + handleTabKeyPress(); + } + return; + + case Qt::Key_Enter: + case Qt::Key_Return: + if (isSelectionInEditionZone()) + { + handleReturnKeyPress(); + } + // ignore return key + return; + + case Qt::Key_Backspace: + if (handleBackspaceKeyPress() || !isSelectionInEditionZone()) + return; + break; + + case Qt::Key_Home: + setHome(e->modifiers() & Qt::ShiftModifier); + case Qt::Key_Down: + if (isInEditionZone()) + { + handleDownKeyPress(); + } + return; + case Qt::Key_Up: + if (isInEditionZone()) + { + handleUpKeyPress(); + } + return; + + //Default behaviour + case Qt::Key_End: + case Qt::Key_Left: + case Qt::Key_Right: + break; + + default: + if (textCursor().hasSelection() ) { + if (!isSelectionInEditionZone()) + { + moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + } + break; + } + else + { //no selection + //when typing normal characters, + //make sure the cursor is positionned in the + //edition zone + if ( !isInEditionZone() ) + { + moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + } + } + } //end of switch + } //end of else : no control pressed + + QTextEdit::keyPressEvent( e ); +} + +//Get the current command +QString QConsole::getCurrentCommand() +{ + QTextCursor cursor = textCursor(); //Get the current command: we just remove the prompt + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, promptLength); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + QString command = cursor.selectedText(); + cursor.clearSelection(); + return command; +} + +//Replace current command with a new one +void QConsole::replaceCurrentCommand(const QString &newCommand) +{ + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, promptLength); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + cursor.insertText(newCommand); +} + +//default implementation: command always complete +bool QConsole::isCommandComplete(const 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() +{ + const int para = textCursor().blockNumber(); + const int index = textCursor().columnNumber(); + return (para > promptParagraph) || ( (para == promptParagraph) && (index >= promptLength) ); +} + + +//Tests whether position (in parameter) is in the edition zone or not (after the prompt +//or in the next lines (in case of multi-line mode) +bool QConsole::isInEditionZone(const int& pos) +{ + QTextCursor cur = textCursor(); + cur.setPosition(pos); + const int para = cur.blockNumber(); + const int index = cur.columnNumber(); + return (para > promptParagraph) || ( (para == promptParagraph) && (index >= promptLength) ); +} + + +//Tests whether the current selection is in th edition zone or not +bool QConsole::isSelectionInEditionZone() +{ + QTextCursor cursor(document()); + int range[2]; + + range[0] = textCursor().selectionStart(); + range[1] = textCursor().selectionEnd(); + for (int i = 0; i < 2; i++) + { + cursor.setPosition(range[i]); + int para = cursor.blockNumber(); + int index = cursor.columnNumber(); + if ((para <= promptParagraph) && ( (para != promptParagraph) || (index < promptLength) )) + { + return false; + } + } + return true; +} + + +//Basically, puts the command into the history list +//And emits a signal (should be called by reimplementations) +QString QConsole::interpretCommand(const QString &command, int *res) +{ + //Add the command to the recordedScript list + if (!*res) + recordedScript.append(command); + //update the history and its index + QString modifiedCommand = command; + modifiedCommand.replace("\n", "\\n"); + history.append(modifiedCommand); + historyIndex = history.size(); + //emit the commandExecuted signal + Q_EMIT commandExecuted(modifiedCommand); + return ""; +} + +//execCommand(QString) executes the command and displays back its result +bool QConsole::execCommand(const QString &command, bool writeCommand, + bool showPrompt, QString *result) +{ + QString modifiedCommand = command; + correctPathName(modifiedCommand); + //Display the prompt with the command first + if (writeCommand) + { + if (getCurrentCommand() != "") + { + append(""); + displayPrompt(); + } + textCursor().insertText(modifiedCommand); + } + //execute the command and get back its text result and its return value + int res = 0; + QString strRes = interpretCommand(modifiedCommand, &res); + //According to the return value, display the result either in red or in blue + if (res == 0) + setTextColor(outColor_); + else + setTextColor(errColor_); + + if(result){ + *result = strRes; + } + if (!(strRes.isEmpty() || strRes.endsWith("\n"))) + strRes.append("\n"); + append(strRes); + moveCursor(QTextCursor::End); + //Display the prompt again + if (showPrompt) + displayPrompt(); + return !res; +} + + +//Change paste behaviour +void QConsole::insertFromMimeData(const QMimeData *source) +{ + if (isSelectionInEditionZone()) + { + QTextEdit::insertFromMimeData(source); + } +} + +//Implement paste with middle mouse button +void QConsole::mousePressEvent(QMouseEvent* event) +{ + oldPosition = textCursor().position(); + if (event->button() == Qt::MidButton) + { + copy(); + QTextCursor cursor = cursorForPosition(event->pos()); + setTextCursor(cursor); + paste(); + return; + } + + QTextEdit::mousePressEvent(event); +} + + +//Redefinition of the dropEvent to have a copy paste +//instead of a cut paste when copying out of the +//editable zone +void QConsole::dropEvent ( QDropEvent * event) +{ + if(!isInEditionZone()) + { + //Execute un drop a drop at the old position + //if the drag started out of the editable zone + QTextCursor cur = textCursor(); + cur.setPosition(oldPosition); + setTextCursor(cur); + } + //Execute a normal drop + QTextEdit::dropEvent(event); +} + + + +void QConsole::dragMoveEvent( QDragMoveEvent * event) +{ + //Get a cursor for the actual mouse position + QTextCursor cur = textCursor(); + cur.setPosition(cursorForPosition(event->pos()).position()); + + if(!isInEditionZone(cursorForPosition(event->pos()).position())) + { + //Ignore the event if out of the editable zone + event->ignore(cursorRect(cur)); + } + else + { + //Accept the event if out of the editable zone + event->accept(cursorRect(cur)); + } +} + + +void QConsole::contextMenuEvent ( QContextMenuEvent * event) +{ + QMenu *menu = new QMenu(this); + + QAction *undo = new QAction(tr("Undo"), this); + undo->setShortcut(tr("Ctrl+Z")); + QAction *redo = new QAction(tr("Redo"), this); + redo->setShortcut(tr("Ctrl+Y")); + QAction *cut = new QAction(tr("Cut"), this); + cut->setShortcut(tr("Ctrl+X")); + QAction *copy = new QAction(tr("Copy"), this); + copy->setShortcut(tr("Ctrl+Ins")); + QAction *paste = new QAction(tr("Paste"), this); + paste->setShortcut(tr("Ctrl+V")); + QAction *del = new QAction(tr("Delete"), this); + del->setShortcut(tr("Del")); + QAction *selectAll = new QAction(tr("Select All"), this); + selectAll->setShortcut(tr("Ctrl+A")); + + menu->addAction(undo); + menu->addAction(redo); + menu->addSeparator(); + menu->addAction(cut); + menu->addAction(copy); + menu->addAction(paste); + menu->addAction(del); + menu->addSeparator(); + menu->addAction(selectAll); + + connect(undo, SIGNAL(triggered()), this, SLOT(undo())); + connect(redo, SIGNAL(triggered()), this, SLOT(redo())); + connect(cut, SIGNAL(triggered()), this, SLOT(cut())); + connect(copy, SIGNAL(triggered()), this, SLOT(copy())); + connect(paste, SIGNAL(triggered()), this, SLOT(paste())); + connect(del, SIGNAL(triggered()), this, SLOT(del())); + connect(selectAll, SIGNAL(triggered()), this, SLOT(selectAll())); + + + menu->exec(event->globalPos()); + + delete menu; +} + + + +void QConsole::cut() +{ + //Cut only in the editing zone, + //perfom a copy otherwise + if(isInEditionZone()) + { + QTextEdit::cut(); + return; + } + + QTextEdit::copy(); +} + + +/* +//Allows pasting with middle mouse button (x window) +//when clicking outside of the edition zone +void QConsole::paste() +{ + restoreOldPosition(); + QTextEdit::paste(); +} +*/ + +void QConsole::del() +{ + //Delete only in the editing zone + if(isInEditionZone()) + { + textCursor().movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); + textCursor().deleteChar(); + } +} + + +void QConsole::correctPathName(QString& pathName) +{ + if(pathName.contains(tr(":\\"))) + { + pathName.replace('\\', tr("/")); + } +}