1414#include < QTimer>
1515#include < QFileInfo>
1616
17- QString get_data_string (QTcpSocket* socket)
17+ QByteArray get_data_string (QTcpSocket* socket)
1818{
1919 int deadEndCounter = 0 ;
20- QString output = " " ;
20+ QByteArray output;
2121
2222 while (deadEndCounter < 4096 )
2323 {
2424 QByteArray data = socket->read (1 );
2525 char c = reinterpret_cast <char >(data[0 ]);
2626 if (c == ' \n ' ) break ;
2727
28- output += c ;
28+ output += data[ 0 ] ;
2929
3030 deadEndCounter++;
3131 }
@@ -49,10 +49,10 @@ QString formatByteSpeed(qint64 bytes)
4949 qint64 megaSize = 1047576 ;
5050 qint64 kilaSize = 1024 ;
5151
52- if (bytes > terraSize) {speed = bytes / terraSize; byteIndex = 4 ;}
53- else if (bytes > gigaSize) {speed = bytes / gigaSize; byteIndex = 3 ;}
54- else if (bytes > megaSize) {speed = bytes / megaSize; byteIndex = 2 ;}
55- else if (bytes > kilaSize) {speed = bytes / kilaSize; byteIndex = 1 ;}
52+ if (bytes > terraSize) {speed = ( double ) bytes / ( double ) terraSize; byteIndex = 4 ;}
53+ else if (bytes > gigaSize) {speed = ( double ) bytes / ( double ) gigaSize; byteIndex = 3 ;}
54+ else if (bytes > megaSize) {speed = ( double ) bytes / ( double ) megaSize; byteIndex = 2 ;}
55+ else if (bytes > kilaSize) {speed = ( double ) bytes / ( double ) kilaSize; byteIndex = 1 ;}
5656
5757 return QString::number (speed, ' f' , 2 ) + " " + byteFormats[byteIndex];
5858}
@@ -64,6 +64,10 @@ MainWindow::MainWindow(QWidget *parent)
6464 ui->setupUi (this );
6565 ui->RemoveFileButton ->setVisible (false );
6666 socket = new QTcpSocket (this );
67+ connect (ui->MessageInput , &QLineEdit::returnPressed, ui->sendButton , &QPushButton::click);
68+ connect (ui->PairIDInput , &QLineEdit::returnPressed, ui->pairButton , &QPushButton::click);
69+ ui->MessageList ->setWordWrap (true ); // allow wrapping
70+ ui->MessageList ->setResizeMode (QListView::Adjust); // items adjust width
6771
6872 updateTimer = new QTimer (this );
6973 connect (updateTimer, &QTimer::timeout, this , [this ]() {
@@ -94,7 +98,7 @@ MainWindow::MainWindow(QWidget *parent)
9498 }
9599 case 1 :{
96100 QJsonParseError parseError;
97- QJsonDocument doc = QJsonDocument::fromJson (get_data_string (socket). toUtf8 () , &parseError);
101+ QJsonDocument doc = QJsonDocument::fromJson (get_data_string (socket), &parseError);
98102
99103 if (parseError.error != QJsonParseError::NoError)
100104 {
@@ -189,6 +193,7 @@ MainWindow::MainWindow(QWidget *parent)
189193 newMessage->setText (obj[" message" ].toString ());
190194
191195 item->setSizeHint (newMessage->sizeHint ());
196+
192197 ui->MessageList ->addItem (item);
193198 ui->MessageList ->setItemWidget (item, newMessage);
194199 }
@@ -315,6 +320,8 @@ MainWindow::MainWindow(QWidget *parent)
315320
316321 ui->MessageList ->clear ();
317322
323+ sendingFile= false ;
324+
318325 if (current_file) {
319326 if (current_file->isOpen ())
320327 current_file->close ();
@@ -417,74 +424,94 @@ void MainWindow::sendFile()
417424{
418425 QFileInfo info (selectedFilePath);
419426
427+ // 1. Send metadata first
420428 QJsonObject jsonMessage;
421429 jsonMessage[" type" ] = " file_metadata" ;
422430 jsonMessage[" file_name" ] = info.fileName ();
423431 jsonMessage[" file_size" ] = info.size ();
424432 jsonMessage[" to" ] = pairPartnerId;
425433
426434 QJsonDocument doc (jsonMessage);
427- QString jsonString = doc.toJson (QJsonDocument::Compact) + " \n " ;
435+ QString jsonString = doc.toJson (QJsonDocument::Compact) + ' \n ' ;
428436 socket->write (jsonString.toUtf8 ());
429437
438+ // 2. Setup state
430439 current_file_size = 0 ;
431440 current_total_file_size = info.size ();
432441
433442 QListWidgetItem *item = new QListWidgetItem (ui->MessageList );
434443 currentFileMessage = new fileMessage;
435-
436444 currentFileMessage->setFileName (info.fileName ());
437445 currentFileMessage->setToAndFromClient (QString::number (myId), QString::number (pairPartnerId));
438- currentFileMessage->setStatus (" Transfering " );
446+ currentFileMessage->setStatus (" Transferring " );
439447 currentFileMessage->setProgress (0 );
440448
441449 item->setSizeHint (currentFileMessage->sizeHint ());
442450 ui->MessageList ->addItem (item);
443451 ui->MessageList ->setItemWidget (item, currentFileMessage);
444452
445- current_file = new QFile;
446- current_file->setFileName (selectedFilePath);
447-
453+ current_file = new QFile (selectedFilePath);
448454 if (!current_file->open (QIODevice::ReadOnly)) {
449- QMessageBox::warning (this , " Error" , " Could not open file for writing!" );
455+ QMessageBox::warning (this , " Error" , " Could not open file for reading!" );
456+ delete current_file;
457+ current_file = nullptr ;
450458 return ;
451459 }
452460
453461 updateTimer->start (1000 );
462+ sendingFile = true ;
454463
455- while (!current_file-> atEnd ()) {
456- QByteArray bytes = current_file-> read ( 1024 );
457- current_file_size += bytes. size ( );
464+ // 3. Connect socket signal → chunk sender
465+ uploadConn = connect (socket, &QTcpSocket::bytesWritten,
466+ this , &MainWindow::sendFileChunk );
458467
459- qint64 written = socket->write (bytes);
460- if (written == -1 ) {
461- QMessageBox::warning (this , " Error" , " Failed to write to socket!" );
462- break ;
463- }
468+ // 4. Kick off first chunk immediately
469+ sendFileChunk ();
470+ }
464471
465- // Block until the OS actually flushes this chunk
466- if (!socket->waitForBytesWritten (-1 )) {
467- QMessageBox::warning (this , " Error" , " Failed to send data chunk!" );
468- break ;
469- }
472+ void MainWindow::sendFileChunk ()
473+ {
474+ if (!sendingFile || !current_file) return ;
470475
471- double progress = (double )current_file_size / (double )current_total_file_size * 100.0 ;
472- static int lastProgress = -1 ;
473- int intProgress = static_cast <int >(progress);
476+ const int chunkSize = 1024 ;
477+ QByteArray bytes = current_file->read (chunkSize);
474478
475- if (intProgress != lastProgress) {
476- currentFileMessage->setProgress (intProgress);
477- lastProgress = intProgress;
478- }
479- }
480-
481- updateTimer->stop ();
479+ if (bytes.isEmpty ()) {
480+ // === Finished ===
481+ sendingFile = false ;
482+ updateTimer->stop ();
482483
483- if (current_file) {
484484 if (current_file->isOpen ())
485485 current_file->close ();
486486 delete current_file;
487487 current_file = nullptr ;
488+
489+ // Disconnect so no future writes trigger us
490+ disconnect (uploadConn);
491+
492+ currentFileMessage->setStatus (" File Transferred" );
493+ currentFileMessage->setProgress (100 );
494+ return ;
495+ }
496+
497+ // Write chunk
498+ qint64 written = socket->write (bytes);
499+ if (written == -1 ) {
500+ QMessageBox::warning (this , " Error" , " Failed to write to socket!" );
501+ return ;
502+ }
503+
504+ current_file_size += bytes.size ();
505+ bytesReceivedThisSecond += bytes.size ();
506+
507+ // Update progress
508+ double progress = (double )current_file_size / (double )current_total_file_size * 100.0 ;
509+ static int lastProgress = -1 ;
510+ int intProgress = static_cast <int >(progress);
511+
512+ if (intProgress != lastProgress) {
513+ currentFileMessage->setProgress (intProgress);
514+ lastProgress = intProgress;
488515 }
489516}
490517
@@ -496,7 +523,7 @@ void MainWindow::sendMessage(const QString messageToSend)
496523 jsonMessage[" to" ] = pairPartnerId;
497524
498525 QJsonDocument doc (jsonMessage);
499- QString jsonString = doc.toJson (QJsonDocument::Compact) + " \n " ;
526+ QString jsonString = doc.toJson (QJsonDocument::Compact) + ' \n ' ;
500527 socket->write (jsonString.toUtf8 ());
501528
502529 QListWidgetItem *item = new QListWidgetItem (ui->MessageList );
0 commit comments