Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

8 семестр / Готовая курсовая работа / ММиВА. Курсовая работа

.pdf
Скачиваний:
31
Добавлен:
09.03.2022
Размер:
2.04 Mб
Скачать

464

{

465

ImapSettings new_imap_settings = new_settings_dialog.get_imap_settings();

466

SmtpSettings new_smtp_settings = new_settings_dialog.get_smtp_settings();

467

imap_settings = new_imap_settings;

468

smtp_settings = new_smtp_settings;

469}

470}

471catch (const std::exception &exc)

472{

473QMessageBox::critical(this, "Ошибка", exc.what());

474}

475}

476

477void MainWindow::on_exit_program_triggered()

478{

479std::lock_guard<std::mutex> main_lock(main_mutex);

480try

481{

482if (QMessageBox::question(this, "Внимание", "Вы уверены, что хотите выйти?", QMessageBox::Yes | QMessageBox::No,

483

QMessageBox::No) == QMessageBox::Yes)

484

{

485

clear_all();

486

exit(0);

487}

488}

489catch (const std::exception &exc)

490{

491QMessageBox::critical(this, "Ошибка", exc.what());

492}

493}

494

495void MainWindow::on_add_folder_triggered()

496{

497std::lock_guard<std::mutex> main_lock(main_mutex);

498try

499{

500std::list<std::string> folder_name_decoded;

501QTreeWidgetItem *current = ui->folders_tree->currentItem();

502while (current)

503{

504

folder_name_decoded.emplace_front(current->text(0).toStdString());

505

current = current->parent();

506}

507std::string folder_name_s;

508for (auto s : folder_name_decoded)

509{

510

folder_name_s += "\\" + s;

511}

512folder_name_decoded.clear();

513bool ok = false;

514std::string update_message;

515QString text = QInputDialog::getText(this, "Создание новой папки", "Название папки:", QLineEdit::Normal,

516

QString::fromStdString(folder_name_s),

 

&ok);

517if (ok && !text.isEmpty())

518{

519

std::list<std::string> new_folder_name;

520

std::string new_folder_name_s;

521

for (auto s : text.split('\\'))

522

{

523

if (!s.isEmpty())

524

{

525

new_folder_name.emplace_back(utf7encode(s).toStdString());

526

new_folder_name_s += "\\" + s.toStdString();

527

}

528

}

529

try

530

{

61

531

std::chrono::system_clock::time_point start =

 

std::chrono::system_clock::now();

532

mailio::imaps conn(imap_settings.get_server_address(),

533

 

 

static_cast<unsigned>(imap_settings.get_server_port()), timeout);

534

conn.authenticate(imap_settings.get_login(),

 

imap_settings.get_password(),

535

imap_settings.get_auth_method());

536

ok = conn.create_folder(new_folder_name);

537

if (!ok)

538

{

539

throw mailio::imap_error("отказано в операции сервером");

540

}

541

std::chrono::duration<double> sec = std::chrono::system_clock::now() -

 

start;

542

update_message = "Папка " + new_folder_name_s + " добавлена (" +

 

std::to_string(sec.count()) + " сек.)";

543

}

544

catch (const std::exception &exc)

545

{

546

update_message = "Папка " + new_folder_name_s + " не добавлена: " +

 

std::string(exc.what());

547

}

548

}

549

else

550

{

551

update_message = "Папка не добавлена: отмена операции";

552}

553std::string current_datetime_s = get_current_datetime_as_string();

554QString log_message = QString::fromStdString(current_datetime_s + ". " + update_message);

555ui->status_bar->showMessage(log_message);

556ui->logs_text_edit->appendPlainText(log_message);

557if (ok)

558{

559

main_mutex.unlock();

560

on_update_folders_and_messages_triggered();

561}

562}

563catch (const std::exception &exc)

564{

565QMessageBox::critical(this, "Ошибка", exc.what());

566}

567}

568

569void MainWindow::on_rename_folder_triggered()

570{

571std::lock_guard<std::mutex> main_lock(main_mutex);

572try

573{

574if (ui->folders_tree->currentItem() == nullptr)

575{

576

QMessageBox::warning(this, "Внимание", "Папка не выбрана");

577

return;

578}

579std::list<std::string> old_folder_name, old_folder_name_decoded;

580QTreeWidgetItem *current = ui->folders_tree->currentItem();

581while (current)

582{

583

old_folder_name_decoded.emplace_front(current->text(0).toStdString());

584

old_folder_name.emplace_front(current->text(3).toStdString());

585

current = current->parent();

586}

587std::string old_folder_name_s;

588for (auto s : old_folder_name_decoded)

589{

590

old_folder_name_s += "\\" + s;

591}

592bool ok = false;

593std::string update_message;

594QString text =

62

595

QInputDialog::getText(this, "Переименование/перемещение папки", "Новое

 

название папки:", QLineEdit::Normal,

596

QString::fromStdString(old_folder_name_s), &ok);

597if (ok && !text.isEmpty())

598{

599

try

600

{

601

std::chrono::system_clock::time_point start =

 

std::chrono::system_clock::now();

602

mailio::imaps conn(imap_settings.get_server_address(),

603

 

 

static_cast<unsigned>(imap_settings.get_server_port()), timeout);

604

conn.authenticate(imap_settings.get_login(),

 

imap_settings.get_password(),

605

imap_settings.get_auth_method());

606

std::list<std::string> new_folder_name;

607

std::string new_folder_name_s;

608

for (auto s : text.split('\\'))

609

{

610

if (!s.isEmpty())

611

{

612

new_folder_name.emplace_back(utf7encode(s).toStdString());

613

new_folder_name_s += "\\" + s.toStdString();

614

}

615

}

616

ok = conn.rename_folder(old_folder_name, new_folder_name);

617

if (!ok)

618

{

619

throw mailio::imap_error("отказано в операции сервером");

620

}

621

std::chrono::duration<double> sec = std::chrono::system_clock::now() -

 

start;

622

update_message = "Папка " + old_folder_name_s + " переименована -> " +

 

new_folder_name_s + " (" +

623

std::to_string(sec.count()) + " сек.)";

624

}

625

catch (const std::exception &exc)

626

{

627

update_message = "Папка " + old_folder_name_s + " не переименована: "

 

+ std::string(exc.what());

628

}

629}

630else

631{

632

update_message = "Папка " + old_folder_name_s + " не переименована: отмена

 

операции";

633}

634std::string current_datetime_s = get_current_datetime_as_string();

635QString log_message = QString::fromStdString(current_datetime_s + ". " + update_message);

636ui->status_bar->showMessage(log_message);

637ui->logs_text_edit->appendPlainText(log_message);

638if (ok)

639{

640

main_mutex.unlock();

641

on_update_folders_and_messages_triggered();

642}

643}

644catch (const std::exception &exc)

645{

646QMessageBox::critical(this, "Ошибка", exc.what());

647}

648}

649

650void MainWindow::on_delete_selected_folder_triggered()

651{

652std::lock_guard<std::mutex> main_lock(main_mutex);

653try

654{

655std::list<std::string> folder_name, folder_name_decoded;

656std::string folder_name_s;

63

64

657QTreeWidgetItem *current = ui->folders_tree->currentItem();

658while (current)

659{

660

folder_name_decoded.emplace_front(current->text(0).toStdString());

661

folder_name.emplace_front(current->text(3).toStdString());

662

current = current->parent();

663}

664for (auto s : folder_name_decoded)

665{

666

folder_name_s += "\\" + s;

667};

668std::string update_message;

669bool ok = (QMessageBox::question(

670

this, "Внимание",

671

QString::fromStdString("Вы уверены, что хотите удалить папку "

 

+ folder_name_s + "?"),

672

QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ==

 

QMessageBox::Yes);

673if (ok)

674{

675

try

676

{

677

std::chrono::system_clock::time_point start =

 

std::chrono::system_clock::now();

678

mailio::imaps conn(imap_settings.get_server_address(),

679

 

 

static_cast<unsigned>(imap_settings.get_server_port()), timeout);

680

conn.authenticate(imap_settings.get_login(),

 

imap_settings.get_password(),

681

imap_settings.get_auth_method());

682

ok = conn.delete_folder(folder_name);

683

if (!ok)

684

{

685

throw mailio::imap_error("отказано в операции сервером");

686

}

687

std::chrono::duration<double> sec = std::chrono::system_clock::now() -

 

start;

688

update_message = "Папка " + folder_name_s + " удалена (" +

 

std::to_string(sec.count()) + " сек.)";

689

}

690

catch (const std::exception &exc)

691

{

692

update_message = "Папка " + folder_name_s + " не удалена: " +

 

std::string(exc.what());

693

}

694

}

695

else

696

{

697

update_message = "Папка " + folder_name_s + " не удалена: отмена

 

операции";

698}

699std::string current_datetime_s = get_current_datetime_as_string();

700QString log_message = QString::fromStdString(current_datetime_s + ". " + update_message);

701ui->status_bar->showMessage(log_message);

702ui->logs_text_edit->appendPlainText(log_message);

703if (ok)

704{

705

main_mutex.unlock();

706

on_update_folders_and_messages_triggered();

707}

708}

709catch (const std::exception &exc)

710{

711QMessageBox::critical(this, "Ошибка", exc.what());

712}

713}

714

715void MainWindow::on_send_message_triggered()

716{

717std::lock_guard<std::mutex> main_lock(main_mutex);

718try

719{

720mailio::smtps conn(smtp_settings.get_server_address(), smtp_settings.get_server_port());

721conn.authenticate(smtp_settings.get_login(), smtp_settings.get_password(), smtp_settings.get_auth_method());

722}

723catch (const std::exception &exc)

724{

725QMessageBox::critical(this, "Ошибка", exc.what());

726return;

727}

728SendMessageDialog new_send_message_dialog;

729try

730{

731while (new_send_message_dialog.exec() == QDialog::Accepted)

732{

733

try

734

{

735

mailio::message message = new_send_message_dialog.get_message();

736

if (message.subject().empty())

737

{

738

QMessageBox::warning(this, "Ошибка", "Тема сообщения пуста");

739

continue;

740

}

741

if (message.recipients().empty() && message.cc_recipients().empty() &&

 

message.bcc_recipients().empty())

742

{

743

QMessageBox::warning(this, "Ошибка", "Получатели отсутствуют");

744

continue;

745

}

746

message.from(mailio::mail_address(smtp_settings.get_name(),

 

smtp_settings.get_login()));

747

mailio::smtps conn(smtp_settings.get_server_address(),

 

smtp_settings.get_server_port());

748

conn.authenticate(smtp_settings.get_login(),

 

smtp_settings.get_password(),

749

smtp_settings.get_auth_method());

750

std::string status = conn.submit(message);

751

std::string update_message = "Сообщение отправлено, обновите "

752

"список папок с сообщениями";

753

std::string current_datetime_s = get_current_datetime_as_string();

754

QString log_message = QString::fromStdString(current_datetime_s + ". "

 

+ update_message);

755

ui->status_bar->showMessage(log_message);

756

ui->logs_text_edit->appendPlainText(log_message);

757

QMessageBox::information(this, "Информация",

758

"Сообщение отправлено\nОбновите список папок

 

"

759

"с сообщениями\n\nОтвет сервера:\n" +

760

QString::fromStdString(status));

761

break;

762

}

763

catch (const std::exception &exc)

764

{

765

QMessageBox::warning(this, "Ошибка", exc.what());

766

}

767}

768}

769catch (const std::exception &exc)

770{

771QMessageBox::critical(this, "Ошибка", exc.what());

772}

773}

774

775void MainWindow::on_download_attachment_triggered()

776{

777std::lock_guard<std::mutex> main_lock(main_mutex);

778try

779{

780QTableWidgetItem *current_item = ui->messages_table->currentItem();

65

781if (current_item == nullptr)

782{

783

QMessageBox::warning(this, "Внимание", "Сообщение не выбрано");

784

return;

785}

786std::string current_message_id =

787

ui->messages_table->item(ui->messages_table->currentRow(), 7)-

 

>text().toStdString();

788if (messages.find(current_message_id) == messages.end())

789{

790

QMessageBox::warning(this, "Внимание", "Сообщение не найдено");

791

return;

792}

793mailio::message current_message = messages[current_message_id];

794size_t n_attachments = current_message.attachments_size();

795if (n_attachments <= 0)

796{

797

QMessageBox::warning(this, "Внимание", "Вложения в сообщении не найдены");

798

return;

799}

800QStringList attachment_names, attachment_names_and_sizes;

801std::vector<std::shared_ptr<std::stringstream>> attachments_data_streams;

802constexpr unsigned long long kb = 1 << 10, mb = kb << 10, gb = mb << 10;

803for (size_t i = 1; i <= n_attachments; ++i)

804{

805

std::string attachment_name, attachment_size;

806

std::shared_ptr<std::stringstream> ss =

 

std::make_shared<std::stringstream>();

807

std::istream &is = *ss;

808

std::ostream &os = *ss;

809

current_message.attachment(i, os, attachment_name);

810

is.seekg(0, std::ios::end);

811

unsigned long long size = is.tellg();

812

is.seekg(0, std::ios::beg);

813

if (size >= gb)

814

{

815

size = size * 100 / gb;

816

attachment_size = std::to_string(size / 100) + "." +

 

std::to_string(size % 100) + " ГиБ";

817

}

818

else if (size >= mb)

819

{

820

size = size * 100 / mb;

821

attachment_size = std::to_string(size / 100) + "." +

 

std::to_string(size % 100) + " МиБ";

822

}

823

else if (size >= kb)

824

{

825

size = size * 100 / kb;

826

attachment_size = std::to_string(size / 100) + "." +

 

std::to_string(size % 100) + " КиБ";

827

}

828

else

829

{

830

attachment_size = std::to_string(size) + " Б";

831

}

832

attachment_names.emplace_back(QString::fromStdString(attachment_name));

833

attachment_names_and_sizes.emplace_back(

834

QString::fromStdString(attachment_name + " (" + attachment_size +

 

")"));

835

attachments_data_streams.emplace_back(ss);

836}

837bool ok = false;

838std::string update_message;

839QString filename_with_size = QInputDialog::getItem(this, "Внимание", "Какое

 

вложение вы хотите скачать?",

840

attachment_names_and_sizes,

 

0, false, &ok);

841if (ok)

842{

843

size_t p = 0;

66

844

if ((p = attachment_names_and_sizes.indexOf(filename_with_size)) < 0)

845

{

846

QMessageBox::warning(this, "Внимание", "Вложение не найдено");

847

return;

848

}

849

QString new_filename = QInputDialog::getText(this, "Внимание", "Введите

 

путь и/или имя файла для записи",

850

QLineEdit::Normal,

 

attachment_names[p], &ok);

851

if (ok)

852

{

853

try

854

{

855

std::ofstream file_out(new_filename.toStdWString().c_str(),

 

std::ios::out | std::ios::binary);

856

file_out << ((std::istream

 

&)*attachments_data_streams[p]).rdbuf();

857

file_out.close();

858

update_message = "Файл " + new_filename.toStdString() + "

 

записан";

859

}

860

catch (const std::exception &exc)

861

{

862

update_message = "Ошибка записи файла на диск: " +

 

std::string(exc.what());

863

}

864

}

865

else

866

{

867

update_message = "Сохранение файла отменено";

868

}

869}

870else

871{

872

update_message = "Сохранение файла отменено";

873}

874std::string current_datetime_s = get_current_datetime_as_string();

875QString log_message = QString::fromStdString(current_datetime_s + ". " + update_message);

876ui->status_bar->showMessage(log_message);

877ui->logs_text_edit->appendPlainText(log_message);

878}

879catch (const std::exception &exc)

880{

881QMessageBox::critical(this, "Ошибка", exc.what());

882}

883}

884

885void MainWindow::on_copy_selected_message_triggered()

886{

887std::lock_guard<std::mutex> main_lock(main_mutex);

888try

889{

890QItemSelectionModel *select = ui->messages_table->selectionModel();

891if (!select->hasSelection())

892{

893

QMessageBox::warning(this, "Внимание", "Сообщения не выбраны");

894

return;

895}

896QList<QString> folders;

897for (auto folder : mailboxes_to_messages_ids)

898{

899

QString folder_to_emplace;

900

for (auto s : folder.first)

901

{

902

folder_to_emplace += "\\" + utf7decode(QString::fromStdString(s));

903

}

904

folders.emplace_back(folder_to_emplace);

905}

906bool ok = false;

907QString text =

67

908

QInputDialog::getItem(this, "Копирование сообщений в папку", "Название

 

папки:", folders, 0, false, &ok);

909if (!ok || text.isEmpty())

910{

911

return;

912}

913std::list<std::string> destination_folder_name;

914for (auto s : text.split('\\'))

915{

916

if (!s.isEmpty())

917

{

918

destination_folder_name.emplace_back(utf7encode(s).toStdString());

919

}

920}

921try

922{

923

std::string update_message;

924

QModelIndexList selection = select->selectedIndexes();

925

if (selection.count() == 0)

926

{

927

QMessageBox::warning(this, "Внимание", "Сообщения не выбраны");

928

return;

929

}

930

std::unordered_set<int> rows;

931

for (qsizetype i = 0; i < selection.count(); i++)

932

{

933

rows.insert(selection.at(i).row());

934

}

935

std::chrono::system_clock::time_point start =

 

std::chrono::system_clock::now();

936

mailio::imaps conn(imap_settings.get_server_address(),

937

static_cast<unsigned>(imap_settings.get_server_port()),

 

timeout);

938

conn.authenticate(imap_settings.get_login(), imap_settings.get_password(),

 

imap_settings.get_auth_method());

939

for (auto row : rows)

940

{

941

QTableWidgetItem *current_uid = ui->messages_table->item(row, 6);

942

if (current_uid == nullptr || current_uid->text().isEmpty())

943

{

944

QMessageBox::warning(this, "Внимание", "UID одного сообщения не

 

найден");

945

continue;

946

}

947

ok = false;

948

unsigned long uid = current_uid->text().toULong(&ok);

949

if (!ok)

950

{

951

QMessageBox::warning(this, "Внимание", "Неверный UID у одного

 

сообщения");

952

continue;

953

}

954

QTableWidgetItem *current_message_id = ui->messages_table->item(row,

 

7);

955

if (current_message_id == nullptr || current_message_id-

 

>text().isEmpty())

956

{

957

QMessageBox::warning(this, "Внимание", "Message ID одного

 

сообщения не найден");

958

continue;

959

}

960

std::string current_message_id_s = current_message_id-

 

>text().toStdString();

961

std::string datetime_s = ui->messages_table->item(row, 2)-

 

>text().toStdString();

962

try

963

{

964

conn.append(destination_folder_name, this-

 

>messages[current_message_id_s]);

965

std::chrono::duration<double> sec =

 

std::chrono::system_clock::now() - start;

68

966

update_message = "Сообщение #" + std::to_string(uid) + " (" +

 

datetime_s + ") скопировано (" +

967

std::to_string(sec.count()) + " сек.)";

968

}

969

catch (const std::exception &exc)

970

{

971

update_message = "Сообщение #" + std::to_string(uid) + " (" +

 

datetime_s +

972

") не скопировано: " + std::string(exc.what());

973

}

974

std::string current_datetime_s = get_current_datetime_as_string();

975

QString log_message = QString::fromStdString(current_datetime_s + ". "

 

+ update_message);

976

ui->status_bar->showMessage(log_message);

977

ui->logs_text_edit->appendPlainText(log_message);

978

ui->current_message->setDocument(&this->empty_text_document);

979

}

980

main_mutex.unlock();

981

on_update_folders_and_messages_triggered();

982}

983catch (const std::exception &exc)

984{

985

QMessageBox::critical(this, "Ошибка", exc.what());

986}

987}

988catch (const std::exception &exc)

989{

990QMessageBox::critical(this, "Ошибка", exc.what());

991}

992}

993

994void MainWindow::on_delete_selected_message_triggered()

995{

996std::lock_guard<std::mutex> main_lock(main_mutex);

997try

998{

999QTreeWidgetItem *current_folder = ui->folders_tree->currentItem(); 1000 std::list<std::string> folder_name;

1001 if (current_folder == nullptr)

1002

{

1003

if (this->current_item.empty())

1004

{

1005

QMessageBox::warning(this, "Внимание", "Папка не выбрана");

1006

return;

1007

}

1008

folder_name = this->current_item;

1009

}

1010

else

1011

{

1012

QTreeWidgetItem *current = current_folder;

1013

while (current)

1014

{

1015

folder_name.emplace_front(current->text(3).toStdString());

1016

current = current->parent();

1017

}

1018

this->current_item = folder_name;

1019

}

1020

QItemSelectionModel *select = ui->messages_table->selectionModel();

1021

if (!select->hasSelection())

1022

{

1023

QMessageBox::warning(this, "Внимание", "Сообщения не выбраны");

1024

return;

1025

}

1026

bool ok = (QMessageBox::question(this, "Внимание", "Вы уверены, что хотите

 

удалить выбранные сообщения?",

1027

QMessageBox::Yes | QMessageBox::No,

 

QMessageBox::No) == QMessageBox::Yes);

1028

if (!ok)

1029

{

1030

return;

1031

}

69

1032

try

1033

{

1034

std::string update_message;

1035

QModelIndexList selection = select->selectedIndexes();

1036

if (selection.count() == 0)

1037

{

1038

QMessageBox::warning(this, "Внимание", "Сообщения не выбраны");

1039

return;

1040

}

1041

std::unordered_set<int> rows;

1042

for (qsizetype i = 0; i < selection.count(); i++)

1043

{

1044

rows.insert(selection.at(i).row());

1045

}

1046

std::chrono::system_clock::time_point start =

 

std::chrono::system_clock::now();

1047

mailio::imaps conn(imap_settings.get_server_address(),

1048

static_cast<unsigned>(imap_settings.get_server_port()),

 

timeout);

1049

conn.authenticate(imap_settings.get_login(), imap_settings.get_password(),

 

imap_settings.get_auth_method());

1050

for (auto row : rows)

1051

{

1052

QTableWidgetItem *current_uid = ui->messages_table->item(row, 6);

1053

if (current_uid == nullptr || current_uid->text().isEmpty())

1054

{

1055

QMessageBox::warning(this, "Внимание", "UID одного сообщения не

 

найден");

1056

continue;

1057

}

1058

ok = false;

1059

unsigned long uid = current_uid->text().toULong(&ok);

1060

if (!ok)

1061

{

1062

QMessageBox::warning(this, "Внимание", "Неверный UID у одного

 

сообщения");

1063

continue;

1064

}

1065

std::string datetime_s = ui->messages_table->item(row, 2)-

 

>text().toStdString();

1066

try

1067

{

1068

conn.remove(folder_name, uid, true);

1069

std::chrono::duration<double> sec =

 

std::chrono::system_clock::now() - start;

1070

update_message = "Сообщение #" + std::to_string(uid) + " (" +

 

datetime_s + ") удалено (" +

1071

std::to_string(sec.count()) + " сек.)";

1072

}

1073

catch (const std::exception &exc)

1074

{

1075

update_message = "Сообщение #" + std::to_string(uid) + " (" +

 

datetime_s +

1076

") не удалено: " + std::string(exc.what());

1077

}

1078

std::string current_datetime_s = get_current_datetime_as_string();

1079

QString log_message = QString::fromStdString(current_datetime_s + ". "

 

+ update_message);

1080

ui->status_bar->showMessage(log_message);

1081

ui->logs_text_edit->appendPlainText(log_message);

1082

ui->current_message->setDocument(&this->empty_text_document);

1083

}

1084

main_mutex.unlock();

1085

on_update_folders_and_messages_triggered();

1086

}

1087

catch (const std::exception &exc)

1088

{

1089

QMessageBox::critical(this, "Ошибка", exc.what());

1090

}

1091

}

1092

catch (const std::exception &exc)

70

Соседние файлы в папке Готовая курсовая работа