Доделал Мессенджер

This commit is contained in:
krivoshein
2024-12-24 12:23:22 +03:00
parent 30ad6330a4
commit bf7b0ac741
45 changed files with 784 additions and 464 deletions

View File

@@ -88,6 +88,8 @@ add_library(InstructorsAndTrainees SHARED
messanger/msgwidget.cpp
messanger/msgwidget.h
messanger/msgwidget.ui
messanger/tabdialogmessenger.cpp
messanger/tabdialogmessenger.h
resources.qrc
)

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.11.1, 2024-12-20T16:19:37. -->
<!-- Written by QtCreator 4.11.1, 2024-12-24T12:21:21. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@@ -4,14 +4,14 @@
#include <QAbstractScrollArea>
#include <QMessageBox>
#include <QLabel>
#include <QScrollBar>
#include "messangerwidget.h"
#include "ui_messangerwidget.h"
#include "msgwidget.h"
MessangerWidget::MessangerWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MessangerWidget)
ui(new Ui::MessangerWidget),
currLogin("")
{
ui->setupUi(this);
@@ -26,23 +26,24 @@ MessangerWidget::~MessangerWidget()
delete ui;
}
void MessangerWidget::addMsg(Trainee trainee, QString text, MessangerWidget::ETypeMsg typeMsg)
void MessangerWidget::addMsgFromClient(Trainee trainee, QString text)
{
//Пробуем добавить вкладку диалога с клиентом (если вдруг еще нет)
addTabDialogMessenger(trainee);
QString prefix = (typeMsg == MessangerWidget::ETypeMsg::fromClient)? ">> " : "<< ";
//Ищем нужный диалог
foreach(TabDialogMessenger dialogMsg, listTabDialogMessenger)
{
if(dialogMsg.getLogin() == trainee.getLogin())
QString login = trainee.getLogin();
foreach(TabDialogMessenger* tabDialog, listTabDialogMessenger)
{//Есть такой
if(tabDialog->getLogin() == login)
{
//Добавляем в существующую вкладку
ui->tabWidget->setCurrentIndex(dialogMsg.getIndexTab());
ui->tabWidget->setCurrentIndex(getIndexTab(login));
tabDialog->addMsgWidgetRemote(text);
//Делаем ее текущей
ui->tabWidget->setCurrentIndex(getIndexTab(login));
dialogMsg.addMsgWidgetRemote(text);
currLogin = trainee.getLogin();
currLogin = login;
return;
}
}
@@ -51,36 +52,82 @@ void MessangerWidget::addMsg(Trainee trainee, QString text, MessangerWidget::ETy
void MessangerWidget::addTabDialogMessenger(Trainee trainee)
{
if(listTabDialogMessenger.count() == 0)
{
{//Самая первая вкладка, делаем ее активной
currLogin = trainee.getLogin();
emit signal_tabMessengerChanged(currLogin);
}
//Проверяем наличие диалога с этим клиентом
foreach(TabDialogMessenger dialogMsg, listTabDialogMessenger)
foreach(TabDialogMessenger* dialogMsg, listTabDialogMessenger)
{
if(dialogMsg.getLogin() == trainee.getLogin())
if(dialogMsg->getLogin() == trainee.getLogin())
{//Диалог для этого клиента уже существует
//Обновляем статус залогинивания
if(trainee.getLoggedIn())
ui->tabWidget->setTabIcon(getIndexTab(trainee.getLogin()), QIcon(":/icons/circleGreen.png"));
else
ui->tabWidget->setTabIcon(getIndexTab(trainee.getLogin()), QIcon(":/icons/circleGray.png"));
return;
}
}
}
//Диалога для этого клиента еще не существует
//Помещаем новый диалог в список диалогов
TabDialogMessenger* tabDialog = new TabDialogMessenger(0 /*TODO доделать передачу реального ID*/, trainee.getLogin(), this);
listTabDialogMessenger.append(tabDialog);
//Добавляем новую вкладку диалога
QListWidget* listWidget = new QListWidget();
listWidget->setWordWrap(true);
listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
int index = ui->tabWidget->addTab(listWidget, /*login + ": " +*/ trainee.getName());
int index = ui->tabWidget->addTab(tabDialog, /*login + ": " +*/ trainee.getName());
//Обновляем статус залогинивания
if(trainee.getLoggedIn())
ui->tabWidget->setTabIcon(index, QIcon(":/icons/circleGreen.png"));
else
ui->tabWidget->setTabIcon(index, QIcon(":/icons/circleGray.png"));
}
//Помещаем новый диалог в список диалогов
TabDialogMessenger dialogMsg(index, listWidget, trainee.getLogin());
listTabDialogMessenger.append(dialogMsg);
void MessangerWidget::actualizationTabsDialogMessenger()
{
foreach(TabDialogMessenger* tabDialog, listTabDialogMessenger)
{
QString login = tabDialog->getLogin();
bool exist = false;
for(Trainee trainee : listTrainees)
{
if(trainee.getLogin() == login)
{
if(trainee.getArchived())
{//Стал архивным
//Удаляем диалог с клиентом
ui->tabWidget->removeTab(getIndexTab(login));
listTabDialogMessenger.removeOne(tabDialog);
}
else
exist = true;
break;
}
}
if(!exist)
{//Нет такого логина
//Удаляем диалог с клиентом
ui->tabWidget->removeTab(getIndexTab(login));
listTabDialogMessenger.removeOne(tabDialog);
}
}
}
int MessangerWidget::getIndexTab(QString login)
{
for(int index = 0; index < ui->tabWidget->count(); index++)
{
TabDialogMessenger* tabDialogMessenger = static_cast<TabDialogMessenger*>(ui->tabWidget->widget(index));
if(tabDialogMessenger->getLogin() == login)
return index;
}
return -1;
}
void MessangerWidget::on_btnSend_clicked()
@@ -91,17 +138,15 @@ void MessangerWidget::on_btnSend_clicked()
ui->editMsg->clear();
QString prefix = "<< ";
//Ищем нужный диалог
foreach(TabDialogMessenger dialogMsg, listTabDialogMessenger)
foreach(TabDialogMessenger* tabDialog, listTabDialogMessenger)
{
if(dialogMsg.getLogin() == currLogin)
if(tabDialog->getLogin() == currLogin)
{
//Добавляем в существующую вкладку
ui->tabWidget->setCurrentIndex(dialogMsg.getIndexTab());
dialogMsg.addMsgWidgetLocal(text);
tabDialog->addMsgWidgetLocal(text);
//Делаем ее активной
ui->tabWidget->setCurrentIndex(getIndexTab(currLogin));
return;
}
@@ -111,11 +156,11 @@ void MessangerWidget::on_btnSend_clicked()
void MessangerWidget::on_tabWidget_currentChanged(int index)
{
//Ищем нужный диалог
foreach(TabDialogMessenger dialogMsg, listTabDialogMessenger)
foreach(TabDialogMessenger* tabDialog, listTabDialogMessenger)
{
if(dialogMsg.getIndexTab() == index)
if(getIndexTab(tabDialog->getLogin()) == index)
{
currLogin = dialogMsg.getLogin();
currLogin = tabDialog->getLogin();
emit signal_tabMessengerChanged(currLogin);
return;
}
@@ -125,12 +170,12 @@ void MessangerWidget::on_tabWidget_currentChanged(int index)
void MessangerWidget::slot_traineeSelected(QString login)
{
//Ищем нужный диалог
foreach(TabDialogMessenger dialogMsg, listTabDialogMessenger)
foreach(TabDialogMessenger* tabDialog, listTabDialogMessenger)
{
if(dialogMsg.getLogin() == login)
if(tabDialog->getLogin() == login)
{
//Активируем нужную вкладку
ui->tabWidget->setCurrentIndex(dialogMsg.getIndexTab());
ui->tabWidget->setCurrentIndex(getIndexTab(login));
return;
}
}
@@ -146,10 +191,12 @@ void MessangerWidget::slot_InitMessanger(QList<Trainee> listTrainees)
{
this->listTrainees = listTrainees;
actualizationTabsDialogMessenger();
for(Trainee trainee: listTrainees)
{
if(! trainee.getArchived())
this->addTabDialogMessenger(trainee);
addTabDialogMessenger(trainee);
}
}
@@ -158,7 +205,7 @@ void MessangerWidget::slot_msgFromClientReady(QString login, QString text)
for(Trainee trainee: listTrainees)
{
if(trainee.getLogin() == login)
addMsg(trainee, text, MessangerWidget::ETypeMsg::fromClient);
addMsgFromClient(trainee, text);
}
}
@@ -178,38 +225,3 @@ void MessangerWidget::changeEvent(QEvent *event)
ui->retranslateUi(this); // переведём окно заново
}
}
void TabDialogMessenger::addMsgWidgetLocal(QString text)
{
QListWidgetItem *listWidgetItem = new QListWidgetItem();
QString avatar = ":/icons/instructor.png";
MsgWidget *msgWidget = new MsgWidget(avatar, MsgWidget::AligneAvatar::Left,
listWidget->width() - listWidget->verticalScrollBar()->size().width());
listWidget->addItem(listWidgetItem);
listWidget->setItemWidget(listWidgetItem, msgWidget);
msgWidget->setText(text);
listWidgetItem->setSizeHint (QSize(10, msgWidget->height()));
listWidget->scrollToItem(listWidgetItem);
}
void TabDialogMessenger::addMsgWidgetRemote(QString text)
{
QListWidgetItem *listWidgetItem = new QListWidgetItem();
QString avatar = ":/icons/trainee.png";
MsgWidget *msgWidget = new MsgWidget(avatar, MsgWidget::AligneAvatar::Right,
listWidget->width() - listWidget->verticalScrollBar()->size().width());
listWidget->addItem(listWidgetItem);
listWidget->setItemWidget(listWidgetItem, msgWidget);
msgWidget->setText(text);
listWidgetItem->setSizeHint (QSize(10, msgWidget->height()));
listWidget->scrollToItem(listWidgetItem);
}

View File

@@ -2,38 +2,18 @@
#define MESSANGERWIDGET_H
#include <QWidget>
#include <QListWidget>
#include <QTranslator>
#include <trainee.h>
#include "Datas.h"
#include "tabdialogmessenger.h"
class TabDialogMessenger
{
public:
TabDialogMessenger();
TabDialogMessenger(int indexTab, QListWidget* listWidget, QString login)
{
this->indexTab = indexTab;
this->listWidget = listWidget;
this->login = login;
};
QString getLogin() {return login;};
int getIndexTab() {return indexTab;};
void addMsgWidgetLocal(QString text);
void addMsgWidgetRemote(QString text);
private:
QString login = "";
int indexTab = 0;
QListWidget* listWidget = nullptr;
};
namespace Ui {
class MessangerWidget;
}
//Главный виджет мессенджера
class MessangerWidget : public QWidget
{
Q_OBJECT
@@ -50,8 +30,12 @@ protected:
public:
enum ETypeMsg{fromClient, toClient};
void addMsg(Trainee trainee, QString text, ETypeMsg typeMsg);
void addMsgFromClient(Trainee trainee, QString text);
void addTabDialogMessenger(Trainee trainee);
void actualizationTabsDialogMessenger();
int getIndexTab(QString login);
private slots:
void on_btnSend_clicked();
@@ -60,7 +44,7 @@ private slots:
signals:
//сигнал о готовности нового сообщения на отправку клиенту
void signal_msgToClientReady(QString login, QString text);
//сигнал об изменении вкладки диалога (TabDialogMessenger)
//сигнал об изменении вкладки диалога с клиентом (TabDialogMessenger)
void signal_tabMessengerChanged(QString login);
public slots:
@@ -76,11 +60,11 @@ public slots:
private:
virtual void keyPressEvent(QKeyEvent *event) override;
private:
QList <TabDialogMessenger> listTabDialogMessenger;
QList<Trainee> listTrainees;
QString currLogin = "";
private:
Ui::MessangerWidget *ui;
QList <TabDialogMessenger*> listTabDialogMessenger;
QList<Trainee> listTrainees;
QString currLogin; //Логин клиента текущего диалога
QTranslator qtLanguageTranslator;
};

View File

@@ -1,6 +1,5 @@
#include "msgwidget.h"
#include "ui_msgwidget.h"
#include <QSizePolicy>
MsgWidget::MsgWidget(QString avatar, AligneAvatar aligneAvatar, int width, QWidget *parent) :
QWidget(parent),
@@ -72,19 +71,22 @@ void MsgWidget::on_textEdit_textChanged()
{
QString text = ui->textEdit->toPlainText();
QFontMetrics metricsFont(ui->textEdit->font()); //метрики шрифта
QRect textRect = metricsFont.boundingRect(QRect(0, 0, 0, 0), 0, text); //геометрические параметры текста (высота/ширина в пикселях)
//геометрические параметры текста (высота/ширина в пикселях). В одну строку
QRect textRect = metricsFont.boundingRect(QRect(0, 0, 0, 0), 0, text);
int X = 10; // отступы
if(textRect.width() > widthEdit)
{
{//Не помещается в одну строку
textRect = metricsFont.boundingRect(QRect(0, 0, widthEdit, 10), Qt::TextWordWrap, text);
ui->textEdit->setFixedHeight(textRect.height()+X);
this->setFixedHeight(textRect.height()+X + 20);
ui->textEdit->setFixedHeight(textRect.height() + X);
this->setFixedHeight(textRect.height() + X + 20);
}
else
{
ui->textEdit->setFixedWidth(textRect.width()+X);
ui->textEdit->setFixedHeight(textRect.height()+X);
this->setFixedHeight(textRect.height()+X + 20);
{//В одну строку
ui->textEdit->setFixedWidth(textRect.width() + X);
ui->textEdit->setFixedHeight(textRect.height() + X);
this->setFixedHeight(textRect.height() + X + 20);
}
}

View File

@@ -7,6 +7,8 @@ namespace Ui {
class MsgWidget;
}
//Виджет одного сообщения для/от клиента
class MsgWidget : public QWidget
{
Q_OBJECT

View File

@@ -0,0 +1,57 @@
#include <QScrollBar>
#include "tabdialogmessenger.h"
#include "msgwidget.h"
TabDialogMessenger::TabDialogMessenger(int id, QString login, QWidget *parent):
QListWidget(parent),
login(""),
id(0)
{
this->id = id;
this->login = login;
setWordWrap(true);
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
}
TabDialogMessenger::~TabDialogMessenger()
{
}
void TabDialogMessenger::addMsgWidgetLocal(QString text)
{
QListWidgetItem *listWidgetItem = new QListWidgetItem();
QString avatar = ":/icons/instructor.png";
MsgWidget *msgWidget = new MsgWidget(avatar, MsgWidget::AligneAvatar::Left,
width() - verticalScrollBar()->size().width());
addItem(listWidgetItem);
setItemWidget(listWidgetItem, msgWidget);
msgWidget->setText(text);
//Корректировка высоты item
listWidgetItem->setSizeHint (QSize(10, msgWidget->height()));
scrollToItem(listWidgetItem);
}
void TabDialogMessenger::addMsgWidgetRemote(QString text)
{
QListWidgetItem *listWidgetItem = new QListWidgetItem();
QString avatar = ":/icons/trainee.png";
MsgWidget *msgWidget = new MsgWidget(avatar, MsgWidget::AligneAvatar::Right,
width() - verticalScrollBar()->size().width());
addItem(listWidgetItem);
setItemWidget(listWidgetItem, msgWidget);
msgWidget->setText(text);
//Корректировка высоты item
listWidgetItem->setSizeHint (QSize(10, msgWidget->height()));
scrollToItem(listWidgetItem);
}

View File

@@ -0,0 +1,29 @@
#ifndef TABDIALOGMESSENGER_H
#define TABDIALOGMESSENGER_H
#include <QListWidget>
//Закладка ведения диалога с одним клиентом
//TODO сделать идентификацию по ID
class TabDialogMessenger : public QListWidget
{
Q_OBJECT
public:
TabDialogMessenger(int id, QString login, QWidget *parent = nullptr);
~TabDialogMessenger();
QString getLogin() {return login;};
int getID() {return id;};
void addMsgWidgetLocal(QString text);
void addMsgWidgetRemote(QString text);
private:
QString login;
int id;
};
#endif // TABDIALOGMESSENGER_H

View File

@@ -43,6 +43,8 @@ void ViewerTrainees::slot_tabMessengerChanged(QString login)
if(loginChild == login)
{
treeWidget->setCurrentItem(treeWidget->topLevelItem(i)->child(j));
typeObject = TypeObject::objTrainee;
lastCurrentID = connectorToServer->getIdTraineeByLogin(login);
Q_EMIT signal_traineeSelected(login);
return;
}