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 <QTextCodec>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTextDocumentFragment>
|
#include <QTextDocumentFragment>
|
||||||
|
#include <QStringListModel>
|
||||||
|
|
||||||
#include "ChatWidget.h"
|
#include "ChatWidget.h"
|
||||||
#include "ui_ChatWidget.h"
|
#include "ui_ChatWidget.h"
|
||||||
@ -127,6 +128,16 @@ ChatWidget::ChatWidget(QWidget *parent) :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
resetStatusBar();
|
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()
|
ChatWidget::~ChatWidget()
|
||||||
@ -245,6 +256,13 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
completionWord.clear();
|
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) {
|
if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) {
|
||||||
// Enter pressed
|
// Enter pressed
|
||||||
if (Settings->getChatSendMessageWithCtrlReturn()) {
|
if (Settings->getChatSendMessageWithCtrlReturn()) {
|
||||||
@ -397,6 +415,45 @@ void ChatWidget::completeNickname(bool reverse)
|
|||||||
cursor.endEditBlock();
|
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)
|
void ChatWidget::addToolsAction(QAction *action)
|
||||||
{
|
{
|
||||||
ui->pushtoolsButton->menu()->addAction(action);
|
ui->pushtoolsButton->menu()->addAction(action);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#define CHATWIDGET_H
|
#define CHATWIDGET_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QCompleter>
|
||||||
#include "gui/common/HashBox.h"
|
#include "gui/common/HashBox.h"
|
||||||
#include "ChatStyle.h"
|
#include "ChatStyle.h"
|
||||||
#include "gui/style/RSStyle.h"
|
#include "gui/style/RSStyle.h"
|
||||||
@ -137,6 +137,7 @@ private:
|
|||||||
void processSettings(bool load);
|
void processSettings(bool load);
|
||||||
|
|
||||||
void completeNickname(bool reverse);
|
void completeNickname(bool reverse);
|
||||||
|
QAbstractItemModel *modelFromPeers();
|
||||||
|
|
||||||
std::string peerId;
|
std::string peerId;
|
||||||
QString title;
|
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.
|
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;
|
Ui::ChatWidget *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,10 +23,16 @@
|
|||||||
#include <QTextDocumentFragment>
|
#include <QTextDocumentFragment>
|
||||||
#include "MimeTextEdit.h"
|
#include "MimeTextEdit.h"
|
||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
MimeTextEdit::MimeTextEdit(QWidget *parent)
|
MimeTextEdit::MimeTextEdit(QWidget *parent)
|
||||||
: QTextEdit(parent)
|
: QTextEdit(parent), mCompleter(0)
|
||||||
{
|
{
|
||||||
|
mCompleterKeyModifiers=Qt::ControlModifier;
|
||||||
|
mCompleterKey=Qt::Key_Space;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
|
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
|
||||||
@ -65,3 +71,128 @@ void MimeTextEdit::insertFromMimeData(const QMimeData* source)
|
|||||||
|
|
||||||
return QTextEdit::insertFromMimeData(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
|
#define MIMETEXTEDIT_H
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
#include <QCompleter>
|
||||||
|
|
||||||
class MimeTextEdit : public QTextEdit
|
class MimeTextEdit : public QTextEdit
|
||||||
{
|
{
|
||||||
@ -31,9 +32,33 @@ class MimeTextEdit : public QTextEdit
|
|||||||
public:
|
public:
|
||||||
MimeTextEdit(QWidget *parent = 0);
|
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:
|
protected:
|
||||||
virtual bool canInsertFromMimeData(const QMimeData* source) const;
|
virtual bool canInsertFromMimeData(const QMimeData* source) const;
|
||||||
virtual void insertFromMimeData(const QMimeData* source);
|
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