mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 23:16:50 +02:00
Added a basic version of the chat window.
This commit is contained in:
parent
1c2e752f3c
commit
437cadf360
8 changed files with 612 additions and 1 deletions
|
@ -161,7 +161,7 @@ Menu::Menu() :
|
||||||
QMenu* toolsMenu = addMenu("Tools");
|
QMenu* toolsMenu = addMenu("Tools");
|
||||||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor()));
|
addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor()));
|
||||||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::FstUploader, 0, Application::getInstance(), SLOT(uploadFST()));
|
addActionToQMenuAndActionHash(toolsMenu, MenuOption::FstUploader, 0, Application::getInstance(), SLOT(uploadFST()));
|
||||||
|
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, 0, this, SLOT(showChat()));
|
||||||
|
|
||||||
QMenu* viewMenu = addMenu("View");
|
QMenu* viewMenu = addMenu("View");
|
||||||
|
|
||||||
|
@ -1021,6 +1021,24 @@ void Menu::showMetavoxelEditor() {
|
||||||
_MetavoxelEditor->raise();
|
_MetavoxelEditor->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::showChat() {
|
||||||
|
if (!_chatWindow) {
|
||||||
|
_chatWindow = new ChatWindow();
|
||||||
|
QMainWindow* mainWindow = Application::getInstance()->getWindow();
|
||||||
|
|
||||||
|
// the height of the title bar is given by frameGeometry().height() - geometry().height()
|
||||||
|
// however, frameGeometry() is initialised after showing (Qt queries the OS windowing system)
|
||||||
|
// on the other hand, moving a window after showing it flickers; so just use some reasonable value
|
||||||
|
int titleBarHeight = 16;
|
||||||
|
_chatWindow->setGeometry(mainWindow->width() - _chatWindow->width(),
|
||||||
|
mainWindow->geometry().y() + titleBarHeight,
|
||||||
|
_chatWindow->width(),
|
||||||
|
mainWindow->height() - titleBarHeight);
|
||||||
|
_chatWindow->show();
|
||||||
|
}
|
||||||
|
_chatWindow->raise();
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::audioMuteToggled() {
|
void Menu::audioMuteToggled() {
|
||||||
QAction *muteAction = _actionHash.value(MenuOption::MuteAudio);
|
QAction *muteAction = _actionHash.value(MenuOption::MuteAudio);
|
||||||
muteAction->setChecked(Application::getInstance()->getAudio()->getMuted());
|
muteAction->setChecked(Application::getInstance()->getAudio()->getMuted());
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include <MenuItemProperties.h>
|
#include <MenuItemProperties.h>
|
||||||
#include <OctreeConstants.h>
|
#include <OctreeConstants.h>
|
||||||
|
|
||||||
|
#include <ui/ChatWindow.h>
|
||||||
|
|
||||||
const float ADJUST_LOD_DOWN_FPS = 40.0;
|
const float ADJUST_LOD_DOWN_FPS = 40.0;
|
||||||
const float ADJUST_LOD_UP_FPS = 55.0;
|
const float ADJUST_LOD_UP_FPS = 55.0;
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@ class QSettings;
|
||||||
class BandwidthDialog;
|
class BandwidthDialog;
|
||||||
class LodToolsDialog;
|
class LodToolsDialog;
|
||||||
class MetavoxelEditor;
|
class MetavoxelEditor;
|
||||||
|
class ChatWindow;
|
||||||
class OctreeStatsDialog;
|
class OctreeStatsDialog;
|
||||||
class MenuItemProperties;
|
class MenuItemProperties;
|
||||||
|
|
||||||
|
@ -140,6 +143,7 @@ private slots:
|
||||||
void cycleFrustumRenderMode();
|
void cycleFrustumRenderMode();
|
||||||
void runTests();
|
void runTests();
|
||||||
void showMetavoxelEditor();
|
void showMetavoxelEditor();
|
||||||
|
void showChat();
|
||||||
void audioMuteToggled();
|
void audioMuteToggled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -187,6 +191,7 @@ private:
|
||||||
FrustumDrawMode _frustumDrawMode;
|
FrustumDrawMode _frustumDrawMode;
|
||||||
ViewFrustumOffset _viewFrustumOffset;
|
ViewFrustumOffset _viewFrustumOffset;
|
||||||
QPointer<MetavoxelEditor> _MetavoxelEditor;
|
QPointer<MetavoxelEditor> _MetavoxelEditor;
|
||||||
|
QPointer<ChatWindow> _chatWindow;
|
||||||
OctreeStatsDialog* _octreeStatsDialog;
|
OctreeStatsDialog* _octreeStatsDialog;
|
||||||
LodToolsDialog* _lodToolsDialog;
|
LodToolsDialog* _lodToolsDialog;
|
||||||
int _maxVoxels;
|
int _maxVoxels;
|
||||||
|
@ -252,6 +257,7 @@ namespace MenuOption {
|
||||||
const QString Logout = "Logout";
|
const QString Logout = "Logout";
|
||||||
const QString LookAtVectors = "Look-at Vectors";
|
const QString LookAtVectors = "Look-at Vectors";
|
||||||
const QString MetavoxelEditor = "Metavoxel Editor...";
|
const QString MetavoxelEditor = "Metavoxel Editor...";
|
||||||
|
const QString Chat = "Chat...";
|
||||||
const QString Metavoxels = "Metavoxels";
|
const QString Metavoxels = "Metavoxels";
|
||||||
const QString Mirror = "Mirror";
|
const QString Mirror = "Mirror";
|
||||||
const QString MoveWithLean = "Move with Lean";
|
const QString MoveWithLean = "Move with Lean";
|
||||||
|
|
129
interface/src/ui/ChatWindow.cpp
Normal file
129
interface/src/ui/ChatWindow.cpp
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QLayoutItem>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QSizePolicy>
|
||||||
|
#include <QTextDocument>
|
||||||
|
|
||||||
|
#include "ChatWindow.h"
|
||||||
|
#include "ui_chatwindow.h"
|
||||||
|
#include "FlowLayout.h"
|
||||||
|
|
||||||
|
#include <QXmppClient.h>
|
||||||
|
#include <QXmppMessage.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <AccountManager.h>
|
||||||
|
|
||||||
|
const QString DEFAULT_SERVER = "chat.highfidelity.io";
|
||||||
|
const QString DEFAULT_CHAT_ROOM = "public@public-chat.highfidelity.io";
|
||||||
|
|
||||||
|
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)");
|
||||||
|
|
||||||
|
ChatWindow::ChatWindow() :
|
||||||
|
QDialog(Application::getInstance()->getGLWidget(), Qt::Tool),
|
||||||
|
ui(new Ui::ChatWindow) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
FlowLayout* flowLayout = new FlowLayout();
|
||||||
|
flowLayout->setContentsMargins(0, 8, 0, 8);
|
||||||
|
ui->usersWidget->setLayout(flowLayout);
|
||||||
|
|
||||||
|
ui->messagePlainTextEdit->installEventFilter(this);
|
||||||
|
|
||||||
|
ui->numOnlineLabel->hide();
|
||||||
|
ui->usersWidget->hide();
|
||||||
|
ui->messagesScrollArea->hide();
|
||||||
|
ui->messagePlainTextEdit->hide();
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
_xmppClient.addExtension(&_xmppMUCManager);
|
||||||
|
connect(&_xmppClient, SIGNAL(connected()), this, SLOT(connected()));
|
||||||
|
connect(&_xmppClient, SIGNAL(error(QXmppClient::Error)), this, SLOT(error(QXmppClient::Error)));
|
||||||
|
connect(&_xmppClient, SIGNAL(messageReceived(QXmppMessage)), this, SLOT(messageReceived(QXmppMessage)));
|
||||||
|
|
||||||
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
QString user = accountManager.getUsername();
|
||||||
|
const QString& password = accountManager.getXMPPPassword();
|
||||||
|
_xmppClient.connectToServer(user + "@" + DEFAULT_SERVER, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatWindow::~ChatWindow() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatWindow::eventFilter(QObject* sender, QEvent* event) {
|
||||||
|
Q_UNUSED(sender);
|
||||||
|
|
||||||
|
if (event->type() != QEvent::KeyPress) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) &&
|
||||||
|
(keyEvent->modifiers() & Qt::ShiftModifier) == 0) {
|
||||||
|
_xmppClient.sendMessage(_chatRoom->jid(), ui->messagePlainTextEdit->document()->toPlainText());
|
||||||
|
ui->messagePlainTextEdit->document()->clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChatWindow::getParticipantName(const QString& participant) {
|
||||||
|
return participant.right(participant.count() - 1 - _chatRoom->jid().count());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::connected() {
|
||||||
|
_chatRoom = _xmppMUCManager.addRoom(DEFAULT_CHAT_ROOM);
|
||||||
|
connect(_chatRoom, SIGNAL(participantsChanged()), this, SLOT(participantsChanged()));
|
||||||
|
_chatRoom->setNickName(AccountManager::getInstance().getUsername());
|
||||||
|
_chatRoom->join();
|
||||||
|
|
||||||
|
ui->connectingToXMPPLabel->hide();
|
||||||
|
ui->numOnlineLabel->show();
|
||||||
|
ui->usersWidget->show();
|
||||||
|
ui->messagesScrollArea->show();
|
||||||
|
ui->messagePlainTextEdit->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::error(QXmppClient::Error error) {
|
||||||
|
ui->connectingToXMPPLabel->setText(QString::number(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::participantsChanged() {
|
||||||
|
QStringList participants = _chatRoom->participants();
|
||||||
|
ui->numOnlineLabel->setText(tr("%1 online now:").arg(participants.count()));
|
||||||
|
|
||||||
|
while (QLayoutItem* item = ui->usersWidget->layout()->takeAt(0)) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
foreach (const QString& participant, participants) {
|
||||||
|
QLabel* userLabel = new QLabel(getParticipantName(participant));
|
||||||
|
userLabel->setStyleSheet(
|
||||||
|
"background-color: palette(light);"
|
||||||
|
"border-radius: 5px;"
|
||||||
|
"color: #267077;"
|
||||||
|
"padding: 2px;"
|
||||||
|
"border: 1px solid palette(shadow);"
|
||||||
|
"font-weight: bold");
|
||||||
|
ui->usersWidget->layout()->addWidget(userLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::messageReceived(const QXmppMessage& message) {
|
||||||
|
QLabel* userLabel = new QLabel(getParticipantName(message.from()));
|
||||||
|
QFont font = userLabel->font();
|
||||||
|
font.setBold(true);
|
||||||
|
userLabel->setFont(font);
|
||||||
|
userLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QLabel* messageLabel = new QLabel(message.body().replace(regexLinks, "<a href=\"\\1\">\\1</a>"));
|
||||||
|
messageLabel->setWordWrap(true);
|
||||||
|
messageLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||||
|
messageLabel->setOpenExternalLinks(true);
|
||||||
|
|
||||||
|
ui->messagesFormLayout->addRow(userLabel, messageLabel);
|
||||||
|
ui->messagesFormLayout->parentWidget()->updateGeometry();
|
||||||
|
Application::processEvents();
|
||||||
|
QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar();
|
||||||
|
verticalScrollBar->setSliderPosition(verticalScrollBar->maximum());
|
||||||
|
}
|
40
interface/src/ui/ChatWindow.h
Normal file
40
interface/src/ui/ChatWindow.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef __interface__ChatWindow__
|
||||||
|
#define __interface__ChatWindow__
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
|
||||||
|
#include <QXmppClient.h>
|
||||||
|
#include <QXmppMucManager.h>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ChatWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatWindow : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ChatWindow();
|
||||||
|
~ChatWindow();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject* sender, QEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ChatWindow* ui;
|
||||||
|
QXmppClient _xmppClient;
|
||||||
|
QXmppMucManager _xmppMUCManager;
|
||||||
|
QXmppMucRoom* _chatRoom;
|
||||||
|
|
||||||
|
QString getParticipantName(const QString& participant);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void connected();
|
||||||
|
void error(QXmppClient::Error error);
|
||||||
|
void participantsChanged();
|
||||||
|
void messageReceived(const QXmppMessage& message);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__interface__ChatWindow__) */
|
213
interface/src/ui/FlowLayout.cpp
Normal file
213
interface/src/ui/FlowLayout.cpp
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the examples of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** 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 COPYRIGHT
|
||||||
|
** OWNER 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_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtWidgets>
|
||||||
|
|
||||||
|
#include "flowlayout.h"
|
||||||
|
//! [1]
|
||||||
|
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||||
|
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||||
|
{
|
||||||
|
setContentsMargins(margin, margin, margin, margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||||
|
: m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||||
|
{
|
||||||
|
setContentsMargins(margin, margin, margin, margin);
|
||||||
|
}
|
||||||
|
//! [1]
|
||||||
|
|
||||||
|
//! [2]
|
||||||
|
FlowLayout::~FlowLayout()
|
||||||
|
{
|
||||||
|
QLayoutItem *item;
|
||||||
|
while ((item = takeAt(0)))
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
//! [2]
|
||||||
|
|
||||||
|
//! [3]
|
||||||
|
void FlowLayout::addItem(QLayoutItem *item)
|
||||||
|
{
|
||||||
|
itemList.append(item);
|
||||||
|
}
|
||||||
|
//! [3]
|
||||||
|
|
||||||
|
//! [4]
|
||||||
|
int FlowLayout::horizontalSpacing() const
|
||||||
|
{
|
||||||
|
if (m_hSpace >= 0) {
|
||||||
|
return m_hSpace;
|
||||||
|
} else {
|
||||||
|
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int FlowLayout::verticalSpacing() const
|
||||||
|
{
|
||||||
|
if (m_vSpace >= 0) {
|
||||||
|
return m_vSpace;
|
||||||
|
} else {
|
||||||
|
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//! [4]
|
||||||
|
|
||||||
|
//! [5]
|
||||||
|
int FlowLayout::count() const
|
||||||
|
{
|
||||||
|
return itemList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QLayoutItem *FlowLayout::itemAt(int index) const
|
||||||
|
{
|
||||||
|
return itemList.value(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
QLayoutItem *FlowLayout::takeAt(int index)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < itemList.size())
|
||||||
|
return itemList.takeAt(index);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//! [5]
|
||||||
|
|
||||||
|
//! [6]
|
||||||
|
Qt::Orientations FlowLayout::expandingDirections() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//! [6]
|
||||||
|
|
||||||
|
//! [7]
|
||||||
|
bool FlowLayout::hasHeightForWidth() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FlowLayout::heightForWidth(int width) const
|
||||||
|
{
|
||||||
|
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
//! [7]
|
||||||
|
|
||||||
|
//! [8]
|
||||||
|
void FlowLayout::setGeometry(const QRect &rect)
|
||||||
|
{
|
||||||
|
QLayout::setGeometry(rect);
|
||||||
|
doLayout(rect, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize FlowLayout::sizeHint() const
|
||||||
|
{
|
||||||
|
return minimumSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize FlowLayout::minimumSize() const
|
||||||
|
{
|
||||||
|
QSize size;
|
||||||
|
QLayoutItem *item;
|
||||||
|
foreach (item, itemList)
|
||||||
|
size = size.expandedTo(item->minimumSize());
|
||||||
|
|
||||||
|
size += QSize(2*margin(), 2*margin());
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
//! [8]
|
||||||
|
|
||||||
|
//! [9]
|
||||||
|
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
|
||||||
|
{
|
||||||
|
int left, top, right, bottom;
|
||||||
|
getContentsMargins(&left, &top, &right, &bottom);
|
||||||
|
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||||
|
int x = effectiveRect.x();
|
||||||
|
int y = effectiveRect.y();
|
||||||
|
int lineHeight = 0;
|
||||||
|
//! [9]
|
||||||
|
|
||||||
|
//! [10]
|
||||||
|
QLayoutItem *item;
|
||||||
|
foreach (item, itemList) {
|
||||||
|
QWidget *wid = item->widget();
|
||||||
|
int spaceX = horizontalSpacing();
|
||||||
|
if (spaceX == -1)
|
||||||
|
spaceX = wid->style()->layoutSpacing(
|
||||||
|
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||||
|
int spaceY = verticalSpacing();
|
||||||
|
if (spaceY == -1)
|
||||||
|
spaceY = wid->style()->layoutSpacing(
|
||||||
|
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||||
|
//! [10]
|
||||||
|
//! [11]
|
||||||
|
int nextX = x + item->sizeHint().width() + spaceX;
|
||||||
|
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||||
|
x = effectiveRect.x();
|
||||||
|
y = y + lineHeight + spaceY;
|
||||||
|
nextX = x + item->sizeHint().width() + spaceX;
|
||||||
|
lineHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!testOnly)
|
||||||
|
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||||
|
|
||||||
|
x = nextX;
|
||||||
|
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||||
|
}
|
||||||
|
return y + lineHeight - rect.y() + bottom;
|
||||||
|
}
|
||||||
|
//! [11]
|
||||||
|
//! [12]
|
||||||
|
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
|
||||||
|
{
|
||||||
|
QObject *parent = this->parent();
|
||||||
|
if (!parent) {
|
||||||
|
return -1;
|
||||||
|
} else if (parent->isWidgetType()) {
|
||||||
|
QWidget *pw = static_cast<QWidget *>(parent);
|
||||||
|
return pw->style()->pixelMetric(pm, 0, pw);
|
||||||
|
} else {
|
||||||
|
return static_cast<QLayout *>(parent)->spacing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//! [12]
|
78
interface/src/ui/FlowLayout.h
Normal file
78
interface/src/ui/FlowLayout.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the examples of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** 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 COPYRIGHT
|
||||||
|
** OWNER 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_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FLOWLAYOUT_H
|
||||||
|
#define FLOWLAYOUT_H
|
||||||
|
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QRect>
|
||||||
|
#include <QStyle>
|
||||||
|
//! [0]
|
||||||
|
class FlowLayout : public QLayout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||||
|
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||||
|
~FlowLayout();
|
||||||
|
|
||||||
|
void addItem(QLayoutItem *item);
|
||||||
|
int horizontalSpacing() const;
|
||||||
|
int verticalSpacing() const;
|
||||||
|
Qt::Orientations expandingDirections() const;
|
||||||
|
bool hasHeightForWidth() const;
|
||||||
|
int heightForWidth(int) const;
|
||||||
|
int count() const;
|
||||||
|
QLayoutItem *itemAt(int index) const;
|
||||||
|
QSize minimumSize() const;
|
||||||
|
void setGeometry(const QRect &rect);
|
||||||
|
QSize sizeHint() const;
|
||||||
|
QLayoutItem *takeAt(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int doLayout(const QRect &rect, bool testOnly) const;
|
||||||
|
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||||
|
|
||||||
|
QList<QLayoutItem *> itemList;
|
||||||
|
int m_hSpace;
|
||||||
|
int m_vSpace;
|
||||||
|
};
|
||||||
|
//! [0]
|
||||||
|
|
||||||
|
#endif // FLOWLAYOUT_H
|
125
interface/ui/chatWindow.ui
Normal file
125
interface/ui/chatWindow.ui
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ChatWindow</class>
|
||||||
|
<widget class="QDialog" name="ChatWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>608</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Chat</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="connectingToXMPPLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Connecting to XMPP...</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="numOnlineLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font-weight: bold; color: palette(shadow)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string> online now:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="usersWidget" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="messagesScrollArea">
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>382</width>
|
||||||
|
<height>356</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="messagesFormLayout">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalSpacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="messagePlainTextEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>messagePlainTextEdit</tabstop>
|
||||||
|
<tabstop>messagesScrollArea</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -52,6 +52,8 @@ public:
|
||||||
void requestAccessToken(const QString& login, const QString& password);
|
void requestAccessToken(const QString& login, const QString& password);
|
||||||
|
|
||||||
QString getUsername() const { return _accountInfo.getUsername(); }
|
QString getUsername() const { return _accountInfo.getUsername(); }
|
||||||
|
|
||||||
|
const QString& getXMPPPassword() const { return _accountInfo.getXMPPPassword(); }
|
||||||
|
|
||||||
void destroy() { delete _networkAccessManager; }
|
void destroy() { delete _networkAccessManager; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue