| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 | 
							- /*=========================================================================
 
-   Library:   CTK
 
-  
 
-   Copyright (c) 2010  Kitware Inc.
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-       http://www.commontk.org/LICENSE
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
-  
 
- =========================================================================*/
 
- /*=========================================================================
 
-    Program: ParaView
 
-    Module:    $RCSfile$
 
-    Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
 
-    All rights reserved.
 
-    ParaView is a free software; you can redistribute it and/or modify it
 
-    under the terms of the ParaView license version 1.2. 
 
-    See License_v1.2.txt for the full ParaView license.
 
-    A copy of this license can be obtained by contacting
 
-    Kitware Inc.
 
-    28 Corporate Drive
 
-    Clifton Park, NY 12065
 
-    USA
 
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
 
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
- =========================================================================*/
 
- // Qt includes
 
- #include <QAbstractItemView>
 
- #include <QApplication>
 
- #include <QClipboard>
 
- #include <QCompleter>
 
- #include <QKeyEvent>
 
- #include <QPointer>
 
- #include <QTextCursor>
 
- #include <QTextEdit>
 
- #include <QVBoxLayout>
 
- #include <QScrollBar>
 
- // CTK includes
 
- #include "ctkConsoleWidget.h"
 
- /////////////////////////////////////////////////////////////////////////
 
- // ctkConsoleWidget::pqImplementation
 
- class ctkConsoleWidget::pqImplementation :
 
-   public QTextEdit
 
- {
 
- public:
 
-   pqImplementation(ctkConsoleWidget& p) :
 
-     QTextEdit(&p),
 
-     Parent(p),
 
-     InteractivePosition(documentEnd())
 
-   {
 
-     this->setTabChangesFocus(false);
 
-     this->setAcceptDrops(false);
 
-     this->setAcceptRichText(false);
 
-     this->setUndoRedoEnabled(false);
 
-     
 
-     QFont f;
 
-     f.setFamily("Courier");
 
-     f.setStyleHint(QFont::TypeWriter);
 
-     f.setFixedPitch(true);
 
-     
 
-     QTextCharFormat format;
 
-     format.setFont(f);
 
-     format.setForeground(QColor(0, 0, 0));
 
-     this->setCurrentCharFormat(format);
 
-     
 
-     this->CommandHistory.append("");
 
-     this->CommandPosition = 0;
 
-   }
 
-   void keyPressEvent(QKeyEvent* e)
 
-   {
 
-   if (this->Completer && this->Completer->popup()->isVisible())
 
-     {
 
-     // The following keys are forwarded by the completer to the widget
 
-     switch (e->key())
 
-       {
 
-       case Qt::Key_Enter:
 
-       case Qt::Key_Return:
 
-       case Qt::Key_Escape:
 
-       case Qt::Key_Tab:
 
-       case Qt::Key_Backtab:
 
-         e->ignore();
 
-         return; // let the completer do default behavior
 
-       default:
 
-         break;
 
-       }
 
-     }
 
-     QTextCursor text_cursor = this->textCursor();
 
-     // Set to true if there's a current selection
 
-     const bool selection = text_cursor.anchor() != text_cursor.position();
 
-     // Set to true if the cursor overlaps the history area
 
-     const bool history_area =
 
-       text_cursor.anchor() < this->InteractivePosition
 
-       || text_cursor.position() < this->InteractivePosition;
 
-     // Allow copying anywhere in the console ...
 
-     if(e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier)
 
-       {
 
-       if(selection)
 
-         {
 
-         this->copy();
 
-         }
 
-         
 
-       e->accept();
 
-       return;
 
-       }
 
-       
 
-     // Allow cut only if the selection is limited to the interactive area ...
 
-     if(e->key() == Qt::Key_X && e->modifiers() == Qt::ControlModifier)
 
-       {
 
-       if(selection && !history_area)
 
-         {
 
-         this->cut();
 
-         }
 
-         
 
-       e->accept();
 
-       return;
 
-       }
 
-     
 
-     // Allow paste only if the selection is in the interactive area ...
 
-     if(e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier)
 
-       {
 
-       if(!history_area)
 
-         {
 
-         const QMimeData* const clipboard = QApplication::clipboard()->mimeData();
 
-         const QString text = clipboard->text();
 
-         if(!text.isNull())
 
-           {
 
-           text_cursor.insertText(text);
 
-           this->updateCommandBuffer();
 
-           }
 
-         }
 
-         
 
-       e->accept();
 
-       return;
 
-       }
 
-     
 
-     // Force the cursor back to the interactive area
 
-     if(history_area && e->key() != Qt::Key_Control)
 
-       {
 
-       text_cursor.setPosition(this->documentEnd());
 
-       this->setTextCursor(text_cursor);
 
-       }
 
-     
 
-     switch(e->key())
 
-       {
 
-       case Qt::Key_Up:
 
-         e->accept();
 
-         if (this->CommandPosition > 0)
 
-           {
 
-           this->replaceCommandBuffer(this->CommandHistory[--this->CommandPosition]);
 
-           }
 
-         break;
 
-         
 
-       case Qt::Key_Down:
 
-         e->accept();
 
-         if (this->CommandPosition < this->CommandHistory.size() - 2)
 
-           {
 
-           this->replaceCommandBuffer(this->CommandHistory[++this->CommandPosition]);
 
-           }
 
-         else
 
-           {
 
-           this->CommandPosition = this->CommandHistory.size()-1;
 
-           this->replaceCommandBuffer("");
 
-           }
 
-         break;
 
-       case Qt::Key_Left:
 
-         if (text_cursor.position() > this->InteractivePosition)
 
-           {
 
-           QTextEdit::keyPressEvent(e);
 
-           }
 
-         else
 
-           {
 
-           e->accept();
 
-           }
 
-         break;
 
-         
 
-   
 
-       case Qt::Key_Delete:
 
-         e->accept();
 
-         QTextEdit::keyPressEvent(e);
 
-         this->updateCommandBuffer();
 
-         break;
 
-         
 
-       case Qt::Key_Backspace:
 
-         e->accept();
 
-         if(text_cursor.position() > this->InteractivePosition)
 
-           {
 
-           QTextEdit::keyPressEvent(e);
 
-           this->updateCommandBuffer();
 
-           this->updateCompleterIfVisible();
 
-           }
 
-         break;
 
-       case Qt::Key_Tab:
 
-         e->accept();
 
-         this->updateCompleter();
 
-         this->selectCompletion();
 
-         break;
 
-         
 
-       case Qt::Key_Home:
 
-         e->accept();
 
-         text_cursor.setPosition(this->InteractivePosition);
 
-         this->setTextCursor(text_cursor);
 
-         break;
 
-         
 
-       case Qt::Key_Return:
 
-       case Qt::Key_Enter:
 
-         e->accept();
 
-         
 
-         text_cursor.setPosition(this->documentEnd());
 
-         this->setTextCursor(text_cursor);
 
-         
 
-         this->internalExecuteCommand();
 
-         break;
 
-         
 
-       default:
 
-         e->accept();
 
-         QTextEdit::keyPressEvent(e);
 
-         this->updateCommandBuffer();
 
-         this->updateCompleterIfVisible();
 
-         break;
 
-       }
 
-   }
 
-   
 
-   /// Returns the end of the document
 
-   /*const*/ int documentEnd()
 
-   {
 
-     QTextCursor c(this->document());
 
-     c.movePosition(QTextCursor::End);
 
-     return c.position();
 
-   }
 
-   void focusOutEvent(QFocusEvent *e)
 
-   {
 
-     QTextEdit::focusOutEvent(e);
 
-     // For some reason the QCompleter tries to set the focus policy to
 
-     // NoFocus, set let's make sure we set it back to the default WheelFocus.
 
-     this->setFocusPolicy(Qt::WheelFocus);
 
-   }
 
-   void updateCompleterIfVisible()
 
-   {
 
-     if (this->Completer && this->Completer->popup()->isVisible())
 
-       {
 
-       this->updateCompleter();
 
-       }
 
-   }
 
-   /// If there is exactly 1 completion, insert it and hide the completer,
 
-   /// else do nothing.
 
-   void selectCompletion()
 
-   {
 
-   if (this->Completer && this->Completer->completionCount() == 1)
 
-     {
 
-     this->Parent.insertCompletion(this->Completer->currentCompletion());
 
-     this->Completer->popup()->hide();
 
-     }
 
-   }
 
-   void updateCompleter()
 
-   {
 
-     if (this->Completer)
 
-       {
 
-       // Get the text between the current cursor position
 
-       // and the start of the line
 
-       QTextCursor text_cursor = this->textCursor();
 
-       text_cursor.setPosition(this->InteractivePosition, QTextCursor::KeepAnchor);
 
-       QString commandText = text_cursor.selectedText();
 
-       // Call the completer to update the completion model
 
-       this->Completer->updateCompletionModel(commandText);
 
-       // Place and show the completer if there are available completions
 
-       if (this->Completer->completionCount())
 
-         {
 
-         // Get a QRect for the cursor at the start of the
 
-         // current word and then translate it down 8 pixels.
 
-         text_cursor = this->textCursor();
 
-         text_cursor.movePosition(QTextCursor::StartOfWord);
 
-         QRect cr = this->cursorRect(text_cursor);
 
-         cr.translate(0,8);
 
-         cr.setWidth(this->Completer->popup()->sizeHintForColumn(0)
 
-           + this->Completer->popup()->verticalScrollBar()->sizeHint().width());
 
-         this->Completer->complete(cr);
 
-         }
 
-       else
 
-         {
 
-         this->Completer->popup()->hide();
 
-         }
 
-       }
 
-   }
 
-   
 
-   /// Update the contents of the command buffer from the contents of the widget
 
-   void updateCommandBuffer()
 
-   {
 
-     this->commandBuffer() = this->toPlainText().mid(this->InteractivePosition);
 
-   }
 
-   
 
-   /// Replace the contents of the command buffer, updating the display
 
-   void replaceCommandBuffer(const QString& Text)
 
-   {
 
-     this->commandBuffer() = Text;
 
-   
 
-     QTextCursor c(this->document());
 
-     c.setPosition(this->InteractivePosition);
 
-     c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
 
-     c.removeSelectedText();
 
-     c.insertText(Text);
 
-   }
 
-   
 
-   /// References the buffer where the current un-executed command is stored
 
-   QString& commandBuffer()
 
-   {
 
-     return this->CommandHistory.back();
 
-   }
 
-   
 
-   /// Implements command-execution
 
-   void internalExecuteCommand()
 
-     {
 
-     // First update the history cache. It's essential to update the
 
-     // this->CommandPosition before calling internalExecuteCommand() since that
 
-     // can result in a clearing of the current command (BUG #8765).
 
-     QString command = this->commandBuffer();
 
-     if (!command.isEmpty()) // Don't store empty commands in the history
 
-       {
 
-       this->CommandHistory.push_back("");
 
-       this->CommandPosition = this->CommandHistory.size() - 1;
 
-       }
 
-     QTextCursor c(this->document());
 
-     c.movePosition(QTextCursor::End);
 
-     c.insertText("\n");
 
-     this->InteractivePosition = this->documentEnd();
 
-     this->Parent.internalExecuteCommand(command);
 
-     }
 
-   void setCompleter(ctkConsoleWidgetCompleter* completer)
 
-     {
 
-     if (this->Completer)
 
-       {
 
-       this->Completer->setWidget(0);
 
-       QObject::disconnect(this->Completer, SIGNAL(activated(const QString&)),
 
-                         &this->Parent, SLOT(insertCompletion(const QString&)));
 
-       }
 
-     this->Completer = completer;
 
-     if (this->Completer)
 
-       {
 
-       this->Completer->setWidget(this);
 
-       QObject::connect(this->Completer, SIGNAL(activated(const QString&)),
 
-                       &this->Parent, SLOT(insertCompletion(const QString&)));
 
-       }
 
-     }
 
-   
 
-   /// Stores a back-reference to our owner
 
-   ctkConsoleWidget& Parent;
 
-   /// A custom completer
 
-   QPointer<ctkConsoleWidgetCompleter> Completer;
 
-   /** Stores the beginning of the area of interactive input, outside which
 
-   changes can't be made to the text edit contents */
 
-   int InteractivePosition;
 
-   /// Stores command-history, plus the current command buffer
 
-   QStringList CommandHistory;
 
-   /// Stores the current position in the command-history
 
-   int CommandPosition;
 
- };
 
- /////////////////////////////////////////////////////////////////////////
 
- // ctkConsoleWidget
 
- ctkConsoleWidget::ctkConsoleWidget(QWidget* Parent) :
 
-   QWidget(Parent),
 
-   Implementation(new pqImplementation(*this))
 
- {
 
-   QVBoxLayout* const l = new QVBoxLayout(this);
 
-   l->setMargin(0);
 
-   l->addWidget(this->Implementation);
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkConsoleWidget::~ctkConsoleWidget()
 
- {
 
-   delete this->Implementation;
 
- }
 
- //-----------------------------------------------------------------------------
 
- QTextCharFormat ctkConsoleWidget::getFormat()
 
- {
 
-   return this->Implementation->currentCharFormat();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::setFormat(const QTextCharFormat& Format)
 
- {
 
-   this->Implementation->setCurrentCharFormat(Format);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::setCompleter(ctkConsoleWidgetCompleter* completer)
 
- {
 
-   this->Implementation->setCompleter(completer);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::insertCompletion(const QString& completion)
 
- {
 
-   QTextCursor tc = this->Implementation->textCursor();
 
-   tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor);
 
-   if (tc.selectedText()==".")
 
-     {
 
-     tc.insertText(QString(".") + completion);
 
-     }
 
-   else
 
-     {
 
-     tc = this->Implementation->textCursor();
 
-     tc.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
 
-     tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
 
-     tc.insertText(completion);
 
-     this->Implementation->setTextCursor(tc);
 
-     }
 
-   this->Implementation->updateCommandBuffer();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::printString(const QString& Text)
 
- {
 
-   this->Implementation->textCursor().movePosition(QTextCursor::End);
 
-   this->Implementation->textCursor().insertText(Text);
 
-   this->Implementation->InteractivePosition = this->Implementation->documentEnd();
 
-   this->Implementation->ensureCursorVisible();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::printCommand(const QString& cmd)
 
- {
 
-   this->Implementation->textCursor().insertText(cmd);
 
-   this->Implementation->updateCommandBuffer();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::prompt(const QString& text)
 
- {
 
-   QTextCursor text_cursor = this->Implementation->textCursor();
 
-   // if the cursor is currently on a clean line, do nothing, otherwise we move
 
-   // the cursor to a new line before showing the prompt.
 
-   text_cursor.movePosition(QTextCursor::StartOfLine);
 
-   int startpos = text_cursor.position();
 
-   text_cursor.movePosition(QTextCursor::EndOfLine);
 
-   int endpos = text_cursor.position();
 
-   if (endpos != startpos)
 
-     {
 
-     this->Implementation->textCursor().insertText("\n");
 
-     }
 
-   this->Implementation->textCursor().insertText(text);
 
-   this->Implementation->InteractivePosition = this->Implementation->documentEnd();
 
-   this->Implementation->ensureCursorVisible();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::clear()
 
- {
 
-   this->Implementation->clear();
 
-   // For some reason the QCompleter tries to set the focus policy to
 
-   // NoFocus, set let's make sure we set it back to the default WheelFocus.
 
-   this->Implementation->setFocusPolicy(Qt::WheelFocus);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkConsoleWidget::internalExecuteCommand(const QString& Command)
 
- {
 
-   emit this->executeCommand(Command);
 
- }
 
 
  |