Tab and Ctrl+Space completion for chatbar.

This commit is contained in:
Stefan Hacker 2009-10-13 21:00:31 +02:00
parent 055c13f2b3
commit 56f5f978c0
5 changed files with 123 additions and 5 deletions

View File

@ -29,6 +29,15 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "CustomElements.h"
#include "ClientUser.h"
/*!
\fn int ChatbarLineEdit::completeAtCursor()
The bar will try to complete the username, if the nickname
is already complete it will try to find a longer match. If
there is none it will cycle the nicknames alphabetically.
Nothing is done on mismatch.
*/
void ChatbarLineEdit::focusInEvent(QFocusEvent *) {
if (bDefaultVisible) {
@ -57,7 +66,7 @@ void ChatbarLineEdit::focusOutEvent(QFocusEvent *) {
ChatbarLineEdit::ChatbarLineEdit(QWidget *p) : QLineEdit(p) {
bDefaultVisible = true;
setDefaultText(tr("Type chat message here"));
};
}
void ChatbarLineEdit::setDefaultText(const QString &new_default) {
qsDefaultText = new_default;
@ -72,6 +81,86 @@ void ChatbarLineEdit::setDefaultText(const QString &new_default) {
}
}
bool ChatbarLineEdit::event(QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *kev = static_cast<QKeyEvent*>(event);
if (kev->key() == Qt::Key_Tab) {
emit tabPressed();
return true;
}
else if (kev->key() == Qt::Key_Space && kev->modifiers() == Qt::ControlModifier) {
emit ctrlSpacePressed();
return true;
}
}
return QLineEdit::event(event);
}
unsigned int ChatbarLineEdit::completeAtCursor() {
// Get an alphabetically sorted list of usernames
unsigned int id = 0;
QList<QString> qlsUsernames;
if (ClientUser::c_qmUsers.empty()) return id;
foreach (ClientUser *usr, ClientUser::c_qmUsers) {
qlsUsernames.append(usr->qsName);
}
qSort(qlsUsernames);
QString newtext;
newtext = text();
QString target = QString();
if (newtext.isEmpty()) {
target = qlsUsernames.first();
newtext = target;
}
else {
// Get the word before the cursor
bool bBaseIsName = false;
int iend = cursorPosition();
int istart = newtext.lastIndexOf(QLatin1Char(' '), iend - 1) + 1;
QString base = newtext.mid(istart, iend - istart);
if (qlsUsernames.last() == base) {
bBaseIsName = true;
target = qlsUsernames.first();
}
else {
if (qlsUsernames.contains(base)) {
// Prevent to complete to what's already there
while (qlsUsernames.takeFirst() != base) {}
bBaseIsName = true;
}
foreach (QString name, qlsUsernames) {
if (name.startsWith(base, Qt::CaseInsensitive)) {
target = name;
break;
}
}
}
if (bBaseIsName && target.isEmpty() && !qlsUsernames.empty()) {
// If autocomplete failed and base was a name get the next one
target = qlsUsernames.first();
}
if (!target.isEmpty()) {
newtext.replace(istart, base.length(), target);
}
}
if (!target.isEmpty()) {
foreach (ClientUser *usr, ClientUser::c_qmUsers) {
if (usr->qsName == target) {
id = usr->uiSession;
break;
}
}
setText(newtext);
}
return id;
}
DockTitleBar::DockTitleBar() {
qtTick = new QTimer(this);

View File

@ -42,9 +42,14 @@ class ChatbarLineEdit : public QLineEdit {
bool bDefaultVisible;
void focusInEvent(QFocusEvent *);
void focusOutEvent(QFocusEvent *);
bool event(QEvent *);
signals:
void tabPressed(void);
void ctrlSpacePressed(void);
public:
ChatbarLineEdit(QWidget *p = NULL);
void setDefaultText(const QString &);
unsigned int completeAtCursor();
};
class DockTitleBar : public QWidget {

View File

@ -57,6 +57,18 @@
#include "NetworkConfig.h"
#include "ACL.h"
/*!
\fn void MainWindow::on_qleChat_tabPressed()
Controlls tab username completion for the chatbar.
\see ChatbarLineEdit::completeAtCursor()
*/
/*!
\fn void MainWindow::on_qleChat_ctrlSpacePressed()
Controlls ctrl space username completion and selection for the chatbar.
\see ChatbarLineEdit::completeAtCursor()
*/
/*!
\fn void MainWindow::qtvUserCurrentChanged(const QModelIndex &, const QModelIndex &)
This function updates the qleChatbar default text according to
@ -1021,6 +1033,16 @@ void MainWindow::on_qleChat_returnPressed() {
qleChat->clear();
}
void MainWindow::on_qleChat_tabPressed() {
qleChat->completeAtCursor();
}
void MainWindow::on_qleChat_ctrlSpacePressed() {
unsigned int res = qleChat->completeAtCursor();
if (res == 0) return;
qtvUsers->setCurrentIndex(pmModel->index(ClientUser::get(res)));
}
void MainWindow::on_qmConfig_aboutToShow() {
// Don't remove the config, as that messes up OSX.
foreach(QAction *a, qmConfig->actions())

View File

@ -167,6 +167,8 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
void on_qaHelpVersionCheck_triggered();
void on_qaQuit_triggered();
void on_qleChat_returnPressed();
void on_qleChat_tabPressed();
void on_qleChat_ctrlSpacePressed();
void on_qteLog_customContextMenuRequested(const QPoint &pos);
void on_qteLog_anchorClicked(const QUrl &);
void on_qteLog_highlighted(const QUrl & link);

View File

@ -92,10 +92,6 @@ class UserModel : public QAbstractItemModel {
QSet<Channel *> qsLinked;
QMap<QString, ClientUser *> qmHashes;
QModelIndex index(ClientUser *, int column = 0) const;
QModelIndex index(Channel *, int column = 0) const;
QModelIndex index(ModelItem *) const;
void recursiveClone(const ModelItem *old, ModelItem *item, QModelIndexList &from, QModelIndexList &to);
ModelItem *moveItem(ModelItem *oldparent, ModelItem *newparent, ModelItem *item);
@ -104,6 +100,10 @@ class UserModel : public QAbstractItemModel {
UserModel(QObject *parent = 0);
~UserModel();
QModelIndex index(ClientUser *, int column = 0) const;
QModelIndex index(Channel *, int column = 0) const;
QModelIndex index(ModelItem *) const;
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;