Changeset 190
- Timestamp:
- 03/28/09 04:17:53 (3 years ago)
- Location:
- branches/message_tree
- Files:
-
- 3 edited
-
message_tree.cpp (modified) (9 diffs)
-
message_tree.h (modified) (1 diff)
-
version.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/message_tree/message_tree.cpp
r189 r190 278 278 //---------------------------------------------------------------------------------------------- 279 279 280 bool AMessageTree::checkCurrentItem (bool select_first) 281 { 282 if (currentItem() != NULL) 283 return true; 284 285 if (topLevelItemCount() == 0) 286 return false; 287 288 if (select_first == true) 289 setCurrentItem(topLevelItem(0)); 290 else 291 { 292 // последний топик в списке 293 MessageTreeWidgetItem* topic_item = static_cast<MessageTreeWidgetItem*>(topLevelItem(topLevelItemCount() - 1)); 294 295 // если элемент еще не загружен, то загружаем 296 if (topic_item->pag()->IsInfoLoaded == false) 297 setCurrentItem(topic_item); 298 299 // если дочерние элементы еще не загружены, то загружаем 300 if (topic_item->pag()->IsChildLoaded == false) 301 topic_item->setExpanded(true); 302 303 // выделяем последний лист в топике 304 MessageTreeWidgetItem* last_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::lastLeaf(topic_item)); 305 306 setCurrentItem(last_item); 307 } 308 309 return true; 310 } 311 //---------------------------------------------------------------------------------------------- 312 313 void AMessageTree::changeForum (const AForumInfo* forum_info) 314 { 315 // 316 // базовая очистка 317 // 318 319 m_current_forum.ID = 0; 320 m_current_forum.IDGroup = 0; 321 m_current_forum.ShortName = ""; 322 m_current_forum.Name = ""; 323 m_current_forum.Rated = false; 324 m_current_forum.InTop = false; 325 m_current_forum.RateLimit = 0; 326 327 m_me.ID = 0; 328 m_me.Name = ""; 329 m_me.Nick = ""; 330 m_me.RealName = ""; 331 m_me.Email = ""; 332 m_me.Homepage = ""; 333 m_me.Specialization = ""; 334 m_me.WhereFrom = ""; 335 m_me.Origin = ""; 336 337 if (m_main_form != NULL) 338 m_main_form->setEnabledAction(aaViewSource, false); 339 340 clear(); 341 342 m_message_view->clear(); 343 344 scrollToTop(); 345 346 // если выделена группа, то просто очистка 347 if (forum_info == NULL) 348 { 349 headerItem()->setText(0, QString::fromUtf8("тема")); 350 351 QFont font = headerItem()->font(0); 352 font.setBold(false); 353 headerItem()->setFont(0, font); 354 355 return; 356 } 357 358 // 359 // есть форум для отображения 360 // 361 362 m_current_forum.ID = forum_info->ID; 363 m_current_forum.IDGroup = forum_info->IDGroup; 364 m_current_forum.ShortName = forum_info->ShortName; 365 m_current_forum.Name = forum_info->Name; 366 m_current_forum.Rated = forum_info->Rated; 367 m_current_forum.InTop = forum_info->InTop; 368 m_current_forum.RateLimit = forum_info->RateLimit; 369 370 // вывод наименования форума в хедер 371 headerItem()->setText(0, m_current_forum.Name); 372 373 // 374 // загрузка топиков в зависимости от типа форума 375 // 376 377 // получение хранилища 378 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 379 380 if (storage.get() == NULL) 381 { 382 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 383 return; 384 } 385 386 // получение информации о себе 387 // TODO: вынести в AGlobal 388 QSettings settings; 389 390 m_me.Name = settings.value("rsdn/login", "").toString(); 391 392 if (storage->whoAmI(m_me, NULL) == false) 393 m_me.Name = ""; 394 395 // если группа форумов обыкновенная 396 if (m_current_forum.IDGroup != SPECIAL_ID_GROUP) 397 { 398 // получение топиков 399 // ориентировочное время выполнения 68 ms (для форума NET, 28199 топиков) 400 // основное время занимает запрос данных из хранилища 401 QList<int> topic_list; 402 403 if (storage->getForumTopicList(m_current_forum.ID, AGlobal::getInstance()->MaxTopicToShow, topic_list, NULL) == false) 404 { 405 storage->showError(m_parent); 406 return; 407 } 408 409 // установка топиков 410 // ориентировочное время выполнения 50 ms (для форума NET, 28199 топиков) 411 // основное время занимает создание объекта MessageTreeWidgetItem 412 QList<QTreeWidgetItem*> items; 413 414 for (int i = 0; i < topic_list.count(); i++) 415 { 416 // начальное заполнение дескриптора топика 417 AMessageInfoGUI* info = createItem(); 418 419 info->ID = topic_list[i]; 420 421 items.append(info->Item); 422 } 423 424 // отображение на виджет 425 addTopLevelItems(items); 426 427 // дозагрузка информации о топиках, находящихся в видимой области отображения 428 scrollTopics(); 429 } 430 else // if (forum_info->IDGroup != SPECIAL_ID_GROUP) 431 { 432 // специальная группа форумов 433 if (m_current_forum.ID == SPECIAL_ID_FORUM_MESSAGE2SEND) 434 loadMessage2Send(); 435 else if (m_current_forum.ID == SPECIAL_ID_FORUM_RATING2SEND) 436 loadRating2Send(); 437 else if (m_current_forum.ID == SPECIAL_ID_FORUM_MODERATE2SEND) 438 loadModerate2Send(); 439 } 440 } 441 //---------------------------------------------------------------------------------------------- 442 280 443 void AMessageTree::vertical_scroll (int /*value*/) 281 444 { 282 445 scrollTopics(); 446 } 447 //---------------------------------------------------------------------------------------------- 448 449 void AMessageTree::scrollTopics () 450 { 451 // Среднее время выполнения для дозагрузки одного элемента 5 ms 452 // Среднее время выполнения для дозагрузки страницы из 56 топиков (полный экран 1280х1024) 32 ms 453 454 // пустой форум или спец-группа 455 if (m_current_forum.ID == 0 || m_current_forum.IDGroup == SPECIAL_ID_GROUP) 456 return; 457 458 // 459 // Определение диапазона возможной подгрузки данных 460 // 461 462 // поиск корня верхнего видимого элемента в отображении 463 QTreeWidgetItem* top_item = itemAt(1, 1); 464 465 if (top_item == NULL) 466 return; // нет элементов в дереве(?) 467 468 top_item = ATreeWidgetItem::rootItem(top_item); 469 470 int top_index = indexOfTopLevelItem(top_item); 471 472 // поиск корня нижнего видимого элемента в отображении 473 QTreeWidgetItem* bottom_item = itemAt(1, height() - 1); 474 475 int bottom_index; 476 477 if (bottom_item == NULL) 478 bottom_index = topLevelItemCount(); 479 else 480 { 481 bottom_item = ATreeWidgetItem::rootItem(bottom_item); 482 483 bottom_index = indexOfTopLevelItem(bottom_item) + 1; 484 } 485 486 // 487 // Поиск еще не загруженных топиков в диапазоне 488 // 489 490 AMessageInfoGUIPtrList list; 491 492 while (top_index < bottom_index) 493 { 494 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(topLevelItem(top_index)); 495 496 AMessageInfoGUI* info = item->pag(); 497 498 if (info->IsInfoLoaded == false) 499 list.append(info); 500 501 top_index++; 502 } 503 504 // 505 // загрузка топиков, которые не загружены 506 // 507 508 if (list.count() == 0) 509 return; 510 511 // получение хранилища 512 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 513 514 if (storage.get() == NULL) 515 { 516 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 517 return; 518 } 519 520 if (storage->getTopicInfoList(m_current_forum.ID, list, m_me.ID, NULL) == false) 521 { 522 storage->showError(m_parent); 523 return; 524 } 525 526 AGlobal* global = AGlobal::getInstance(); 527 528 // 529 // Установка загруженой информации 530 // 531 532 for (int i = 0; i < list.count(); i++) 533 { 534 AMessageInfoGUI* info = list[i]; 535 536 info->IsInfoLoaded = true; 537 info->UnreadChildCount = 0; 538 info->UnreadChildCountMy = 0; 539 540 info->Item->setText(0, info->Subject); 541 542 // TODO: сделать общую функцию формирования имени/ника 543 if (info->IDUser == 0) 544 info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 545 else 546 info->Item->setText(1, info->UserNick); 547 548 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 549 550 if (info->HasChild == true) 551 info->Item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); 552 553 if (info->IsRead == true) 554 { 555 if (info->HasUnreadChildMy) 556 info->Item->setIcon(0, m_child_unread_my); 557 else if (info->HasUnreadChild) 558 info->Item->setIcon(0, m_child_unread); 559 else 560 info->Item->setIcon(0, m_message_read); 561 } 562 else 563 { 564 if (info->HasUnreadChildMy) 565 info->Item->setIcon(0, m_message_unread_my); 566 else 567 info->Item->setIcon(0, m_message_unread); 568 } 569 } 570 } 571 //---------------------------------------------------------------------------------------------- 572 573 void AMessageTree::expand_item (QTreeWidgetItem* item_expanded) 574 { 575 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(item_expanded); 576 577 AMessageInfoGUI* info = item->pag(); 578 579 // если дочерние сообщения не загружены (а это может быть только для топика в текущей реализации) 580 if (info->HasChild == true && info->IsChildLoaded == false) 581 { 582 // получение хранилища 583 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 584 585 if (storage.get() == NULL) 586 { 587 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 588 return; 589 } 590 591 // заполнение списка сообщений 592 // ориентировочное время выполнения 111 ms (для топика 279396 - 5149 сообщений) 593 // основное время занимает присвоение данных полям (преобразование из QVariant в QSqlQuery) 594 AMessageInfoGUIPtrList list; 595 596 if (storage->getTopicMessageList(m_current_forum.ID, info->ID, list, this, NULL) == false) 597 { 598 storage->showError(m_parent); 599 return; 600 } 601 602 // постройка дерева, обход в ширину быстрее чем в высоту 603 // ориентировочное время выполнения 900 ms (для топика 279396 - 5149 сообщений) 604 // наиболее высокое дерево составляет 1555 сообщений (для топика 1099540) 605 // наиболее широкое дерево (глубина рекурсии) пока неизвестно 606 buildTree(info, &list); 607 608 // для предотвращения повторной загрузки 609 info->IsChildLoaded = true; 610 611 // раскрытие дерева до уровня непрочитаных топиков 612 if (info->UnreadChildCount != 0) 613 expandUnreadChild(item); 614 } 615 } 616 //---------------------------------------------------------------------------------------------- 617 618 void AMessageTree::expandUnreadChild (QTreeWidgetItem* widget_item) 619 { 620 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 621 622 if (item->pag()->UnreadChildCount != 0) 623 { 624 for (int i = 0; i < item->childCount(); i++) 625 if (((MessageTreeWidgetItem*)item->child(i))->pag()->UnreadChildCount != 0) 626 expandUnreadChild(item->child(i)); 627 628 expandItem(item); 629 } 630 } 631 //---------------------------------------------------------------------------------------------- 632 633 void AMessageTree::buildTree (AMessageInfoGUI* root, AMessageInfoGUIPtrList* list) 634 { 635 if (list->count() == 0) 636 return; 637 638 int list_index = 0; 639 640 AGlobal* global = AGlobal::getInstance(); 641 642 while (list_index < list->count()) 643 { 644 AMessageInfoGUI* info = list->at(list_index); 645 646 if (info->IDParent == root->ID) 647 { 648 list->removeAt(list_index); 649 650 info->IsInfoLoaded = true; 651 info->IsChildLoaded = true; 652 info->UnreadChildCount = 0; 653 info->UnreadChildCountMy = 0; 654 655 info->Item->setText(0, info->Subject); 656 657 // TODO: сделать общую функцию формирования имени/ника 658 if (info->IDUser != 0) 659 info->Item->setText(1, info->UserNick); 660 else 661 info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 662 663 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 664 665 root->Item->addChild(info->Item); 666 667 // установка родителям свойств непрочитанных сообщений 668 if (info->IsRead == false && root->IDUser == m_me.ID) 669 { 670 // сообщение не прочитано и это ответ не мне 671 info->Item->setIcon(0, m_message_unread_my); 672 673 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 674 675 while (item_parent != NULL) 676 { 677 AMessageInfoGUI* info_parent = item_parent->pag(); 678 679 if (info_parent->HasUnreadChildMy != true) 680 { 681 info_parent->HasUnreadChild = true; 682 info_parent->HasUnreadChildMy = true; 683 684 if (info_parent->IsRead == true) 685 item_parent->setIcon(0, m_child_unread_my); 686 else 687 item_parent->setIcon(0, m_message_unread_my); 688 } 689 690 info_parent->UnreadChildCount++; 691 info_parent->UnreadChildCountMy++; 692 693 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 694 695 } // while (item_parent != NULL) 696 } 697 else if (info->IsRead == false) 698 { 699 // сообщение не прочитано, но это ответ не мне 700 info->Item->setIcon(0, m_message_unread); 701 702 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 703 704 while (item_parent != NULL) 705 { 706 AMessageInfoGUI* info_parent = item_parent->pag(); 707 708 if (info_parent->HasUnreadChild != true) 709 { 710 info_parent->HasUnreadChild = true; 711 712 if (info_parent->IsRead == true) 713 item_parent->setIcon(0, m_child_unread); 714 } 715 716 info_parent->UnreadChildCount++; 717 718 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 719 720 } // while (item_parent != NULL) 721 } 722 else // else if (info->IsRead == false) 723 { 724 // сообщение прочитано 725 info->Item->setIcon(0, m_message_read); 726 } 727 728 // достройка дочерних веток для текущей 729 if (info->HasChild) 730 { 731 buildTree(info, list); 732 list_index = 0; 733 } 734 } 735 else // if (info->ID == id_parent) 736 { 737 list_index++; 738 } 739 } 740 } 741 //---------------------------------------------------------------------------------------------- 742 743 void AMessageTree::timer_on_timer () 744 { 745 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 746 747 if (item != NULL) 748 markItemAsRead(item, true); 283 749 } 284 750 //---------------------------------------------------------------------------------------------- … … 353 819 //---------------------------------------------------------------------------------------------- 354 820 821 void AMessageTree::markItemAsRead (QTreeWidgetItem* widget_item, bool is_read) 822 { 823 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 824 825 AMessageInfoGUI* info = item->pag(); 826 827 // если уже прочитан 828 if (info->IsRead == is_read) 829 return; 830 831 // пометить как прочитанное в хранилище 832 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 833 834 if (storage.get() == NULL) 835 { 836 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 837 return; 838 } 839 840 if (storage->setIDsAsRead(QList<int>() << info->ID, idsMessage, is_read, QDateTime(), NULL) == false) 841 { 842 storage->showError(m_parent); 843 return; 844 } 845 846 // установка флага как прочитанного и пометка в дереве 847 info->IsRead = is_read; 848 849 if (is_read == true) 850 { 851 // установка иконки помечаемому сообщению 852 if (info->HasUnreadChildMy) 853 item->setIcon(0, m_child_unread_my); 854 else if (info->HasUnreadChild) 855 item->setIcon(0, m_child_unread); 856 else 857 item->setIcon(0, m_message_read); 858 859 // флаг того, что это было сообщение для меня 860 bool message_to_me = false; 861 862 // установка флагов и иконок у родительских сообщений 863 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(item->parent()); 864 865 if (item_parent != NULL && item_parent->pag()->IDUser == m_me.ID) 866 message_to_me = true; 867 868 while (item_parent != NULL) 869 { 870 AMessageInfoGUI* info_parent = item_parent->pag(); 871 872 int old_unread_count = info_parent->UnreadChildCount; 873 int old_unread_count_my = info_parent->UnreadChildCountMy; 874 875 // уменьшение количества непрочитанных дочерних 876 // и установка соответствующих флагов 877 if (info_parent->UnreadChildCount > 0) 878 info_parent->UnreadChildCount--; 879 880 if (message_to_me == true && info_parent->UnreadChildCountMy > 0) 881 info_parent->UnreadChildCountMy--; 882 883 if (info_parent->UnreadChildCountMy == 0) 884 info_parent->HasUnreadChildMy = false; 885 886 if (info_parent->UnreadChildCount == 0) 887 info_parent->HasUnreadChild = false; 888 889 // установка иконок 890 if (info_parent->IsRead == false) 891 { 892 // родитель непрочитан 893 894 // если среди дочерних прочитали дочернее мне и больше непрочитанных дочерних мне нет 895 // и должна произойти смена иконки 896 if (old_unread_count_my != 0 && info_parent->UnreadChildCountMy == 0) 897 item_parent->setIcon(0, m_message_unread); 898 } 899 else 900 { 901 // родитель прочитан 902 903 // если среди дочерних есть непрочитанные мне 904 // и должна произойти смена иконки 905 if (old_unread_count_my != info_parent->UnreadChildCountMy && info_parent->UnreadChildCountMy > 0) 906 item_parent->setIcon(0, m_child_unread_my); 907 908 // если среди дочерних есть непрочитанные 909 // и должна произойти смена иконки 910 else if (old_unread_count != info_parent->UnreadChildCount && info_parent->UnreadChildCount > 0) 911 item_parent->setIcon(0, m_child_unread); 912 913 // нет дочерних непрочитанных 914 else 915 item_parent->setIcon(0, m_message_read); 916 } 917 918 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 919 } 920 921 // уменьшение количества непрочитанных в дереве форума 922 m_forum_tree->changeUnreadCount(-1); 923 } 924 else // if (is_read == true) 925 { 926 // TODO: Доделать пометку родителей, если отметилось сообщение, которое является ответом мне 927 928 // установка иконки помечаемому сообщению 929 item->setIcon(0, m_message_unread); 930 931 // установка флагов и иконок у родительских сообщений 932 MessageTreeWidgetItem* parent_item = static_cast<MessageTreeWidgetItem*>(item->parent()); 933 934 while (parent_item != NULL) 935 { 936 AMessageInfoGUI* parent_info = parent_item->pag(); 937 938 // смена иконки при необходимости 939 if (parent_info->IsRead == true && parent_info->HasUnreadChild == false) 940 parent_item->setIcon(0, m_child_unread); 941 942 parent_info->UnreadChildCount++; 943 parent_info->HasUnreadChild = true; 944 945 parent_item = static_cast<MessageTreeWidgetItem*>(parent_item->parent()); 946 } 947 948 // увеличение количества непрочитанных в дереве форума 949 m_forum_tree->changeUnreadCount(1); 950 951 } // if (is_read == true) ... else 952 } 953 //---------------------------------------------------------------------------------------------- 954 955 void AMessageTree::menu_mark_message_as_read_triggered () 956 { 957 QTreeWidgetItem* item = currentItem(); 958 959 if (item == NULL) 960 return; 961 962 markItemAsRead(item, true); 963 } 964 //---------------------------------------------------------------------------------------------- 965 966 void AMessageTree::menu_mark_message_as_unread_triggered () 967 { 968 QTreeWidgetItem* item = currentItem(); 969 970 if (item == NULL) 971 return; 972 973 markItemAsRead(item, false); 974 } 975 //---------------------------------------------------------------------------------------------- 976 977 bool AMessageTree::markThreadAsRead (int id, bool is_read) 978 { 979 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 980 981 if (storage.get() == NULL) 982 { 983 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 984 return false; 985 } 986 987 if (storage->setIDsAsRead(QList<int>() << id, idsTopic, is_read, QDateTime(), NULL) == false) 988 { 989 storage->showError(m_parent); 990 return false; 991 } 992 993 return true; 994 } 995 //---------------------------------------------------------------------------------------------- 996 997 void AMessageTree::menu_mark_thread_as_read_triggered () 998 { 999 QTreeWidgetItem* item = currentItem(); 1000 1001 if (item == NULL) 1002 return; 1003 1004 // поиск родителя 1005 MessageTreeWidgetItem* parent = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 1006 1007 AMessageInfoGUI* info = parent->pag(); 1008 1009 // пометка в хранилище 1010 if (markThreadAsRead(info->ID, true) != true) 1011 return; 1012 1013 // пометка в дереве 1014 if (info->IsChildLoaded == true) 1015 { 1016 int count = 0; 1017 1018 markThreadAsRead(parent, true, count); 1019 1020 m_forum_tree->changeUnreadCount(-count); 1021 } 1022 else 1023 { 1024 parent->setIcon(0, m_message_read); 1025 1026 AMessageInfoGUI* info = parent->pag(); 1027 1028 info->HasUnreadChild = false; 1029 info->HasUnreadChildMy = false; 1030 info->UnreadChildCount = 0; 1031 info->UnreadChildCountMy = 0; 1032 1033 // поскольку дочерние элементы еще не загружены, 1034 // обновление количества непрочитаных в дереве форума 1035 m_forum_tree->reloadUnread(false); 1036 } 1037 } 1038 //---------------------------------------------------------------------------------------------- 1039 1040 void AMessageTree::menu_mark_thread_as_unread_triggered () 1041 { 1042 QTreeWidgetItem* item = currentItem(); 1043 1044 if (item == NULL) 1045 return; 1046 1047 // поиск родителя 1048 MessageTreeWidgetItem* parent = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 1049 1050 AMessageInfoGUI* info = parent->pag(); 1051 1052 // пометка в хранилище 1053 if (markThreadAsRead(info->ID, false) != true) 1054 return; 1055 1056 // пометка в дереве 1057 if (info->IsChildLoaded == true) 1058 { 1059 int count = 0; 1060 1061 markThreadAsRead(parent, false, count); 1062 1063 m_forum_tree->changeUnreadCount(count); 1064 } 1065 else 1066 { 1067 parent->setIcon(0, m_message_unread); 1068 1069 AMessageInfoGUI* info = parent->pag(); 1070 1071 if (info->HasChild == true) 1072 info->HasUnreadChild = true; 1073 else 1074 info->HasUnreadChild = false; 1075 1076 info->HasUnreadChildMy = false; 1077 1078 // поскольку дочерние элементы еще не загружены, 1079 // обновление количества непрочитаных в дереве форума 1080 m_forum_tree->reloadUnread(false); 1081 } 1082 } 1083 //---------------------------------------------------------------------------------------------- 1084 1085 void AMessageTree::menu_reply_triggered () 1086 { 1087 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 1088 1089 if (item == NULL) 1090 return; 1091 1092 FormMessage* form = new FormMessage(NULL, true, *(item->pag())); 1093 1094 form->setForumTree(m_forum_tree); 1095 form->setMainForm(m_main_form); 1096 1097 form->show(); 1098 } 1099 //---------------------------------------------------------------------------------------------- 1100 1101 void AMessageTree::loadMessage2Send () 1102 { 1103 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1104 1105 if (storage.get() == NULL) 1106 { 1107 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1108 return; 1109 } 1110 1111 AMessageInfoList list; 1112 1113 if (storage->getMessage2SendList(list, NULL) == false) 1114 { 1115 storage->showError(m_parent); 1116 return; 1117 } 1118 1119 QList<QTreeWidgetItem*> items; 1120 1121 AGlobal* global = AGlobal::getInstance(); 1122 1123 for (int i = 0; i < list.count(); i++) 1124 { 1125 AMessageInfoGUI* info = createItem(); 1126 1127 info->ID = list[i].ID; 1128 info->IDTopic = list[i].IDTopic; 1129 info->IDParent = list[i].IDParent; 1130 info->IDUser = list[i].IDUser; 1131 info->IDForum = list[i].IDForum; 1132 info->Subject = list[i].Subject; 1133 info->MessageName = list[i].MessageName; 1134 info->UserNick = list[i].UserNick; 1135 info->Message = list[i].Message; 1136 info->IDArticle = list[i].IDArticle; 1137 info->MessageDate = list[i].MessageDate; 1138 info->UpdateDate = list[i].UpdateDate; 1139 info->UserRole = list[i].UserRole; 1140 info->UserTitle = list[i].UserTitle; 1141 info->UserTitleColor = list[i].UserTitleColor; 1142 info->LastModerated = list[i].LastModerated; 1143 1144 info->IsInfoLoaded = true; 1145 info->IsRead = true; 1146 info->IsBodyLoaded = true; 1147 info->IsChildLoaded = true; 1148 info->HasUnreadChild = 0; 1149 info->HasUnreadChildMy = 0; 1150 info->Special = list[i].ID; 1151 1152 info->Item->setText(0, info->Subject); 1153 1154 if (info->IDUser == 0) 1155 { 1156 info->UserNick = QString::fromUtf8("(локальный)"); 1157 info->Item->setText(1, info->UserNick); 1158 } 1159 else 1160 info->Item->setText(1, info->UserNick); 1161 1162 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 1163 1164 items.append(info->Item); 1165 } 1166 1167 addTopLevelItems(items); 1168 } 1169 //---------------------------------------------------------------------------------------------- 1170 355 1171 void AMessageTree::processUrl (const QString& url) 356 1172 { … … 459 1275 //---------------------------------------------------------------------------------------------- 460 1276 461 void AMessageTree::menu_reply_triggered () 462 { 1277 void AMessageTree::gotoNextUnreadArticle (QTreeWidgetItem* current_item) 1278 { 1279 AMessageInfoGUI* info = NULL; 1280 1281 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(current_item); 1282 1283 // если не было выделения, то ищем первый непрочитанный топик или топик с непрочитанными сообщениями 1284 if (item == NULL) 1285 { 1286 for (int i = 0; i < topLevelItemCount(); i++) 1287 { 1288 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(i)); 1289 1290 info = item->pag(); 1291 1292 if (info->IsInfoLoaded == false) 1293 return; 1294 else if (info->IsRead == false) 1295 { 1296 setCurrentItem(item); 1297 1298 scrollToItem(item, QAbstractItemView::PositionAtCenter); 1299 1300 return; 1301 } 1302 else if (info->HasUnreadChild == true) 1303 break; 1304 } 1305 } 1306 else 1307 info = item->pag(); 1308 1309 // флаг петли 1310 bool loopback = false; 1311 1312 // есть выделение или найден топик с непрочитанными сообщениями 1313 while (true) 1314 { 1315 if (info->HasUnreadChild == true && info->IsChildLoaded == false) 1316 item->setExpanded(true); 1317 1318 // выбор следующего элемента 1319 if (info->HasUnreadChild == true) 1320 // если есть дочерние непрочитанные, то выбираем первый дочерний 1321 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::firstChild(item)); 1322 else 1323 { 1324 // если нет дочерних непрочитанных, то ... 1325 1326 // смотрим, есть ли у элемента родитель и есть ли у родителя непрочитанные дочерние 1327 MessageTreeWidgetItem* parent_item = static_cast<MessageTreeWidgetItem*>(item->parent()); 1328 1329 // если есть родитель и у него нет непрочитанных дочерних, то поднимаемся на уровень родителя 1330 if (parent_item != NULL && parent_item->pag()->HasUnreadChild == false) 1331 item = parent_item; 1332 else 1333 { 1334 // у родителя есть непрочитанные дочерние или нет родителя - переходим к следующему брату 1335 // несмотря на то, что непрочитанный брат может быть и выше 1336 MessageTreeWidgetItem* sibling_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item)); 1337 1338 // если следующего брата нет 1339 if (sibling_item == NULL && parent_item != NULL) 1340 { 1341 // движение вверх по дереву, пока не найдется следующий брат у родителя 1342 while (parent_item != NULL) 1343 { 1344 MessageTreeWidgetItem* last_child_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::lastChild(parent_item)); 1345 1346 if (last_child_item != item) 1347 break; 1348 1349 item = parent_item; 1350 1351 parent_item = static_cast<MessageTreeWidgetItem*>(item->parent()); 1352 } 1353 1354 // сдвиг на следующего брата в соседней подветке 1355 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item)); 1356 } 1357 else 1358 item = sibling_item; 1359 } 1360 } 1361 1362 // если достигнут конец дерева, то переходим в корень 1363 if (item == NULL) 1364 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 1365 1366 info = item->pag(); 1367 1368 // если найденый топик с незагруженной информацией 1369 if (info->IsInfoLoaded == false) 1370 { 1371 if (loopback == true) 1372 return; 1373 1374 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 1375 info = item->pag(); 1376 1377 loopback = true; 1378 } 1379 1380 if (info->IsRead == false) 1381 break; 1382 } 1383 1384 setCurrentItem(item); 1385 1386 scrollToItem(item, QAbstractItemView::PositionAtCenter); 1387 } 1388 //---------------------------------------------------------------------------------------------- 1389 1390 void AMessageTree::loadRating2Send () 1391 { 1392 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1393 1394 if (storage.get() == NULL) 1395 { 1396 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1397 return; 1398 } 1399 1400 ARating2SendList rating_list; 1401 AMessageInfoList message_list; 1402 1403 if (storage->getRating2SendList(message_list, rating_list, NULL) == false) 1404 { 1405 storage->showError(m_parent); 1406 return; 1407 } 1408 1409 QList<QTreeWidgetItem*> items; 1410 1411 AGlobal* global = AGlobal::getInstance(); 1412 1413 for (int i = 0; i < message_list.count(); i++) 1414 { 1415 AMessageInfoGUI* info = createItem(); 1416 1417 info->ID = message_list[i].ID; 1418 info->IDTopic = message_list[i].IDTopic; 1419 info->IDParent = message_list[i].IDParent; 1420 info->IDUser = message_list[i].IDUser; 1421 info->IDForum = message_list[i].IDForum; 1422 info->Subject = message_list[i].Subject; 1423 info->MessageName = message_list[i].MessageName; 1424 info->UserNick = message_list[i].UserNick; 1425 info->Message = message_list[i].Message; 1426 info->IDArticle = message_list[i].IDArticle; 1427 info->MessageDate = message_list[i].MessageDate; 1428 info->UpdateDate = message_list[i].UpdateDate; 1429 info->UserRole = message_list[i].UserRole; 1430 info->UserTitle = message_list[i].UserTitle; 1431 info->UserTitleColor = message_list[i].UserTitleColor; 1432 info->LastModerated = message_list[i].LastModerated; 1433 1434 info->IsInfoLoaded = true; 1435 info->IsRead = true; 1436 info->IsBodyLoaded = true; 1437 info->IsChildLoaded = true; 1438 info->HasUnreadChild = 0; 1439 info->HasUnreadChildMy = 0; 1440 info->Special = rating_list[i].ID; 1441 1442 info->Item->setText(0, info->Subject); 1443 1444 if (info->IDUser == 0) 1445 { 1446 info->UserNick = QString::fromUtf8("(локальный)"); 1447 info->Item->setText(1, info->UserNick); 1448 } 1449 else 1450 info->Item->setText(1, info->UserNick); 1451 1452 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 1453 1454 int rate = rating_list[i].Rate; 1455 1456 if (rate == -4) 1457 info->Item->setIcon(0, m_rating_plus); 1458 else if (rate == -3) 1459 info->Item->setIcon(0, m_rating_plus_1); 1460 else if (rate == -2) 1461 info->Item->setIcon(0, m_rating_smile); 1462 else if (rate == -1) 1463 info->Item->setIcon(0, m_rating_cross); 1464 else if (rate == 0) 1465 info->Item->setIcon(0, m_rating_minus); 1466 else if (rate == 1) 1467 info->Item->setIcon(0, m_rating_1); 1468 else if (rate == 2) 1469 info->Item->setIcon(0, m_rating_2); 1470 else if (rate == 3) 1471 info->Item->setIcon(0, m_rating_3); 1472 1473 items.append(info->Item); 1474 } 1475 1476 addTopLevelItems(items); 1477 } 1478 //---------------------------------------------------------------------------------------------- 1479 1480 void AMessageTree::loadModerate2Send () 1481 { 1482 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1483 1484 if (storage.get() == NULL) 1485 { 1486 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1487 return; 1488 } 1489 1490 AMessageInfoList message_list; 1491 AModerate2SendList moderate_list; 1492 1493 if (storage->getModerate2SendList(message_list, moderate_list, NULL) == false) 1494 { 1495 storage->showError(m_parent); 1496 return; 1497 } 1498 1499 QList<QTreeWidgetItem*> items; 1500 1501 AGlobal* global = AGlobal::getInstance(); 1502 1503 for (int i = 0; i < message_list.count(); i++) 1504 { 1505 AMessageInfoGUI* info = createItem(); 1506 1507 info->ID = message_list[i].ID; 1508 info->IDTopic = message_list[i].IDTopic; 1509 info->IDParent = message_list[i].IDParent; 1510 info->IDUser = message_list[i].IDUser; 1511 info->IDForum = message_list[i].IDForum; 1512 info->Subject = message_list[i].Subject; 1513 info->MessageName = message_list[i].MessageName; 1514 info->UserNick = message_list[i].UserNick; 1515 info->Message = message_list[i].Message; 1516 info->IDArticle = message_list[i].IDArticle; 1517 info->MessageDate = message_list[i].MessageDate; 1518 info->UpdateDate = message_list[i].UpdateDate; 1519 info->UserRole = message_list[i].UserRole; 1520 info->UserTitle = message_list[i].UserTitle; 1521 info->UserTitleColor = message_list[i].UserTitleColor; 1522 info->LastModerated = message_list[i].LastModerated; 1523 1524 info->IsInfoLoaded = true; 1525 info->IsRead = true; 1526 info->IsBodyLoaded = true; 1527 info->IsChildLoaded = true; 1528 info->HasUnreadChild = 0; 1529 info->HasUnreadChildMy = 0; 1530 info->Special = message_list[i].ID; 1531 1532 info->Item->setText(0, info->Subject); 1533 1534 if (info->IDUser == 0) 1535 { 1536 info->UserNick = QString::fromUtf8("(локальный)"); 1537 info->Item->setText(1, info->UserNick); 1538 } 1539 else 1540 info->Item->setText(1, info->UserNick); 1541 1542 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 1543 1544 info->Item->setIcon(0, m_moderate); 1545 1546 items.append(info->Item); 1547 } 1548 1549 addTopLevelItems(items); 1550 } 1551 //---------------------------------------------------------------------------------------------- 1552 1553 void AMessageTree::gotoNextUnreadThread () 1554 { 1555 AMessageInfoGUI* info = NULL; 1556 463 1557 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 464 1558 1559 // если не было выделения, то ищем следующую непрочитанную статью (она будет первой) 465 1560 if (item == NULL) 466 return; 467 468 FormMessage* form = new FormMessage(NULL, true, *(item->pag())); 469 470 form->setForumTree(m_forum_tree); 471 form->setMainForm(m_main_form); 472 473 form->show(); 474 } 475 //---------------------------------------------------------------------------------------------- 476 477 void AMessageTree::item_double_clicked (QTreeWidgetItem* item, int /*column*/) 478 { 1561 { 1562 gotoNextUnreadArticle(NULL); 1563 return; 1564 } 1565 1566 // item установлен на топик 1567 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 1568 info = item->pag(); 1569 1570 // флаг петли 1571 bool loopback = false; 1572 1573 // поиск следующего топика с непрочитанными сообщениями 1574 while (true) 1575 { 1576 // следующий топик за текущим 1577 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item)); 1578 1579 // если достигнут конец дерева, то переходим в корень 1580 if (item == NULL) 1581 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 1582 1583 info = item->pag(); 1584 1585 // если найденый топик с незагруженной информацией 1586 if (info->IsInfoLoaded == false) 1587 { 1588 if (loopback == true) 1589 return; 1590 1591 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 1592 info = item->pag(); 1593 1594 loopback = true; 1595 } 1596 1597 if (info->IsRead == false) 1598 break; 1599 1600 if (info->HasUnreadChild == true) 1601 { 1602 gotoNextUnreadArticle(item); 1603 return; 1604 } 1605 } 1606 1607 setCurrentItem(item); 1608 1609 scrollToItem(item, QAbstractItemView::PositionAtCenter); 1610 } 1611 //---------------------------------------------------------------------------------------------- 1612 1613 void AMessageTree::menu_special_delete_triggered () 1614 { 1615 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 1616 479 1617 if (item == NULL) 480 1618 return; 481 482 setCurrentItem(item);483 1619 484 1620 if (!(m_current_forum.ID == SPECIAL_ID_FORUM_MESSAGE2SEND || … … 488 1624 return; 489 1625 490 menu_special_edit_triggered(); 491 } 492 //---------------------------------------------------------------------------------------------- 493 494 void AMessageTree::menu_special_edit_triggered () 495 { 496 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 497 1626 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1627 1628 if (storage.get() == NULL) 1629 { 1630 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1631 return; 1632 } 1633 1634 if (storage->deleteSpecial(QList<int>() << item->pag()->Special, m_current_forum.ID, NULL) == false) 1635 { 1636 storage->showError(m_parent); 1637 return; 1638 } 1639 1640 // обновление в дереве форумов количества непрочитанных сообщений 1641 if (m_forum_tree != NULL) 1642 m_forum_tree->reloadUnread(true); 1643 } 1644 //---------------------------------------------------------------------------------------------- 1645 1646 void AMessageTree::item_double_clicked (QTreeWidgetItem* item, int /*column*/) 1647 { 498 1648 if (item == NULL) 499 1649 return; 1650 1651 setCurrentItem(item); 500 1652 501 1653 if (!(m_current_forum.ID == SPECIAL_ID_FORUM_MESSAGE2SEND || … … 505 1657 return; 506 1658 507 if (m_current_forum.ID == SPECIAL_ID_FORUM_MESSAGE2SEND) 508 { 509 FormMessage* form = new FormMessage(NULL, false, *(item->pag()), item->pag()->Special); 510 511 form->setForumTree(m_forum_tree); 512 form->setMainForm(m_main_form); 513 514 form->show(); 515 } 516 else if (m_current_forum.ID == SPECIAL_ID_FORUM_MODERATE2SEND) 517 { 518 FormModerate* form = new FormModerate(m_parent, item->pag()->ID, item->pag()->Special); 519 520 form->setForumTree(m_forum_tree); 521 522 form->exec(); 523 524 return; 525 } 526 } 527 //---------------------------------------------------------------------------------------------- 528 529 void AMessageTree::menu_special_delete_triggered () 1659 menu_special_edit_triggered(); 1660 } 1661 //---------------------------------------------------------------------------------------------- 1662 1663 void AMessageTree::menu_special_edit_triggered () 530 1664 { 531 1665 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); … … 540 1674 return; 541 1675 542 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 543 544 if (storage.get() == NULL) 545 { 546 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 547 return; 548 } 549 550 if (storage->deleteSpecial(QList<int>() << item->pag()->Special, m_current_forum.ID, NULL) == false) 551 { 552 storage->showError(m_parent); 553 return; 554 } 555 556 // обновление в дереве форумов количества непрочитанных сообщений 557 if (m_forum_tree != NULL) 558 m_forum_tree->reloadUnread(true); 1676 if (m_current_forum.ID == SPECIAL_ID_FORUM_MESSAGE2SEND) 1677 { 1678 FormMessage* form = new FormMessage(NULL, false, *(item->pag()), item->pag()->Special); 1679 1680 form->setForumTree(m_forum_tree); 1681 form->setMainForm(m_main_form); 1682 1683 form->show(); 1684 } 1685 else if (m_current_forum.ID == SPECIAL_ID_FORUM_MODERATE2SEND) 1686 { 1687 FormModerate* form = new FormModerate(m_parent, item->pag()->ID, item->pag()->Special); 1688 1689 form->setForumTree(m_forum_tree); 1690 1691 form->exec(); 1692 1693 return; 1694 } 559 1695 } 560 1696 //---------------------------------------------------------------------------------------------- … … 740 1876 //---------------------------------------------------------------------------------------------- 741 1877 742 bool AMessageTree::checkCurrentItem (bool select_first)743 {744 if (currentItem() != NULL)745 return true;746 747 if (topLevelItemCount() == 0)748 return false;749 750 if (select_first == true)751 setCurrentItem(topLevelItem(0));752 else753 {754 // последний топик в списке755 MessageTreeWidgetItem* topic_item = static_cast<MessageTreeWidgetItem*>(topLevelItem(topLevelItemCount() - 1));756 757 // если элемент еще не загружен, то загружаем758 if (topic_item->pag()->IsInfoLoaded == false)759 setCurrentItem(topic_item);760 761 // если дочерние элементы еще не загружены, то загружаем762 if (topic_item->pag()->IsChildLoaded == false)763 topic_item->setExpanded(true);764 765 // выделяем последний лист в топике766 MessageTreeWidgetItem* last_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::lastLeaf(topic_item));767 768 setCurrentItem(last_item);769 }770 771 return true;772 }773 //----------------------------------------------------------------------------------------------774 775 void AMessageTree::gotoNextUnreadArticle (QTreeWidgetItem* current_item)776 {777 AMessageInfoGUI* info = NULL;778 779 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(current_item);780 781 // если не было выделения, то ищем первый непрочитанный топик или топик с непрочитанными сообщениями782 if (item == NULL)783 {784 for (int i = 0; i < topLevelItemCount(); i++)785 {786 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(i));787 788 info = item->pag();789 790 if (info->IsInfoLoaded == false)791 return;792 else if (info->IsRead == false)793 {794 setCurrentItem(item);795 796 scrollToItem(item, QAbstractItemView::PositionAtCenter);797 798 return;799 }800 else if (info->HasUnreadChild == true)801 break;802 }803 }804 else805 info = item->pag();806 807 // флаг петли808 bool loopback = false;809 810 // есть выделение или найден топик с непрочитанными сообщениями811 while (true)812 {813 if (info->HasUnreadChild == true && info->IsChildLoaded == false)814 item->setExpanded(true);815 816 // выбор следующего элемента817 if (info->HasUnreadChild == true)818 // если есть дочерние непрочитанные, то выбираем первый дочерний819 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::firstChild(item));820 else821 {822 // если нет дочерних непрочитанных, то ...823 824 // смотрим, есть ли у элемента родитель и есть ли у родителя непрочитанные дочерние825 MessageTreeWidgetItem* parent_item = static_cast<MessageTreeWidgetItem*>(item->parent());826 827 // если есть родитель и у него нет непрочитанных дочерних, то поднимаемся на уровень родителя828 if (parent_item != NULL && parent_item->pag()->HasUnreadChild == false)829 item = parent_item;830 else831 {832 // у родителя есть непрочитанные дочерние или нет родителя - переходим к следующему брату833 // несмотря на то, что непрочитанный брат может быть и выше834 MessageTreeWidgetItem* sibling_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item));835 836 // если следующего брата нет837 if (sibling_item == NULL && parent_item != NULL)838 {839 // движение вверх по дереву, пока не найдется следующий брат у родителя840 while (parent_item != NULL)841 {842 MessageTreeWidgetItem* last_child_item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::lastChild(parent_item));843 844 if (last_child_item != item)845 break;846 847 item = parent_item;848 849 parent_item = static_cast<MessageTreeWidgetItem*>(item->parent());850 }851 852 // сдвиг на следующего брата в соседней подветке853 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item));854 }855 else856 item = sibling_item;857 }858 }859 860 // если достигнут конец дерева, то переходим в корень861 if (item == NULL)862 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0));863 864 info = item->pag();865 866 // если найденый топик с незагруженной информацией867 if (info->IsInfoLoaded == false)868 {869 if (loopback == true)870 return;871 872 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0));873 info = item->pag();874 875 loopback = true;876 }877 878 if (info->IsRead == false)879 break;880 }881 882 setCurrentItem(item);883 884 scrollToItem(item, QAbstractItemView::PositionAtCenter);885 }886 //----------------------------------------------------------------------------------------------887 888 1878 void AMessageTree::gotoNextUnreadArticle () 889 1879 { … … 892 1882 //---------------------------------------------------------------------------------------------- 893 1883 894 void AMessageTree::gotoNextUnreadThread () 895 { 896 AMessageInfoGUI* info = NULL; 897 898 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 899 900 // если не было выделения, то ищем следующую непрочитанную статью (она будет первой) 901 if (item == NULL) 902 { 903 gotoNextUnreadArticle(NULL); 904 return; 905 } 906 907 // item установлен на топик 908 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 909 info = item->pag(); 910 911 // флаг петли 912 bool loopback = false; 913 914 // поиск следующего топика с непрочитанными сообщениями 915 while (true) 916 { 917 // следующий топик за текущим 918 item = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::nextSibling(item)); 919 920 // если достигнут конец дерева, то переходим в корень 921 if (item == NULL) 922 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 923 924 info = item->pag(); 925 926 // если найденый топик с незагруженной информацией 927 if (info->IsInfoLoaded == false) 928 { 929 if (loopback == true) 930 return; 931 932 item = static_cast<MessageTreeWidgetItem*>(topLevelItem(0)); 933 info = item->pag(); 934 935 loopback = true; 936 } 937 938 if (info->IsRead == false) 939 break; 940 941 if (info->HasUnreadChild == true) 942 { 943 gotoNextUnreadArticle(item); 944 return; 945 } 946 } 947 948 setCurrentItem(item); 949 950 scrollToItem(item, QAbstractItemView::PositionAtCenter); 951 } 952 //---------------------------------------------------------------------------------------------- 953 954 void AMessageTree::menu_mark_message_as_read_triggered () 955 { 956 QTreeWidgetItem* item = currentItem(); 957 958 if (item == NULL) 959 return; 960 961 markItemAsRead(item, true); 962 } 963 //---------------------------------------------------------------------------------------------- 964 965 void AMessageTree::menu_mark_message_as_unread_triggered () 966 { 967 QTreeWidgetItem* item = currentItem(); 968 969 if (item == NULL) 970 return; 971 972 markItemAsRead(item, false); 973 } 974 //---------------------------------------------------------------------------------------------- 975 976 void AMessageTree::timer_on_timer () 977 { 978 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(currentItem()); 979 980 if (item != NULL) 981 markItemAsRead(item, true); 982 } 983 //---------------------------------------------------------------------------------------------- 984 985 void AMessageTree::markItemAsRead (QTreeWidgetItem* widget_item, bool is_read) 986 { 987 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 1884 1885 AMessageInfoGUI* AMessageTree::createItem () 1886 { 1887 MessageTreeWidgetItem* item = new MessageTreeWidgetItem(); 988 1888 989 1889 AMessageInfoGUI* info = item->pag(); 990 1890 991 // если уже прочитан 992 if (info->IsRead == is_read) 993 return; 994 995 // пометить как прочитанное в хранилище 996 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 997 998 if (storage.get() == NULL) 999 { 1000 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1001 return; 1002 } 1003 1004 if (storage->setIDsAsRead(QList<int>() << info->ID, idsMessage, is_read, QDateTime(), NULL) == false) 1005 { 1006 storage->showError(m_parent); 1007 return; 1008 } 1009 1010 // установка флага как прочитанного и пометка в дереве 1891 info->Item = item; 1892 1893 return info; 1894 } 1895 //---------------------------------------------------------------------------------------------- 1896 1897 void AMessageTree::markThreadAsRead (QTreeWidgetItem* parent, bool is_read, int& count) 1898 { 1899 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(parent); 1900 1901 AMessageInfoGUI* info = item->pag(); 1902 1903 if (info->IsRead != is_read) 1904 count++; 1905 1011 1906 info->IsRead = is_read; 1012 1907 1013 1908 if (is_read == true) 1014 1909 { 1015 // установка иконки помечаемому сообщению 1016 if (info->HasUnreadChildMy) 1017 item->setIcon(0, m_child_unread_my); 1018 else if (info->HasUnreadChild) 1019 item->setIcon(0, m_child_unread); 1020 else 1021 item->setIcon(0, m_message_read); 1022 1023 // флаг того, что это было сообщение для меня 1024 bool message_to_me = false; 1025 1026 // установка флагов и иконок у родительских сообщений 1027 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(item->parent()); 1028 1029 if (item_parent != NULL && item_parent->pag()->IDUser == m_me.ID) 1030 message_to_me = true; 1031 1032 while (item_parent != NULL) 1033 { 1034 AMessageInfoGUI* info_parent = item_parent->pag(); 1035 1036 int old_unread_count = info_parent->UnreadChildCount; 1037 int old_unread_count_my = info_parent->UnreadChildCountMy; 1038 1039 // уменьшение количества непрочитанных дочерних 1040 // и установка соответствующих флагов 1041 if (info_parent->UnreadChildCount > 0) 1042 info_parent->UnreadChildCount--; 1043 1044 if (message_to_me == true && info_parent->UnreadChildCountMy > 0) 1045 info_parent->UnreadChildCountMy--; 1046 1047 if (info_parent->UnreadChildCountMy == 0) 1048 info_parent->HasUnreadChildMy = false; 1049 1050 if (info_parent->UnreadChildCount == 0) 1051 info_parent->HasUnreadChild = false; 1052 1053 // установка иконок 1054 if (info_parent->IsRead == false) 1055 { 1056 // родитель непрочитан 1057 1058 // если среди дочерних прочитали дочернее мне и больше непрочитанных дочерних мне нет 1059 // и должна произойти смена иконки 1060 if (old_unread_count_my != 0 && info_parent->UnreadChildCountMy == 0) 1061 item_parent->setIcon(0, m_message_unread); 1062 } 1063 else 1064 { 1065 // родитель прочитан 1066 1067 // если среди дочерних есть непрочитанные мне 1068 // и должна произойти смена иконки 1069 if (old_unread_count_my != info_parent->UnreadChildCountMy && info_parent->UnreadChildCountMy > 0) 1070 item_parent->setIcon(0, m_child_unread_my); 1071 1072 // если среди дочерних есть непрочитанные 1073 // и должна произойти смена иконки 1074 else if (old_unread_count != info_parent->UnreadChildCount && info_parent->UnreadChildCount > 0) 1075 item_parent->setIcon(0, m_child_unread); 1076 1077 // нет дочерних непрочитанных 1078 else 1079 item_parent->setIcon(0, m_message_read); 1080 } 1081 1082 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 1083 } 1084 1085 // уменьшение количества непрочитанных в дереве форума 1086 m_forum_tree->changeUnreadCount(-1); 1087 } 1088 else // if (is_read == true) 1089 { 1090 // TODO: Доделать пометку родителей, если отметилось сообщение, которое является ответом мне 1091 1092 // установка иконки помечаемому сообщению 1093 item->setIcon(0, m_message_unread); 1094 1095 // установка флагов и иконок у родительских сообщений 1096 MessageTreeWidgetItem* parent_item = static_cast<MessageTreeWidgetItem*>(item->parent()); 1097 1098 while (parent_item != NULL) 1099 { 1100 AMessageInfoGUI* parent_info = parent_item->pag(); 1101 1102 // смена иконки при необходимости 1103 if (parent_info->IsRead == true && parent_info->HasUnreadChild == false) 1104 parent_item->setIcon(0, m_child_unread); 1105 1106 parent_info->UnreadChildCount++; 1107 parent_info->HasUnreadChild = true; 1108 1109 parent_item = static_cast<MessageTreeWidgetItem*>(parent_item->parent()); 1110 } 1111 1112 // увеличение количества непрочитанных в дереве форума 1113 m_forum_tree->changeUnreadCount(1); 1114 1115 } // if (is_read == true) ... else 1116 } 1117 //---------------------------------------------------------------------------------------------- 1118 1119 AMessageInfoGUI* AMessageTree::createItem () 1120 { 1121 MessageTreeWidgetItem* item = new MessageTreeWidgetItem(); 1122 1123 AMessageInfoGUI* info = item->pag(); 1124 1125 info->Item = item; 1126 1127 return info; 1128 } 1129 //---------------------------------------------------------------------------------------------- 1130 1131 void AMessageTree::changeForum (const AForumInfo* forum_info) 1132 { 1133 // 1134 // базовая очистка 1135 // 1136 1137 m_current_forum.ID = 0; 1138 m_current_forum.IDGroup = 0; 1139 m_current_forum.ShortName = ""; 1140 m_current_forum.Name = ""; 1141 m_current_forum.Rated = false; 1142 m_current_forum.InTop = false; 1143 m_current_forum.RateLimit = 0; 1144 1145 m_me.ID = 0; 1146 m_me.Name = ""; 1147 m_me.Nick = ""; 1148 m_me.RealName = ""; 1149 m_me.Email = ""; 1150 m_me.Homepage = ""; 1151 m_me.Specialization = ""; 1152 m_me.WhereFrom = ""; 1153 m_me.Origin = ""; 1154 1155 if (m_main_form != NULL) 1156 m_main_form->setEnabledAction(aaViewSource, false); 1157 1158 clear(); 1159 1160 m_message_view->clear(); 1161 1162 scrollToTop(); 1163 1164 // если выделена группа, то просто очистка 1165 if (forum_info == NULL) 1166 { 1167 headerItem()->setText(0, QString::fromUtf8("тема")); 1168 1169 QFont font = headerItem()->font(0); 1170 font.setBold(false); 1171 headerItem()->setFont(0, font); 1172 1173 return; 1174 } 1175 1176 // 1177 // есть форум для отображения 1178 // 1179 1180 m_current_forum.ID = forum_info->ID; 1181 m_current_forum.IDGroup = forum_info->IDGroup; 1182 m_current_forum.ShortName = forum_info->ShortName; 1183 m_current_forum.Name = forum_info->Name; 1184 m_current_forum.Rated = forum_info->Rated; 1185 m_current_forum.InTop = forum_info->InTop; 1186 m_current_forum.RateLimit = forum_info->RateLimit; 1187 1188 // вывод наименования форума в хедер 1189 headerItem()->setText(0, m_current_forum.Name); 1190 1191 // 1192 // загрузка топиков в зависимости от типа форума 1193 // 1194 1195 // получение хранилища 1196 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1197 1198 if (storage.get() == NULL) 1199 { 1200 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1201 return; 1202 } 1203 1204 // получение информации о себе 1205 // TODO: вынести в AGlobal 1206 QSettings settings; 1207 1208 m_me.Name = settings.value("rsdn/login", "").toString(); 1209 1210 if (storage->whoAmI(m_me, NULL) == false) 1211 m_me.Name = ""; 1212 1213 // если группа форумов обыкновенная 1214 if (m_current_forum.IDGroup != SPECIAL_ID_GROUP) 1215 { 1216 // получение топиков 1217 // ориентировочное время выполнения 68 ms (для форума NET, 28199 топиков) 1218 // основное время занимает запрос данных из хранилища 1219 QList<int> topic_list; 1220 1221 if (storage->getForumTopicList(m_current_forum.ID, AGlobal::getInstance()->MaxTopicToShow, topic_list, NULL) == false) 1222 { 1223 storage->showError(m_parent); 1224 return; 1225 } 1226 1227 // установка топиков 1228 // ориентировочное время выполнения 50 ms (для форума NET, 28199 топиков) 1229 // основное время занимает создание объекта MessageTreeWidgetItem 1230 QList<QTreeWidgetItem*> items; 1231 1232 for (int i = 0; i < topic_list.count(); i++) 1233 { 1234 // начальное заполнение дескриптора топика 1235 AMessageInfoGUI* info = createItem(); 1236 1237 info->ID = topic_list[i]; 1238 1239 items.append(info->Item); 1240 } 1241 1242 // отображение на виджет 1243 addTopLevelItems(items); 1244 1245 // дозагрузка информации о топиках, находящихся в видимой области отображения 1246 scrollTopics(); 1247 } 1248 else // if (forum_info->IDGroup != SPECIAL_ID_GROUP) 1249 { 1250 } 1251 } 1252 //---------------------------------------------------------------------------------------------- 1253 1254 void AMessageTree::scrollTopics () 1255 { 1256 // Среднее время выполнения для дозагрузки одного элемента 5 ms 1257 // Среднее время выполнения для дозагрузки страницы из 56 топиков (полный экран 1280х1024) 32 ms 1258 1259 // пустой форум или спец-группа 1260 if (m_current_forum.ID == 0 || m_current_forum.IDGroup == SPECIAL_ID_GROUP) 1261 return; 1262 1263 // 1264 // Определение диапазона возможной подгрузки данных 1265 // 1266 1267 // поиск корня верхнего видимого элемента в отображении 1268 QTreeWidgetItem* top_item = itemAt(1, 1); 1269 1270 if (top_item == NULL) 1271 return; // нет элементов в дереве(?) 1272 1273 top_item = ATreeWidgetItem::rootItem(top_item); 1274 1275 int top_index = indexOfTopLevelItem(top_item); 1276 1277 // поиск корня нижнего видимого элемента в отображении 1278 QTreeWidgetItem* bottom_item = itemAt(1, height() - 1); 1279 1280 int bottom_index; 1281 1282 if (bottom_item == NULL) 1283 bottom_index = topLevelItemCount(); 1284 else 1285 { 1286 bottom_item = ATreeWidgetItem::rootItem(bottom_item); 1287 1288 bottom_index = indexOfTopLevelItem(bottom_item) + 1; 1289 } 1290 1291 // 1292 // Поиск еще не загруженных топиков в диапазоне 1293 // 1294 1295 AMessageInfoGUIPtrList list; 1296 1297 while (top_index < bottom_index) 1298 { 1299 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(topLevelItem(top_index)); 1300 1301 AMessageInfoGUI* info = item->pag(); 1302 1303 if (info->IsInfoLoaded == false) 1304 list.append(info); 1305 1306 top_index++; 1307 } 1308 1309 // 1310 // загрузка топиков, которые не загружены 1311 // 1312 1313 if (list.count() == 0) 1314 return; 1315 1316 // получение хранилища 1317 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1318 1319 if (storage.get() == NULL) 1320 { 1321 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1322 return; 1323 } 1324 1325 if (storage->getTopicInfoList(m_current_forum.ID, list, m_me.ID, NULL) == false) 1326 { 1327 storage->showError(m_parent); 1328 return; 1329 } 1330 1331 AGlobal* global = AGlobal::getInstance(); 1332 1333 // 1334 // Установка загруженой информации 1335 // 1336 1337 for (int i = 0; i < list.count(); i++) 1338 { 1339 AMessageInfoGUI* info = list[i]; 1340 1341 info->IsInfoLoaded = true; 1342 info->UnreadChildCount = 0; 1343 info->UnreadChildCountMy = 0; 1344 1345 info->Item->setText(0, info->Subject); 1346 1347 // TODO: сделать общую функцию формирования имени/ника 1348 if (info->IDUser == 0) 1349 info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 1350 else 1351 info->Item->setText(1, info->UserNick); 1352 1353 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 1354 1355 if (info->HasChild == true) 1356 info->Item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); 1357 1358 if (info->IsRead == true) 1359 { 1360 if (info->HasUnreadChildMy) 1361 info->Item->setIcon(0, m_child_unread_my); 1362 else if (info->HasUnreadChild) 1363 info->Item->setIcon(0, m_child_unread); 1364 else 1365 info->Item->setIcon(0, m_message_read); 1366 } 1367 else 1368 { 1369 if (info->HasUnreadChildMy) 1370 info->Item->setIcon(0, m_message_unread_my); 1371 else 1372 info->Item->setIcon(0, m_message_unread); 1373 } 1374 } 1375 } 1376 //---------------------------------------------------------------------------------------------- 1377 1378 void AMessageTree::expand_item (QTreeWidgetItem* item_expanded) 1379 { 1380 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(item_expanded); 1381 1382 AMessageInfoGUI* info = item->pag(); 1383 1384 // если дочерние сообщения не загружены (а это может быть только для топика в текущей реализации) 1385 if (info->HasChild == true && info->IsChildLoaded == false) 1386 { 1387 // получение хранилища 1388 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1389 1390 if (storage.get() == NULL) 1391 { 1392 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1393 return; 1394 } 1395 1396 // заполнение списка сообщений 1397 // ориентировочное время выполнения 111 ms (для топика 279396 - 5149 сообщений) 1398 // основное время занимает присвоение данных полям (преобразование из QVariant в QSqlQuery) 1399 AMessageInfoGUIPtrList list; 1400 1401 if (storage->getTopicMessageList(m_current_forum.ID, info->ID, list, this, NULL) == false) 1402 { 1403 storage->showError(m_parent); 1404 return; 1405 } 1406 1407 // постройка дерева, обход в ширину быстрее чем в высоту 1408 // ориентировочное время выполнения 900 ms (для топика 279396 - 5149 сообщений) 1409 // наиболее высокое дерево составляет 1555 сообщений (для топика 1099540) 1410 // наиболее широкое дерево (глубина рекурсии) пока неизвестно 1411 buildTree(info, &list); 1412 1413 // для предотвращения повторной загрузки 1414 info->IsChildLoaded = true; 1415 1416 // раскрытие дерева до уровня непрочитаных топиков 1417 if (info->UnreadChildCount != 0) 1418 expandUnreadChild(item); 1419 } 1420 } 1421 //---------------------------------------------------------------------------------------------- 1422 1423 void AMessageTree::buildTree (AMessageInfoGUI* root, AMessageInfoGUIPtrList* list) 1424 { 1425 if (list->count() == 0) 1426 return; 1427 1428 int list_index = 0; 1429 1430 AGlobal* global = AGlobal::getInstance(); 1431 1432 while (list_index < list->count()) 1433 { 1434 AMessageInfoGUI* info = list->at(list_index); 1435 1436 if (info->IDParent == root->ID) 1437 { 1438 list->removeAt(list_index); 1439 1440 info->IsInfoLoaded = true; 1441 info->IsChildLoaded = true; 1442 info->UnreadChildCount = 0; 1443 info->UnreadChildCountMy = 0; 1444 1445 info->Item->setText(0, info->Subject); 1446 1447 // TODO: сделать общую функцию формирования имени/ника 1448 if (info->IDUser != 0) 1449 info->Item->setText(1, info->UserNick); 1450 else 1451 info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 1452 1453 info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 1454 1455 root->Item->addChild(info->Item); 1456 1457 // установка родителям свойств непрочитанных сообщений 1458 if (info->IsRead == false && root->IDUser == m_me.ID) 1459 { 1460 // сообщение не прочитано и это ответ не мне 1461 info->Item->setIcon(0, m_message_unread_my); 1462 1463 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 1464 1465 while (item_parent != NULL) 1466 { 1467 AMessageInfoGUI* info_parent = item_parent->pag(); 1468 1469 if (info_parent->HasUnreadChildMy != true) 1470 { 1471 info_parent->HasUnreadChild = true; 1472 info_parent->HasUnreadChildMy = true; 1473 1474 if (info_parent->IsRead == true) 1475 item_parent->setIcon(0, m_child_unread_my); 1476 else 1477 item_parent->setIcon(0, m_message_unread_my); 1478 } 1479 1480 info_parent->UnreadChildCount++; 1481 info_parent->UnreadChildCountMy++; 1482 1483 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 1484 1485 } // while (item_parent != NULL) 1486 } 1487 else if (info->IsRead == false) 1488 { 1489 // сообщение не прочитано, но это ответ не мне 1490 info->Item->setIcon(0, m_message_unread); 1491 1492 MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 1493 1494 while (item_parent != NULL) 1495 { 1496 AMessageInfoGUI* info_parent = item_parent->pag(); 1497 1498 if (info_parent->HasUnreadChild != true) 1499 { 1500 info_parent->HasUnreadChild = true; 1501 1502 if (info_parent->IsRead == true) 1503 item_parent->setIcon(0, m_child_unread); 1504 } 1505 1506 info_parent->UnreadChildCount++; 1507 1508 item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 1509 1510 } // while (item_parent != NULL) 1511 } 1512 else // else if (info->IsRead == false) 1513 { 1514 // сообщение прочитано 1515 info->Item->setIcon(0, m_message_read); 1516 } 1517 1518 // достройка дочерних веток для текущей 1519 if (info->HasChild) 1520 { 1521 buildTree(info, list); 1522 list_index = 0; 1523 } 1524 } 1525 else // if (info->ID == id_parent) 1526 { 1527 list_index++; 1528 } 1529 } 1530 } 1531 //---------------------------------------------------------------------------------------------- 1532 1533 void AMessageTree::expandUnreadChild (QTreeWidgetItem* widget_item) 1534 { 1535 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 1536 1537 if (item->pag()->UnreadChildCount != 0) 1538 { 1539 for (int i = 0; i < item->childCount(); i++) 1540 if (((MessageTreeWidgetItem*)item->child(i))->pag()->UnreadChildCount != 0) 1541 expandUnreadChild(item->child(i)); 1542 1543 expandItem(item); 1544 } 1545 } 1546 //---------------------------------------------------------------------------------------------- 1547 1548 bool AMessageTree::markThreadAsRead (int id, bool is_read) 1549 { 1550 std::auto_ptr<IAStorage> storage(AStorageFactory::getStorage()); 1551 1552 if (storage.get() == NULL) 1553 { 1554 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 1555 return false; 1556 } 1557 1558 if (storage->setIDsAsRead(QList<int>() << id, idsTopic, is_read, QDateTime(), NULL) == false) 1559 { 1560 storage->showError(m_parent); 1561 return false; 1562 } 1563 1564 return true; 1565 } 1566 //---------------------------------------------------------------------------------------------- 1567 1568 void AMessageTree::menu_mark_thread_as_read_triggered () 1569 { 1570 QTreeWidgetItem* item = currentItem(); 1571 1572 if (item == NULL) 1573 return; 1574 1575 // поиск родителя 1576 MessageTreeWidgetItem* parent = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 1577 1578 AMessageInfoGUI* info = parent->pag(); 1579 1580 // пометка в хранилище 1581 if (markThreadAsRead(info->ID, true) != true) 1582 return; 1583 1584 // пометка в дереве 1585 if (info->IsChildLoaded == true) 1586 { 1587 int count = 0; 1588 1589 markThreadAsRead(parent, true, count); 1590 1591 m_forum_tree->changeUnreadCount(-count); 1592 } 1593 else 1594 { 1595 parent->setIcon(0, m_message_read); 1596 1597 AMessageInfoGUI* info = parent->pag(); 1910 item->setIcon(0, m_message_read); 1598 1911 1599 1912 info->HasUnreadChild = false; … … 1602 1915 info->UnreadChildCountMy = 0; 1603 1916 1604 // поскольку дочерние элементы еще не загружены, 1605 // обновление количества непрочитаных в дереве форума 1606 m_forum_tree->reloadUnread(false); 1607 } 1608 } 1609 //---------------------------------------------------------------------------------------------- 1610 1611 void AMessageTree::menu_mark_thread_as_unread_triggered () 1612 { 1613 QTreeWidgetItem* item = currentItem(); 1614 1615 if (item == NULL) 1616 return; 1617 1618 // поиск родителя 1619 MessageTreeWidgetItem* parent = static_cast<MessageTreeWidgetItem*>(ATreeWidgetItem::rootItem(item)); 1620 1621 AMessageInfoGUI* info = parent->pag(); 1622 1623 // пометка в хранилище 1624 if (markThreadAsRead(info->ID, false) != true) 1625 return; 1626 1627 // пометка в дереве 1628 if (info->IsChildLoaded == true) 1629 { 1630 int count = 0; 1631 1632 markThreadAsRead(parent, false, count); 1633 1634 m_forum_tree->changeUnreadCount(count); 1635 } 1636 else 1637 { 1638 parent->setIcon(0, m_message_unread); 1639 1640 AMessageInfoGUI* info = parent->pag(); 1641 1642 if (info->HasChild == true) 1917 for (int i = 0; i < item->childCount(); i++) 1918 markThreadAsRead(item->child(i), is_read, count); 1919 } 1920 else // if (is_read == true) 1921 { 1922 item->setIcon(0, m_message_unread); 1923 1924 info->HasUnreadChild = false; 1925 info->HasUnreadChildMy = false; 1926 info->UnreadChildCount = 0; 1927 info->UnreadChildCountMy = 0; 1928 1929 MessageTreeWidgetItem* parent = static_cast<MessageTreeWidgetItem*>(item->parent()); 1930 1931 while (parent != NULL) 1932 { 1933 info = parent->pag(); 1934 1643 1935 info->HasUnreadChild = true; 1644 else 1645 info->HasUnreadChild = false; 1646 1647 info->HasUnreadChildMy = false; 1648 1649 // поскольку дочерние элементы еще не загружены, 1650 // обновление количества непрочитаных в дереве форума 1651 m_forum_tree->reloadUnread(false); 1652 } 1653 } 1654 //---------------------------------------------------------------------------------------------- 1655 1656 void AMessageTree::markThreadAsRead (QTreeWidgetItem* parent, bool is_read, int& count) 1657 { 1658 } 1659 //---------------------------------------------------------------------------------------------- 1936 info->UnreadChildCount++; 1937 1938 parent = static_cast<MessageTreeWidgetItem*>(parent->parent()); 1939 } 1940 1941 for (int i = 0; i < item->childCount(); i++) 1942 markThreadAsRead(item->child(i), is_read, count); 1943 1944 } // if (is_read == true) ... else 1945 } 1946 //---------------------------------------------------------------------------------------------- -
branches/message_tree/message_tree.h
r189 r190 200 200 bool markThreadAsRead (int id, bool is_read); 201 201 202 /*! 203 * \brief Загрузить сообщения к отправке 204 */ 205 void loadMessage2Send (); 206 207 /*! 208 * \brief Загрузить рейтинги к отправке 209 */ 210 void loadRating2Send (); 211 212 /*! 213 * \brief Загрузить модерилки к отправке 214 */ 215 void loadModerate2Send (); 216 202 217 // IMessageTree 203 218 public: -
branches/message_tree/version.h
r189 r190 20 20 * \brief Дата билда (заменяется автоматически при каждом билде в version.h, что и приводит к смене номера ревизии) 21 21 */ 22 #define AVALON_DATE " Птн Мар 27 20:01:36MSK 2009"22 #define AVALON_DATE "Сбт Мар 28 03:12:39 MSK 2009" 23 23 24 24 #endif
Note: See TracChangeset
for help on using the changeset viewer.
