mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
added completer to MimeTextEdit and ChatWidget (Patch from Phenom)
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6475 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
33f4e5b779
commit
90e7a3cd54
@ -31,6 +31,7 @@
|
||||
#include <QTextCodec>
|
||||
#include <QTimer>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QStringListModel>
|
||||
|
||||
#include "ChatWidget.h"
|
||||
#include "ui_ChatWidget.h"
|
||||
@ -127,6 +128,16 @@ ChatWidget::ChatWidget(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
resetStatusBar();
|
||||
|
||||
completer = new QCompleter(this);
|
||||
completer->setModel(modelFromPeers());
|
||||
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer->setWrapAround(false);
|
||||
ui->chatTextEdit->setCompleter(completer);
|
||||
ui->chatTextEdit->setCompleterKeyModifiers(Qt::ControlModifier);
|
||||
ui->chatTextEdit->setCompleterKey(Qt::Key_Space);
|
||||
|
||||
}
|
||||
|
||||
ChatWidget::~ChatWidget()
|
||||
@ -245,6 +256,13 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
completionWord.clear();
|
||||
}
|
||||
}
|
||||
if ((keyEvent->modifiers() & ui->chatTextEdit->getCompleterKeyModifiers()) && keyEvent->key() == ui->chatTextEdit->getCompleterKey()) {
|
||||
completer->setModel(modelFromPeers());
|
||||
}
|
||||
if (keyEvent->text()=="@") {
|
||||
ui->chatTextEdit->forceCompleterShowNextKeyEvent("@");
|
||||
completer->setModel(modelFromPeers());
|
||||
}
|
||||
if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) {
|
||||
// Enter pressed
|
||||
if (Settings->getChatSendMessageWithCtrlReturn()) {
|
||||
@ -397,6 +415,45 @@ void ChatWidget::completeNickname(bool reverse)
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
|
||||
QAbstractItemModel *ChatWidget::modelFromPeers()
|
||||
{
|
||||
// Find lobby we belong to
|
||||
const ChatLobbyInfo *lobby = NULL;
|
||||
std::list<ChatLobbyInfo> lobbies;
|
||||
rsMsgs->getChatLobbyList(lobbies);
|
||||
|
||||
std::list<ChatLobbyInfo>::const_iterator lobbyIt;
|
||||
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
|
||||
std::string vpid;
|
||||
if (rsMsgs->getVirtualPeerId(lobbyIt->lobby_id, vpid)) {
|
||||
if (vpid == peerId) {
|
||||
lobby = &*lobbyIt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lobby)
|
||||
return new QStringListModel(completer);
|
||||
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
#endif
|
||||
// Get participants list
|
||||
QStringList participants;
|
||||
for ( std::map<std::string,time_t>::const_iterator it = lobby->nick_names.begin();
|
||||
it != lobby->nick_names.end();
|
||||
it++) {
|
||||
participants.push_front(QString::fromUtf8(it->first.c_str()));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
QApplication::restoreOverrideCursor();
|
||||
#endif
|
||||
return new QStringListModel(participants, completer);
|
||||
}
|
||||
|
||||
void ChatWidget::addToolsAction(QAction *action)
|
||||
{
|
||||
ui->pushtoolsButton->menu()->addAction(action);
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define CHATWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <QCompleter>
|
||||
#include "gui/common/HashBox.h"
|
||||
#include "ChatStyle.h"
|
||||
#include "gui/style/RSStyle.h"
|
||||
@ -137,6 +137,7 @@ private:
|
||||
void processSettings(bool load);
|
||||
|
||||
void completeNickname(bool reverse);
|
||||
QAbstractItemModel *modelFromPeers();
|
||||
|
||||
std::string peerId;
|
||||
QString title;
|
||||
@ -164,6 +165,8 @@ private:
|
||||
|
||||
TransferRequestFlags mDefaultExtraFileFlags ; // flags for extra files shared in this chat. Will be 0 by default, but might be ANONYMOUS for chat lobbies.
|
||||
|
||||
QCompleter *completer;
|
||||
|
||||
Ui::ChatWidget *ui;
|
||||
};
|
||||
|
||||
|
@ -23,10 +23,16 @@
|
||||
#include <QTextDocumentFragment>
|
||||
#include "MimeTextEdit.h"
|
||||
#include "util/HandleRichText.h"
|
||||
#include <QCompleter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QKeyEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
MimeTextEdit::MimeTextEdit(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
: QTextEdit(parent), mCompleter(0)
|
||||
{
|
||||
mCompleterKeyModifiers=Qt::ControlModifier;
|
||||
mCompleterKey=Qt::Key_Space;
|
||||
}
|
||||
|
||||
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
|
||||
@ -65,3 +71,128 @@ void MimeTextEdit::insertFromMimeData(const QMimeData* source)
|
||||
|
||||
return QTextEdit::insertFromMimeData(source);
|
||||
}
|
||||
|
||||
void MimeTextEdit::setCompleter(QCompleter *completer)
|
||||
{
|
||||
if (mCompleter)
|
||||
QObject::disconnect(mCompleter, 0, this, 0);
|
||||
|
||||
mCompleter = completer;
|
||||
|
||||
if (!mCompleter)
|
||||
return;
|
||||
|
||||
mCompleter->setWidget(this);
|
||||
mCompleter->setCompletionMode(QCompleter::PopupCompletion);
|
||||
mCompleter->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
QObject::connect(mCompleter, SIGNAL(activated(QString)),
|
||||
this, SLOT(insertCompletion(QString)));
|
||||
}
|
||||
|
||||
QCompleter *MimeTextEdit::completer() const
|
||||
{
|
||||
return mCompleter;
|
||||
}
|
||||
|
||||
void MimeTextEdit::insertCompletion(const QString& completion)
|
||||
{
|
||||
if (mCompleter->widget() != this)
|
||||
return;
|
||||
QTextCursor tc = textCursor();
|
||||
if (mCompleter->completionPrefix().length()>0) {
|
||||
tc.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
|
||||
}
|
||||
tc.removeSelectedText();
|
||||
tc.insertText(mCompleterStartString+completion);
|
||||
mCompleterStartString="";
|
||||
setTextCursor(tc);
|
||||
}
|
||||
|
||||
QString MimeTextEdit::textUnderCursor() const
|
||||
{
|
||||
QTextCursor tc = textCursor();
|
||||
tc.select(QTextCursor::WordUnderCursor);
|
||||
return tc.selectedText();
|
||||
}
|
||||
|
||||
void MimeTextEdit::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
if (mCompleter)
|
||||
mCompleter->setWidget(this);
|
||||
QTextEdit::focusInEvent(e);
|
||||
}
|
||||
|
||||
void MimeTextEdit::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
|
||||
if (mCompleter && mCompleter->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:
|
||||
mCompleter->popup()->hide();
|
||||
mForceCompleterShowNextKeyEvent=false;
|
||||
e->ignore();
|
||||
return; // let the completer do default behavior
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isShortcut = ((e->modifiers() & mCompleterKeyModifiers) && e->key() == mCompleterKey);
|
||||
if (isShortcut && !mForceCompleterShowNextKeyEvent) {
|
||||
mCompleterStartString="";
|
||||
}
|
||||
isShortcut |= mForceCompleterShowNextKeyEvent;
|
||||
if (!mCompleter || !isShortcut) // do not process the shortcut when we have a completer
|
||||
QTextEdit::keyPressEvent(e);
|
||||
|
||||
if (!isShortcut && (mCompleter && !mCompleter->popup()->isVisible())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mForceCompleterShowNextKeyEvent) {
|
||||
static QString eow(" ~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
|
||||
if (!isShortcut && ( e->text().isEmpty() || eow.contains(e->text().right(1)))){
|
||||
mCompleter->popup()->hide();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString completionPrefix = textUnderCursor();
|
||||
if (completionPrefix != mCompleter->completionPrefix()) {
|
||||
mCompleter->setCompletionPrefix(completionPrefix);
|
||||
mCompleter->popup()->setCurrentIndex(mCompleter->completionModel()->index(0, 0));
|
||||
}
|
||||
QRect cr = cursorRect();
|
||||
cr.setWidth(mCompleter->popup()->sizeHintForColumn(0)
|
||||
+ mCompleter->popup()->verticalScrollBar()->sizeHint().width());
|
||||
mCompleter->complete(cr); // popup it up!
|
||||
mForceCompleterShowNextKeyEvent=false;
|
||||
}
|
||||
|
||||
void MimeTextEdit::setCompleterKeyModifiers(Qt::KeyboardModifier modifiers)
|
||||
{
|
||||
mCompleterKeyModifiers=modifiers;
|
||||
}
|
||||
Qt::KeyboardModifier MimeTextEdit::getCompleterKeyModifiers() const
|
||||
{
|
||||
return mCompleterKeyModifiers;
|
||||
}
|
||||
|
||||
void MimeTextEdit::setCompleterKey(Qt::Key key)
|
||||
{
|
||||
mCompleterKey=key;
|
||||
}
|
||||
Qt::Key MimeTextEdit::getCompleterKey() const
|
||||
{
|
||||
return mCompleterKey;
|
||||
}
|
||||
void MimeTextEdit::forceCompleterShowNextKeyEvent(QString startString="")
|
||||
{
|
||||
mForceCompleterShowNextKeyEvent=true;
|
||||
mCompleterStartString=startString;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define MIMETEXTEDIT_H
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QCompleter>
|
||||
|
||||
class MimeTextEdit : public QTextEdit
|
||||
{
|
||||
@ -31,9 +32,33 @@ class MimeTextEdit : public QTextEdit
|
||||
public:
|
||||
MimeTextEdit(QWidget *parent = 0);
|
||||
|
||||
//Form here: http://qt-project.org/doc/qt-4.8/tools-customcompleter.html
|
||||
void setCompleter(QCompleter *completer);
|
||||
QCompleter *completer() const;
|
||||
void setCompleterKeyModifiers(Qt::KeyboardModifier modifiers);
|
||||
Qt::KeyboardModifier getCompleterKeyModifiers() const;
|
||||
void setCompleterKey(Qt::Key key);
|
||||
Qt::Key getCompleterKey() const;
|
||||
void forceCompleterShowNextKeyEvent(QString startString);
|
||||
|
||||
protected:
|
||||
virtual bool canInsertFromMimeData(const QMimeData* source) const;
|
||||
virtual void insertFromMimeData(const QMimeData* source);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void focusInEvent(QFocusEvent *e);
|
||||
|
||||
private slots:
|
||||
void insertCompletion(const QString &completion);
|
||||
|
||||
private:
|
||||
QString textUnderCursor() const;
|
||||
|
||||
private:
|
||||
QCompleter *mCompleter;
|
||||
Qt::KeyboardModifier mCompleterKeyModifiers;
|
||||
Qt::Key mCompleterKey;
|
||||
bool mForceCompleterShowNextKeyEvent;
|
||||
QString mCompleterStartString;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user