TCPClient/mainwidget.cpp

471 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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(thistr("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();
}