471 lines
16 KiB
C++
471 lines
16 KiB
C++
#include "mainwidget.h"
|
||
#include "ui_mainwidget.h"
|
||
|
||
MainWidget::MainWidget(QString username,QWidget *parent) :
|
||
QWidget(parent),
|
||
ui(new Ui::MainWidget)
|
||
{
|
||
ui->setupUi(this);
|
||
this->setFixedSize(this->width(), this->height());
|
||
this->setWindowIcon(QIcon(":/icon.png"));
|
||
this->setWindowTitle(QString("TCP聊天室:%1").arg(username));
|
||
this->setAttribute(Qt::WA_StyledBackground);
|
||
|
||
ui->name_list->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允许编辑
|
||
//ui->name_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||
ui->name_list->verticalScrollBar()->setStyleSheet("QScrollBar{width:16px;}");
|
||
|
||
ui->textEdit->setReadOnly(true);
|
||
ui->textEdit->setFocusPolicy(Qt::NoFocus);
|
||
//防止QTextBrowser中的内容被重定向
|
||
ui->textEdit->setOpenLinks(false);
|
||
ui->textEdit->setOpenExternalLinks(false);
|
||
connect(ui->textEdit, &QTextBrowser::anchorClicked, this, [=](const QUrl &link)
|
||
{
|
||
auto path = link.path();
|
||
path.remove(0, 1);
|
||
qDebug() << path;
|
||
QFileInfo info(path);
|
||
if(info.isDir())
|
||
QDesktopServices::openUrl(link);
|
||
else if(info.isFile())
|
||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||
});
|
||
|
||
ui->send_btn->setFocus();
|
||
ui->send_btn->setDefault(true);
|
||
|
||
ui->send_text->setMouseTracking(true);
|
||
ui->send_text->setToolTip(QStringLiteral("发送文件"));
|
||
ui->stop->setMouseTracking(true);
|
||
ui->stop->setToolTip(QStringLiteral("注销用户"));
|
||
ui->exit_btn->setMouseTracking(true);
|
||
ui->exit_btn->setToolTip(QStringLiteral("退出登录"));
|
||
ui->save_btn->setMouseTracking(true);
|
||
ui->save_btn->setToolTip(QStringLiteral("保存聊天记录"));
|
||
|
||
ui->msg_edit->installEventFilter(this);//设置完后自动调用其eventFilter函数
|
||
this->username = username;
|
||
}
|
||
|
||
MainWidget::~MainWidget()
|
||
{
|
||
delete ui;
|
||
}
|
||
|
||
void MainWidget::on_send_text_clicked()
|
||
{
|
||
zoom_down(ui->send_text);
|
||
zoom_up(ui->send_text);
|
||
QString homePath = QDir::homePath();
|
||
QString filePath = QFileDialog::getOpenFileName(this, tr("Open a file"), homePath, tr("All files (*.*)"), NULL, QFileDialog::DontResolveSymlinks);
|
||
|
||
QString filename = filePath.section("/", -1);
|
||
|
||
if (filename.isEmpty())
|
||
return;
|
||
|
||
QMessageBox::StandardButton reply;
|
||
reply = QMessageBox::question(this, "发送文件", tr("Do you want to send \"%1\"?").arg(filename));
|
||
|
||
if (reply == QMessageBox::No)
|
||
return;
|
||
else
|
||
{
|
||
QString text = ui->msg_edit->text();
|
||
if(text.isEmpty()) //群发
|
||
{
|
||
QString currentTime = QTime::currentTime().toString("H:mm A");
|
||
QString html = "<a href=\"file:///" + filePath + "\">" + filename + "</a>";
|
||
qDebug() << html;
|
||
ui->textEdit->append("<p><font color=\"MediumBlue\"><b>" + username + " [" + currentTime + "] send a file \"" + html + "\"</b></font></p>");
|
||
this->sendFile(filePath,filename);
|
||
}
|
||
else //私发文件
|
||
{
|
||
ui->msg_edit->clear();
|
||
int n = text.indexOf(' ');
|
||
QString name = text.mid(1,n-1);
|
||
if(username == name)
|
||
{
|
||
QMessageBox::critical(this,"错误","不能自己给自己发送文件!");
|
||
return;
|
||
}
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < ui->name_list->count(); i++)
|
||
{
|
||
if(name != ui->name_list->item(index)->text())
|
||
index++;
|
||
}
|
||
if(index >= ui->name_list->count())
|
||
{
|
||
QMessageBox::critical(this,"错误","未找到指定用户!");
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
QString currentTime = QTime::currentTime().toString("H:mm A");
|
||
QString html = "<a href=\"file:///" + filePath + "\">" + filename + "</a>";
|
||
qDebug() << html;
|
||
ui->textEdit->append("<p><font color=\"MediumBlue\"><b>" + username + " [" + currentTime + "] send " + name + " a private file \"" + html + "\"</b></font><p>");
|
||
this->sendFile(filePath,filename,name);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void MainWidget::on_save_btn_clicked()
|
||
{
|
||
zoom_down(ui->save_btn);
|
||
zoom_up(ui->save_btn);
|
||
QFile file("./ChatRecord/memory.txt");
|
||
if (file.exists()) //文件存在
|
||
{
|
||
QMessageBox::StandardButton reply;
|
||
reply = QMessageBox::question(this, "提示", tr("是否覆盖之前的聊天记录?"));
|
||
if (reply == QMessageBox::No)
|
||
{
|
||
if (file.open(QIODevice::WriteOnly | QIODevice::Append))
|
||
{
|
||
QTextStream stream(&file);
|
||
//转换为字符串
|
||
QString str = ui->textEdit->toPlainText();
|
||
QString date = QDate::currentDate().toString("yyyy-MM-dd ");
|
||
QString currentTime = QTime::currentTime().toString("H:mm A\n");
|
||
str = "\n\n" + date + currentTime + str;
|
||
//加入时间戳并写入
|
||
stream << str;
|
||
//关闭文件
|
||
file.close();
|
||
QMessageBox::information(this,"保存聊天记录","保存成功!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||
{
|
||
QTextStream stream(&file);
|
||
//转换为字符串
|
||
QString str = ui->textEdit->toPlainText();
|
||
QString date = QDate::currentDate().toString("yyyy-MM-dd ");
|
||
QString currentTime = QTime::currentTime().toString("H:mm A\n");
|
||
str = date + currentTime + str + "\n";
|
||
stream << str;
|
||
//关闭文件
|
||
file.close();
|
||
QMessageBox::information(this,"保存聊天记录","保存成功!");
|
||
}
|
||
}
|
||
}
|
||
|
||
else
|
||
{
|
||
QMessageBox::warning(this, "提示", tr("聊天记录文件不存在,已为您自动创建文件!"));
|
||
file.open(QIODevice::WriteOnly | QIODevice::Append);
|
||
}
|
||
}
|
||
|
||
void MainWidget::on_send_btn_clicked()
|
||
{
|
||
zoom_down(ui->send_btn);
|
||
zoom_up(ui->send_btn);
|
||
QString text;
|
||
text = ui->msg_edit->text();
|
||
if(text.isEmpty())
|
||
{
|
||
QMessageBox::warning(this, "发送失败", "输入不能为空!");
|
||
return;
|
||
}
|
||
ui->msg_edit->clear();
|
||
|
||
if(text[0] == '@')
|
||
{
|
||
int n = text.indexOf(' ');
|
||
QString to_user = text.mid(1,n-1);
|
||
QString insert = "tell you quietly:";
|
||
QString data_text = insert + text.mid(n,-1);
|
||
QString text_self = QString("私发给%1:%2").arg(to_user).arg(text.mid(n));
|
||
qDebug() << text_self;
|
||
if(username == to_user)
|
||
{
|
||
QMessageBox::critical(this,"错误","不能自己给自己发送文件!");
|
||
return;
|
||
}
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < ui->name_list->count(); i++)
|
||
{
|
||
if(to_user != ui->name_list->item(index)->text())
|
||
index++;
|
||
}
|
||
if(index >= ui->name_list->count())
|
||
{
|
||
QMessageBox::critical(this,"错误","未找到指定用户!");
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
ui->textEdit->append("<p><font color=\"MediumBlue\"><b>" + username + " [" + currentTime + "] </b> " + text_self + "</font></p>");
|
||
emit send_to_user(username,to_user,data_text);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
ui->textEdit->append("<p><font color=\"MediumBlue\"><b>" + username + " [" + currentTime + "] :</b> " + text + "</font></p>");
|
||
emit send_text(username,text);
|
||
}
|
||
}
|
||
|
||
|
||
void MainWidget::on_name_list_itemDoubleClicked(QListWidgetItem *item)
|
||
{
|
||
QString client_name = ui->name_list->currentItem()->text();
|
||
QString a = "@";
|
||
a = a + client_name + " ";
|
||
ui->msg_edit->clear();
|
||
ui->msg_edit->setText(a);
|
||
}
|
||
|
||
|
||
void MainWidget::on_exit_btn_clicked()
|
||
{
|
||
zoom_down(ui->exit_btn);
|
||
zoom_up(ui->exit_btn);
|
||
QMessageBox::StandardButton response;
|
||
response = QMessageBox::question(this, "退出", tr("是否退出软件?"));
|
||
|
||
if(response == QMessageBox::Yes)
|
||
{
|
||
//emit exit_client();
|
||
//emit update_namelist(username);
|
||
this->close();
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
void MainWidget::on_stop_clicked()
|
||
{
|
||
zoom_down(ui->stop);
|
||
zoom_up(ui->stop);
|
||
QMessageBox::StandardButton response;
|
||
response = QMessageBox::question(this, "注销", tr("是否退出软件并注销账户?"));
|
||
|
||
if(response == QMessageBox::Yes)
|
||
{
|
||
qDebug() << "点击注销账户按钮";
|
||
//emit exit_client();
|
||
emit account_cancellation(username);
|
||
this->close();
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
void MainWidget::update_text(QString sendname,QString data)
|
||
{
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
ui->textEdit->append("<p>" + sendname + " [" + currentTime + "] : " + data + "</p>");
|
||
qDebug() << sendname + " [" + currentTime + "] : " + data;
|
||
}
|
||
|
||
void MainWidget::update_file(QString sendname,QString filename,QString file_data)
|
||
{
|
||
readFile(filename,QByteArray::fromHex(file_data.toUtf8()));
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
QString html = "<a href=\"file:///./Document/" + filename + "\">" + filename + "</a>";
|
||
QString msg = "<p>" + username + " [" + currentTime + "] : " + QString("收到了一个来自%1的群发文件:").arg(sendname) + html + "</p>";
|
||
ui->textEdit->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
|
||
void MainWidget::update_file_private(QString sendname,QString filename,QString file_data)
|
||
{
|
||
readFile(filename,QByteArray::fromHex(file_data.toUtf8()));
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
QString html = "<a href=\"file:///./Document/" + filename + "\">" + filename + "</a>";
|
||
QString msg = "<p>" + username + " [" + currentTime + "] : " + QString("收到了一个来自%1的私发文件:").arg(sendname) + html + "</p>";
|
||
ui->textEdit->append(msg);
|
||
qDebug() << msg;
|
||
}
|
||
/*
|
||
void MainWidget::update_file(QString sendname,QString filename,QString file_data)
|
||
{
|
||
QMessageBox::StandardButton response;
|
||
QString content = QString("你收到了一个来自%1的群发文件%2,是否接收?").arg(sendname).arg(filename);
|
||
response = QMessageBox::question(this,"提示",content);
|
||
if(response == QMessageBox::Yes)
|
||
{
|
||
readFile(filename,file_data.toUtf8());
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
ui->textEdit->append(QString(username + " [" + currentTime + "] : "
|
||
+ "收到了一个来自%1的群发文件%2").arg(sendname).arg(filename));
|
||
}
|
||
else
|
||
{
|
||
QMessageBox::information(this,"接收文件","未接收该文件!");
|
||
}
|
||
}
|
||
|
||
void MainWidget::update_file_private(QString sendname,QString filename,QString file_data)
|
||
{
|
||
QMessageBox::StandardButton response;
|
||
QString content = QString("你收到了%1私发给你的文件%2,是否接收?").arg(sendname).arg(filename);
|
||
response = QMessageBox::question(this,"提示",content);
|
||
if(response == QMessageBox::Yes)
|
||
{
|
||
readFile(filename,file_data.toUtf8());
|
||
QString currentTime = QTime::currentTime().toString("H:m A");
|
||
ui->textEdit->append(QString(username + " [" + currentTime + "] :"
|
||
+ "收到了一个来自%1的私发文件%2").arg(sendname).arg(filename));
|
||
}
|
||
else
|
||
{
|
||
QMessageBox::information(this,"消息","未接收该文件!");
|
||
}
|
||
}
|
||
*/
|
||
void MainWidget::update_users(int count,QList<QString>online_users)
|
||
{
|
||
ui->name_list->clear();
|
||
QList<QString>::iterator it = online_users.begin();
|
||
for(; it!=online_users.end(); ++it)
|
||
{
|
||
ui->name_list->addItem(*it);
|
||
}
|
||
for(int i=0;i<ui->name_list->count();i++)
|
||
{
|
||
ui->name_list->item(i)->setIcon(QIcon(":/user_label.png"));
|
||
}
|
||
|
||
}
|
||
|
||
void MainWidget::disconnect_form_server()
|
||
{
|
||
QMessageBox::critical(this,"连接超时","请检查您的网络连接!");
|
||
}
|
||
void MainWidget::sendFile(QString filePath,QString filename,QString name)
|
||
{
|
||
//发送的数据存入block中
|
||
QByteArray block;
|
||
QFile file(filePath);
|
||
//打开文件,定义错误提醒
|
||
if(!file.open(QIODevice::ReadOnly)){
|
||
QMessageBox::warning(this,"错误","无法打开文件!");
|
||
return;
|
||
}
|
||
|
||
/*打开文件流,以写的方式打开
|
||
QDataStream out(&block,QIODevice::WriteOnly);
|
||
out.setVersion(QDataStream::Qt_5_8);*/
|
||
|
||
//将数据读取到QByteArray
|
||
QByteArray dataOfFile = file.readAll();
|
||
//关闭文件
|
||
file.close();
|
||
|
||
if(name.isEmpty()) //群发文件
|
||
{
|
||
emit send_file_to_all(username,filename,dataOfFile);
|
||
}
|
||
|
||
else //私发文件
|
||
{
|
||
emit send_file_private(username,filename,dataOfFile,name);
|
||
}
|
||
QProgressDialog *progressDlg = new QProgressDialog(this);
|
||
progressDlg->setWindowModality(Qt::WindowModal);
|
||
progressDlg->setMinimumDuration(0);
|
||
progressDlg->setAttribute(Qt::WA_DeleteOnClose, true);
|
||
progressDlg->setWindowTitle(tr("上传文件"));
|
||
progressDlg->setLabelText(tr("正在上传......"));
|
||
progressDlg->setCancelButtonText(tr("取消"));
|
||
progressDlg->setRange(0, 12000);
|
||
for (int i = 1; i < 12000; i++)
|
||
{
|
||
progressDlg->setValue(i);
|
||
if (progressDlg->wasCanceled())
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
progressDlg->close();
|
||
QMessageBox::information(this,"发送文件","发送成功!");
|
||
}
|
||
|
||
void MainWidget::readFile(QString filename,QByteArray data)
|
||
{
|
||
/*QString homePath = QDir::homePath();
|
||
QString filePath = QFileDialog::getExistingDirectory(this,tr("Open Directory"),homePath,
|
||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);*/
|
||
QString filepath = "./Document";
|
||
QDir dir(filepath);
|
||
if(dir.exists())
|
||
{
|
||
QFile outFile(filepath + "/" +filename);
|
||
if(!outFile.open(QIODevice::WriteOnly)){
|
||
QMessageBox::warning(this,"错误","接收文件出错!");
|
||
return;
|
||
}
|
||
outFile.write(data);
|
||
outFile.close();
|
||
}
|
||
else
|
||
{
|
||
dir.mkdir(filepath);
|
||
QFile outFile(filepath + "/" +filename);
|
||
if(!outFile.open(QIODevice::WriteOnly)){
|
||
QMessageBox::warning(this,"错误","接收文件出错!");
|
||
return;
|
||
}
|
||
outFile.write(data);
|
||
outFile.close();
|
||
}
|
||
}
|
||
|
||
bool MainWidget::eventFilter(QObject *target, QEvent *event)
|
||
{
|
||
if(target == ui->msg_edit) //可替换
|
||
{
|
||
if(event->type() == QEvent::KeyPress)//回车键
|
||
{
|
||
QKeyEvent *k = static_cast<QKeyEvent *>(event);
|
||
|
||
if(k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)
|
||
{
|
||
on_send_btn_clicked(); //替换为需要响应的函数事件,以这里的按钮为例
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return QWidget::eventFilter(target,event);
|
||
}
|
||
|
||
void MainWidget::zoom_down(QPushButton* btn)
|
||
{
|
||
QPropertyAnimation *animalton = new QPropertyAnimation(btn,"geometry");
|
||
animalton->setDuration(150);
|
||
animalton->setStartValue(QRect(btn->x(),btn->y(),btn->width(),btn->height()));
|
||
animalton->setEndValue(QRect(btn->x(),btn->y()+5,btn->width(),btn->height()));
|
||
animalton->setEasingCurve(QEasingCurve::OutBounce);
|
||
animalton->start();
|
||
|
||
}
|
||
|
||
void MainWidget::zoom_up(QPushButton* btn)
|
||
{
|
||
QPropertyAnimation *animalton = new QPropertyAnimation(btn,"geometry");
|
||
animalton->setDuration(150);
|
||
animalton->setStartValue(QRect(btn->x(),btn->y()+5,btn->width(),btn->height()));
|
||
animalton->setEndValue(QRect(btn->x(),btn->y(),btn->width(),btn->height()));
|
||
animalton->setEasingCurve(QEasingCurve::OutBounce);
|
||
animalton->start();
|
||
}
|