diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-02-07 21:48:40 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-04-08 18:46:46 +0100 |
commit | 5ac0166388ac9a493491a30fbc3570f23950dc51 (patch) | |
tree | 8fe2019a8d3376042d1f92b7a2127bd73d3c97e3 /utils/regtools/qeditor/utils.cpp | |
parent | cc4c9b70bcac048fc388d0f553b7621f52449526 (diff) | |
download | rockbox-5ac0166388ac9a493491a30fbc3570f23950dc51.tar.gz rockbox-5ac0166388ac9a493491a30fbc3570f23950dc51.zip |
qeditor: port to the new hwstub library and add features
This commit adds support for the version of the hwstub library, which requires
a lot of changes. It also adds some editing features, such as register access
and much better editing of fields using the mouse (double click on a field
to be able to resize and move it).
Change-Id: I3c4e4cc855cb44911c72bc8127bad841b68efe52
Diffstat (limited to 'utils/regtools/qeditor/utils.cpp')
-rw-r--r-- | utils/regtools/qeditor/utils.cpp | 594 |
1 files changed, 527 insertions, 67 deletions
diff --git a/utils/regtools/qeditor/utils.cpp b/utils/regtools/qeditor/utils.cpp index 0d0a7de5ed..748a989512 100644 --- a/utils/regtools/qeditor/utils.cpp +++ b/utils/regtools/qeditor/utils.cpp | |||
@@ -30,6 +30,9 @@ | |||
30 | #include <QXmlStreamWriter> | 30 | #include <QXmlStreamWriter> |
31 | #include <QTextBlock> | 31 | #include <QTextBlock> |
32 | #include <QApplication> | 32 | #include <QApplication> |
33 | #include <QPushButton> | ||
34 | #include <QMessageBox> | ||
35 | #include <QStandardItemModel> | ||
33 | 36 | ||
34 | /** | 37 | /** |
35 | * SocBitRangeValidator | 38 | * SocBitRangeValidator |
@@ -406,6 +409,11 @@ bool SocFieldBitRange::operator<(const SocFieldBitRange& o) const | |||
406 | return m_last_bit < o.m_last_bit; | 409 | return m_last_bit < o.m_last_bit; |
407 | } | 410 | } |
408 | 411 | ||
412 | bool SocFieldBitRange::operator!=(const SocFieldBitRange& o) const | ||
413 | { | ||
414 | return m_first_bit != o.m_first_bit || m_last_bit != o.m_last_bit; | ||
415 | } | ||
416 | |||
409 | /** | 417 | /** |
410 | * SocFieldCachedItemDelegate | 418 | * SocFieldCachedItemDelegate |
411 | */ | 419 | */ |
@@ -476,6 +484,53 @@ void SocFieldCachedEditor::setValue(SocFieldCachedValue val) | |||
476 | } | 484 | } |
477 | 485 | ||
478 | /** | 486 | /** |
487 | * SocAccessItemDelegate | ||
488 | */ | ||
489 | QString SocAccessItemDelegate::displayText(const QVariant& value, const QLocale& locale) const | ||
490 | { | ||
491 | if(isUserType< soc_desc::access_t >(value)) | ||
492 | { | ||
493 | soc_desc::access_t acc = value.value< soc_desc::access_t >(); | ||
494 | switch(acc) | ||
495 | { | ||
496 | case soc_desc::UNSPECIFIED: return m_unspec_text; | ||
497 | case soc_desc::READ_ONLY: return "Read-Only"; | ||
498 | case soc_desc::READ_WRITE: return "Read-Write"; | ||
499 | case soc_desc::WRITE_ONLY: return "Write-Only"; | ||
500 | default: return "<bug>"; | ||
501 | } | ||
502 | } | ||
503 | else | ||
504 | return QStyledItemDelegate::displayText(value, locale); | ||
505 | } | ||
506 | |||
507 | /** | ||
508 | * SocAccessEditor | ||
509 | */ | ||
510 | SocAccessEditor::SocAccessEditor(const QString& unspec_text, QWidget *parent) | ||
511 | :QComboBox(parent) | ||
512 | { | ||
513 | addItem(unspec_text, QVariant::fromValue(soc_desc::UNSPECIFIED)); | ||
514 | addItem("Read-Only", QVariant::fromValue(soc_desc::READ_ONLY)); | ||
515 | addItem("Read-Write", QVariant::fromValue(soc_desc::READ_WRITE)); | ||
516 | addItem("Write-Only", QVariant::fromValue(soc_desc::WRITE_ONLY)); | ||
517 | } | ||
518 | |||
519 | SocAccessEditor::~SocAccessEditor() | ||
520 | { | ||
521 | } | ||
522 | |||
523 | soc_desc::access_t SocAccessEditor::access() const | ||
524 | { | ||
525 | return itemData(currentIndex()).value< soc_desc::access_t >(); | ||
526 | } | ||
527 | |||
528 | void SocAccessEditor::setAccess(soc_desc::access_t acc) | ||
529 | { | ||
530 | setCurrentIndex(findData(QVariant::fromValue(acc))); | ||
531 | } | ||
532 | |||
533 | /** | ||
479 | * SocFieldEditorCreator | 534 | * SocFieldEditorCreator |
480 | */ | 535 | */ |
481 | QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const | 536 | QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const |
@@ -494,6 +549,19 @@ void SocFieldEditorCreator::setWidth(int bitcount) | |||
494 | } | 549 | } |
495 | 550 | ||
496 | /** | 551 | /** |
552 | * SocAccessEditorCreator | ||
553 | */ | ||
554 | QWidget *SocAccessEditorCreator::createWidget(QWidget *parent) const | ||
555 | { | ||
556 | return new SocAccessEditor(m_unspec_text, parent); | ||
557 | } | ||
558 | |||
559 | QByteArray SocAccessEditorCreator::valuePropertyName() const | ||
560 | { | ||
561 | return QByteArray("access"); | ||
562 | } | ||
563 | |||
564 | /** | ||
497 | * SocFieldCachedEditorCreator | 565 | * SocFieldCachedEditorCreator |
498 | */ | 566 | */ |
499 | QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const | 567 | QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const |
@@ -602,8 +670,22 @@ bool RegFieldTableModel::setData(const QModelIndex& idx, const QVariant& value, | |||
602 | if(role != Qt::EditRole) | 670 | if(role != Qt::EditRole) |
603 | return false; | 671 | return false; |
604 | int section = idx.column(); | 672 | int section = idx.column(); |
673 | if(section == BitRangeColumn) | ||
674 | { | ||
675 | if(idx.row() < 0 || idx.row() >= rowCount()) | ||
676 | return false; | ||
677 | if(value.type() != QVariant::UserType && value.userType() == qMetaTypeId< SocFieldBitRange >()) | ||
678 | return false; | ||
679 | SocFieldBitRange bitrange = value.value< SocFieldBitRange >(); | ||
680 | m_reg.field[idx.row()].pos = bitrange.GetFirstBit(); | ||
681 | m_reg.field[idx.row()].width = bitrange.GetLastBit() - bitrange.GetFirstBit() + 1; | ||
682 | emit OnBitrangeModified(idx.row()); | ||
683 | } | ||
605 | if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size()) | 684 | if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size()) |
685 | { | ||
686 | qDebug() << "ignore setData to column " << section; | ||
606 | return false; | 687 | return false; |
688 | } | ||
607 | section -= FirstValueColumn; | 689 | section -= FirstValueColumn; |
608 | const SocFieldCachedValue& v = value.value< SocFieldCachedValue >(); | 690 | const SocFieldCachedValue& v = value.value< SocFieldCachedValue >(); |
609 | if(!m_value[section].isValid()) | 691 | if(!m_value[section].isValid()) |
@@ -622,7 +704,12 @@ Qt::ItemFlags RegFieldTableModel::flags(const QModelIndex& index) const | |||
622 | Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; | 704 | Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; |
623 | int section = index.column(); | 705 | int section = index.column(); |
624 | if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size()) | 706 | if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size()) |
707 | { | ||
708 | /* bitrange or name */ | ||
709 | if(!m_read_only) | ||
710 | flags |= Qt::ItemIsEditable; | ||
625 | return flags; | 711 | return flags; |
712 | } | ||
626 | section -= FirstValueColumn; | 713 | section -= FirstValueColumn; |
627 | if(m_value[section].isValid() && !m_read_only) | 714 | if(m_value[section].isValid() && !m_read_only) |
628 | flags |= Qt::ItemIsEditable; | 715 | flags |= Qt::ItemIsEditable; |
@@ -764,6 +851,207 @@ bool RegFieldProxyModel::lessThan(const QModelIndex& left, | |||
764 | } | 851 | } |
765 | 852 | ||
766 | /** | 853 | /** |
854 | * YRegDisplayItemEditor | ||
855 | */ | ||
856 | YRegDisplayItemEditor::YRegDisplayItemEditor(QWidget *parent, YRegDisplay *display, | ||
857 | YRegDisplayItemDelegate *delegate, QModelIndex bitrange_index, | ||
858 | QModelIndex name_index) | ||
859 | :QWidget(parent), m_display_delegate(delegate), | ||
860 | m_display(display), m_state(Idle) | ||
861 | { | ||
862 | m_col_width = m_display->BitrangeRect(SocFieldBitRange(0, 0)).width(); | ||
863 | m_resize_margin = m_col_width / 4; | ||
864 | setEditorData(bitrange_index, name_index); | ||
865 | setMouseTracking(true); | ||
866 | setAutoFillBackground(true); | ||
867 | setFocusPolicy(Qt::StrongFocus); // QItemDelegate says it's important | ||
868 | } | ||
869 | |||
870 | void YRegDisplayItemEditor::setEditorData(QModelIndex bitrange_index, QModelIndex name_index) | ||
871 | { | ||
872 | if(m_state != Idle) | ||
873 | { | ||
874 | m_state = Idle; | ||
875 | QApplication::restoreOverrideCursor(); | ||
876 | } | ||
877 | m_bitrange_index = bitrange_index; | ||
878 | m_name_index = name_index; | ||
879 | m_bitrange = bitrange_index.data().value< SocFieldBitRange >(); | ||
880 | } | ||
881 | |||
882 | void YRegDisplayItemEditor::getEditorData(QVariant& name, QVariant& bitrange) | ||
883 | { | ||
884 | name = QVariant(); /* don't touch the name */ | ||
885 | bitrange = QVariant::fromValue(m_bitrange); | ||
886 | } | ||
887 | |||
888 | YRegDisplayItemEditor::~YRegDisplayItemEditor() | ||
889 | { | ||
890 | /* make sure to restore cursor if modified */ | ||
891 | if(m_state != Idle) | ||
892 | { | ||
893 | m_state = Idle; | ||
894 | QApplication::restoreOverrideCursor(); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | YRegDisplayItemEditor::Zone YRegDisplayItemEditor::GetZone(const QPoint& pt) | ||
899 | { | ||
900 | if(!rect().contains(pt)) | ||
901 | return NoZone; | ||
902 | if(pt.x() >= 0 && pt.x() <= m_resize_margin) | ||
903 | return ResizeLeftZone; | ||
904 | if(pt.x() >= width() - m_resize_margin && pt.x() <= width()) | ||
905 | return ResizeRightZone; | ||
906 | return MoveZone; | ||
907 | } | ||
908 | |||
909 | void YRegDisplayItemEditor::mouseMoveEvent(QMouseEvent *event) | ||
910 | { | ||
911 | Zone zone = GetZone(event->pos()); | ||
912 | bool in_resize_zone = (zone == ResizeLeftZone || zone == ResizeRightZone); | ||
913 | /* resizing/moving has priority */ | ||
914 | if(m_state == ResizingLeft || m_state == ResizingRight || m_state == Moving) | ||
915 | { | ||
916 | SocFieldBitRange new_bitrange = m_bitrange; | ||
917 | if(m_state == Moving) | ||
918 | { | ||
919 | /* Compute new bitrange: we know the offset of the mouse relative to the | ||
920 | * left of the register: use that offset to compute the new position of | ||
921 | * the MSB bit. To make it more natural, add half of a column of margin | ||
922 | * so that the register does not move until half of a bit column displacement | ||
923 | * was made */ | ||
924 | int bit = m_display->bitColumnAt(mapTo(m_display, | ||
925 | event->pos() - QPoint(m_move_offset - m_col_width / 2, 0))); | ||
926 | new_bitrange.SetLastBit(bit); | ||
927 | int w = m_bitrange.GetLastBit() - m_bitrange.GetFirstBit(); | ||
928 | /* make sure range is valid */ | ||
929 | if(bit - w < 0) | ||
930 | return; | ||
931 | new_bitrange.SetFirstBit(bit - w); | ||
932 | } | ||
933 | else | ||
934 | { | ||
935 | /* Compute new bitrange. To make it more natural, add quarter of a column of margin | ||
936 | * so that the register does not resize until quarter of a bit column displacement | ||
937 | * was made */ | ||
938 | int bit = m_display->bitColumnAt(mapTo(m_display, event->pos() | ||
939 | + QPoint(m_col_width / 4, 0))); | ||
940 | if(m_state == ResizingLeft) | ||
941 | new_bitrange.SetLastBit(bit); | ||
942 | else | ||
943 | new_bitrange.SetFirstBit(bit); | ||
944 | /* make sure range is valid */ | ||
945 | if(new_bitrange.GetLastBit() < new_bitrange.GetFirstBit()) | ||
946 | return; | ||
947 | } | ||
948 | /* make sure range does not overlap with other fields */ | ||
949 | /* TODO */ | ||
950 | /* update current bitrange (display only) and resize widget */ | ||
951 | if(m_bitrange != new_bitrange) | ||
952 | { | ||
953 | m_bitrange = new_bitrange; | ||
954 | /* resize widget */ | ||
955 | QRect rect = m_display->BitrangeRect(m_bitrange); | ||
956 | rect.moveTopLeft(parentWidget()->mapFromGlobal(m_display->mapToGlobal(rect.topLeft()))); | ||
957 | setGeometry(rect); | ||
958 | } | ||
959 | } | ||
960 | /* any zone -> resize zone */ | ||
961 | else if(in_resize_zone) | ||
962 | { | ||
963 | /* don't do unnecessary changes */ | ||
964 | if(m_state != InResizeZone) | ||
965 | { | ||
966 | /* restore old cursor if needed */ | ||
967 | if(m_state != Idle) | ||
968 | QApplication::restoreOverrideCursor(); | ||
969 | m_state = InResizeZone; | ||
970 | QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor)); | ||
971 | } | ||
972 | } | ||
973 | /* any zone -> move zone */ | ||
974 | else if(zone == MoveZone) | ||
975 | { | ||
976 | /* don't do unnecessary changes */ | ||
977 | if(m_state != InMoveZone) | ||
978 | { | ||
979 | /* restore old cursor if needed */ | ||
980 | if(m_state != Idle) | ||
981 | QApplication::restoreOverrideCursor(); | ||
982 | m_state = InMoveZone; | ||
983 | QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor)); | ||
984 | } | ||
985 | } | ||
986 | /* any zone -> no zone */ | ||
987 | else if(zone == NoZone) | ||
988 | { | ||
989 | if(m_state != Idle) | ||
990 | { | ||
991 | m_state = Idle; | ||
992 | QApplication::restoreOverrideCursor(); | ||
993 | } | ||
994 | } | ||
995 | } | ||
996 | |||
997 | void YRegDisplayItemEditor::leaveEvent(QEvent *event) | ||
998 | { | ||
999 | Q_UNUSED(event); | ||
1000 | if(m_state == InResizeZone) | ||
1001 | { | ||
1002 | m_state = Idle; | ||
1003 | QApplication::restoreOverrideCursor(); | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | void YRegDisplayItemEditor::mousePressEvent(QMouseEvent *event) | ||
1008 | { | ||
1009 | /* just in case the mouseMove event was not done */ | ||
1010 | mouseMoveEvent(event); | ||
1011 | /* we need to track mouse outside of widget but Qt already grabs the mouse | ||
1012 | * for us on mouse press in widget */ | ||
1013 | if(m_state == InResizeZone) | ||
1014 | { | ||
1015 | if(GetZone(event->pos()) == ResizeLeftZone) | ||
1016 | m_state = ResizingLeft; | ||
1017 | else | ||
1018 | m_state = ResizingRight; | ||
1019 | } | ||
1020 | else if(m_state == InMoveZone) | ||
1021 | { | ||
1022 | m_state = Moving; | ||
1023 | /* store offset from the left, to keep relative position of the register | ||
1024 | * with respect to the mouse */ | ||
1025 | m_move_offset = event->pos().x(); | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | void YRegDisplayItemEditor::mouseReleaseEvent(QMouseEvent *event) | ||
1030 | { | ||
1031 | if(m_state == ResizingLeft || m_state == ResizingRight || m_state == Moving) | ||
1032 | { | ||
1033 | QApplication::restoreOverrideCursor(); | ||
1034 | m_state = Idle; | ||
1035 | /* update cursor */ | ||
1036 | mouseMoveEvent(event); | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | void YRegDisplayItemEditor::paintEvent(QPaintEvent *event) | ||
1041 | { | ||
1042 | Q_UNUSED(event); | ||
1043 | QPainter painter(this); | ||
1044 | /* reuse delegate code to paint */ | ||
1045 | QStyleOptionViewItemV4 opt = m_display->viewOptions(); | ||
1046 | opt.state |= QStyle::State_HasFocus | QStyle::State_Selected | QStyle::State_Active; | ||
1047 | opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter; | ||
1048 | opt.rect = rect(); | ||
1049 | opt.showDecorationSelected = true; | ||
1050 | m_display_delegate->initStyleOption(&opt, m_name_index); | ||
1051 | m_display_delegate->MyPaint(&painter, opt); | ||
1052 | } | ||
1053 | |||
1054 | /** | ||
767 | * YRegDisplayItemDelegate | 1055 | * YRegDisplayItemDelegate |
768 | */ | 1056 | */ |
769 | 1057 | ||
@@ -772,14 +1060,9 @@ YRegDisplayItemDelegate::YRegDisplayItemDelegate(QObject *parent) | |||
772 | { | 1060 | { |
773 | } | 1061 | } |
774 | 1062 | ||
775 | void YRegDisplayItemDelegate::paint(QPainter *painter, | 1063 | void YRegDisplayItemDelegate::MyPaint(QPainter *painter, const QStyleOptionViewItemV4& option) const |
776 | const QStyleOptionViewItem& option, const QModelIndex& index) const | ||
777 | { | 1064 | { |
778 | QStyleOptionViewItemV4 opt = option; | 1065 | QStyleOptionViewItemV4 opt = option; |
779 | // default alignment is centered unless specified | ||
780 | opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter; | ||
781 | initStyleOption(&opt, index); | ||
782 | |||
783 | painter->save(); | 1066 | painter->save(); |
784 | // draw everything rotated, requires careful manipulation of the | 1067 | // draw everything rotated, requires careful manipulation of the |
785 | // rects involved | 1068 | // rects involved |
@@ -789,17 +1072,58 @@ YRegDisplayItemDelegate::YRegDisplayItemDelegate(QObject *parent) | |||
789 | QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); | 1072 | QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); |
790 | style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); | 1073 | style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); |
791 | painter->restore(); | 1074 | painter->restore(); |
1075 | } | ||
1076 | |||
1077 | void YRegDisplayItemDelegate::paint(QPainter *painter, | ||
1078 | const QStyleOptionViewItem& option, const QModelIndex& index) const | ||
1079 | { | ||
1080 | QStyleOptionViewItemV4 opt = option; | ||
1081 | // default alignment is centered unless specified | ||
1082 | opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter; | ||
1083 | initStyleOption(&opt, index); | ||
1084 | |||
1085 | MyPaint(painter, opt); | ||
792 | 1086 | ||
793 | } | 1087 | } |
794 | 1088 | ||
795 | QSize YRegDisplayItemDelegate::sizeHint(const QStyleOptionViewItem& option, | 1089 | QSize YRegDisplayItemDelegate::sizeHint(const QStyleOptionViewItem& option, |
796 | const QModelIndex& index) const | 1090 | const QModelIndex& index) const |
797 | { | 1091 | { |
1092 | /* useless in our case, the view ignores this */ | ||
798 | Q_UNUSED(option); | 1093 | Q_UNUSED(option); |
799 | Q_UNUSED(index); | 1094 | Q_UNUSED(index); |
800 | return QSize(); | 1095 | return QSize(); |
801 | } | 1096 | } |
802 | 1097 | ||
1098 | QWidget *YRegDisplayItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, | ||
1099 | const QModelIndex& index) const | ||
1100 | { | ||
1101 | Q_UNUSED(option); | ||
1102 | Q_UNUSED(index); | ||
1103 | YRegDisplay *display = dynamic_cast< YRegDisplay* >(parent->parent()); | ||
1104 | Q_ASSERT(display != nullptr); | ||
1105 | /* column 0 is name, column 1 is range */ | ||
1106 | return new YRegDisplayItemEditor(parent, display, const_cast< YRegDisplayItemDelegate* >(this), | ||
1107 | index.sibling(index.row(), 0), index.sibling(index.row(), 1)); | ||
1108 | } | ||
1109 | |||
1110 | void YRegDisplayItemDelegate::setEditorData(QWidget *editor, const QModelIndex& index) const | ||
1111 | { | ||
1112 | dynamic_cast< YRegDisplayItemEditor* >(editor)->setEditorData( | ||
1113 | index.sibling(index.row(), 0), index.sibling(index.row(), 1)); | ||
1114 | } | ||
1115 | |||
1116 | void YRegDisplayItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, | ||
1117 | const QModelIndex& index) const | ||
1118 | { | ||
1119 | QVariant name, bitrange; | ||
1120 | dynamic_cast< YRegDisplayItemEditor* >(editor)->getEditorData(name, bitrange); | ||
1121 | if(name.isValid()) | ||
1122 | model->setData(index.sibling(index.row(), 1), name); | ||
1123 | if(bitrange.isValid()) | ||
1124 | model->setData(index.sibling(index.row(), 0), bitrange); | ||
1125 | } | ||
1126 | |||
803 | /** | 1127 | /** |
804 | * YRegDisplay | 1128 | * YRegDisplay |
805 | */ | 1129 | */ |
@@ -814,7 +1138,8 @@ YRegDisplay::YRegDisplay(QWidget *parent) | |||
814 | // the frame around the register is ugly, disable it | 1138 | // the frame around the register is ugly, disable it |
815 | setFrameShape(QFrame::NoFrame); | 1139 | setFrameShape(QFrame::NoFrame); |
816 | setSelectionMode(SingleSelection); | 1140 | setSelectionMode(SingleSelection); |
817 | setItemDelegate(new YRegDisplayItemDelegate()); | 1141 | setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); |
1142 | setItemDelegate(new YRegDisplayItemDelegate(this)); | ||
818 | } | 1143 | } |
819 | 1144 | ||
820 | void YRegDisplay::setWidth(int nr_bits) | 1145 | void YRegDisplay::setWidth(int nr_bits) |
@@ -1055,6 +1380,11 @@ QRect YRegDisplay::itemRect(const QModelIndex& index) const | |||
1055 | return itemRect(range, index.column()); | 1380 | return itemRect(range, index.column()); |
1056 | } | 1381 | } |
1057 | 1382 | ||
1383 | QRect YRegDisplay::BitrangeRect(const SocFieldBitRange& range) const | ||
1384 | { | ||
1385 | return itemRect(range, m_data_col); | ||
1386 | } | ||
1387 | |||
1058 | QRect YRegDisplay::itemRect(const SocFieldBitRange& range, int col) const | 1388 | QRect YRegDisplay::itemRect(const SocFieldBitRange& range, int col) const |
1059 | { | 1389 | { |
1060 | int top, bot; | 1390 | int top, bot; |
@@ -1276,17 +1606,17 @@ MyTextEditor::MyTextEditor(QWidget *parent) | |||
1276 | m_edit->setAutoFormatting(QTextEdit::AutoAll); | 1606 | m_edit->setAutoFormatting(QTextEdit::AutoAll); |
1277 | 1607 | ||
1278 | m_bold_button = new QToolButton(this); | 1608 | m_bold_button = new QToolButton(this); |
1279 | m_bold_button->setIcon(QIcon::fromTheme("format-text-bold")); | 1609 | m_bold_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextBold)); |
1280 | m_bold_button->setText("bold"); | 1610 | m_bold_button->setText("bold"); |
1281 | m_bold_button->setCheckable(true); | 1611 | m_bold_button->setCheckable(true); |
1282 | 1612 | ||
1283 | m_italic_button = new QToolButton(this); | 1613 | m_italic_button = new QToolButton(this); |
1284 | m_italic_button->setIcon(QIcon::fromTheme("format-text-italic")); | 1614 | m_italic_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextItalic)); |
1285 | m_italic_button->setText("italic"); | 1615 | m_italic_button->setText("italic"); |
1286 | m_italic_button->setCheckable(true); | 1616 | m_italic_button->setCheckable(true); |
1287 | 1617 | ||
1288 | m_underline_button = new QToolButton(this); | 1618 | m_underline_button = new QToolButton(this); |
1289 | m_underline_button->setIcon(QIcon::fromTheme("format-text-underline")); | 1619 | m_underline_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextUnderline)); |
1290 | m_underline_button->setText("underline"); | 1620 | m_underline_button->setText("underline"); |
1291 | m_underline_button->setCheckable(true); | 1621 | m_underline_button->setCheckable(true); |
1292 | 1622 | ||
@@ -1419,10 +1749,13 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent) | |||
1419 | :QWidget(parent), m_backend(backend) | 1749 | :QWidget(parent), m_backend(backend) |
1420 | { | 1750 | { |
1421 | m_data_selector = new QComboBox(this); | 1751 | m_data_selector = new QComboBox(this); |
1422 | m_data_selector->addItem(QIcon::fromTheme("text-x-generic"), "Nothing...", QVariant(DataSelNothing)); | 1752 | m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::TextGeneric), |
1423 | m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); | 1753 | "Nothing...", QVariant(DataSelNothing)); |
1754 | m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen), | ||
1755 | "File...", QVariant(DataSelFile)); | ||
1424 | #ifdef HAVE_HWSTUB | 1756 | #ifdef HAVE_HWSTUB |
1425 | m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice)); | 1757 | m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::MultimediaPlayer), |
1758 | "USB Device...", QVariant(DataSelDevice)); | ||
1426 | #endif | 1759 | #endif |
1427 | m_data_sel_edit = new QLineEdit(this); | 1760 | m_data_sel_edit = new QLineEdit(this); |
1428 | m_data_sel_edit->setReadOnly(true); | 1761 | m_data_sel_edit->setReadOnly(true); |
@@ -1435,7 +1768,18 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent) | |||
1435 | data_sel_layout->addStretch(0); | 1768 | data_sel_layout->addStretch(0); |
1436 | #ifdef HAVE_HWSTUB | 1769 | #ifdef HAVE_HWSTUB |
1437 | m_dev_selector = new QComboBox; | 1770 | m_dev_selector = new QComboBox; |
1771 | m_ctx_model = new HWStubContextModel; | ||
1772 | m_ctx_model->EnableDummy(true, "Please select a device..."); | ||
1773 | m_dev_selector->setModel(m_ctx_model); /* m_dev_selector will delete m_ctx_model */ | ||
1774 | m_ctx_selector = new QComboBox; | ||
1775 | m_ctx_manager = HWStubManager::Get(); | ||
1776 | m_ctx_selector->setModel(m_ctx_manager); | ||
1777 | m_ctx_manage_button = new QPushButton(); | ||
1778 | m_ctx_manage_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::Preferences)); | ||
1779 | m_ctx_manage_button->setToolTip("Manage contexts"); | ||
1438 | data_sel_layout->addWidget(m_dev_selector, 1); | 1780 | data_sel_layout->addWidget(m_dev_selector, 1); |
1781 | data_sel_layout->addWidget(m_ctx_selector); | ||
1782 | data_sel_layout->addWidget(m_ctx_manage_button); | ||
1439 | #endif | 1783 | #endif |
1440 | 1784 | ||
1441 | m_io_backend = m_backend->CreateDummyIoBackend(); | 1785 | m_io_backend = m_backend->CreateDummyIoBackend(); |
@@ -1443,18 +1787,25 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent) | |||
1443 | connect(m_data_selector, SIGNAL(activated(int)), | 1787 | connect(m_data_selector, SIGNAL(activated(int)), |
1444 | this, SLOT(OnDataSelChanged(int))); | 1788 | this, SLOT(OnDataSelChanged(int))); |
1445 | #ifdef HAVE_HWSTUB | 1789 | #ifdef HAVE_HWSTUB |
1446 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), | 1790 | connect(m_ctx_selector, SIGNAL(currentIndexChanged(int)), this, |
1447 | this, SLOT(OnDevChanged(int))); | 1791 | SLOT(OnContextSelChanged(int))); |
1448 | connect(&m_hwstub_helper, SIGNAL(OnDevListChanged(bool, struct libusb_device *)), | 1792 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), this, |
1449 | this, SLOT(OnDevListChanged2(bool, struct libusb_device *))); | 1793 | SLOT(OnDeviceSelChanged(int))); |
1794 | connect(m_dev_selector, SIGNAL(activated(int)), this, | ||
1795 | SLOT(OnDeviceSelActivated(int))); | ||
1796 | #endif | ||
1797 | |||
1798 | #ifdef HAVE_HWSTUB | ||
1799 | OnContextSelChanged(0); | ||
1450 | #endif | 1800 | #endif |
1451 | OnDataSelChanged(0); | 1801 | OnDataSelChanged(0); |
1452 | } | 1802 | } |
1453 | 1803 | ||
1454 | BackendSelector::~BackendSelector() | 1804 | BackendSelector::~BackendSelector() |
1455 | { | 1805 | { |
1806 | /* avoid m_ctx_selector from deleting HWStubManager */ | ||
1456 | #ifdef HAVE_HWSTUB | 1807 | #ifdef HAVE_HWSTUB |
1457 | ClearDevList(); | 1808 | m_ctx_selector->setModel(new QStandardItemModel()); |
1458 | #endif | 1809 | #endif |
1459 | delete m_io_backend; | 1810 | delete m_io_backend; |
1460 | } | 1811 | } |
@@ -1475,6 +1826,8 @@ void BackendSelector::OnDataSelChanged(int index) | |||
1475 | m_data_sel_edit->show(); | 1826 | m_data_sel_edit->show(); |
1476 | #ifdef HAVE_HWSTUB | 1827 | #ifdef HAVE_HWSTUB |
1477 | m_dev_selector->hide(); | 1828 | m_dev_selector->hide(); |
1829 | m_ctx_selector->hide(); | ||
1830 | m_ctx_manage_button->hide(); | ||
1478 | #endif | 1831 | #endif |
1479 | QFileDialog *fd = new QFileDialog(m_data_selector); | 1832 | QFileDialog *fd = new QFileDialog(m_data_selector); |
1480 | QStringList filters; | 1833 | QStringList filters; |
@@ -1496,7 +1849,10 @@ void BackendSelector::OnDataSelChanged(int index) | |||
1496 | m_nothing_text->hide(); | 1849 | m_nothing_text->hide(); |
1497 | m_data_sel_edit->hide(); | 1850 | m_data_sel_edit->hide(); |
1498 | m_dev_selector->show(); | 1851 | m_dev_selector->show(); |
1499 | OnDevListChanged(); | 1852 | m_ctx_selector->show(); |
1853 | m_ctx_manage_button->show(); | ||
1854 | /* explicitely change the backend now */ | ||
1855 | OnDeviceSelActivated(m_dev_selector->currentIndex()); | ||
1500 | } | 1856 | } |
1501 | #endif | 1857 | #endif |
1502 | else | 1858 | else |
@@ -1505,83 +1861,68 @@ void BackendSelector::OnDataSelChanged(int index) | |||
1505 | m_nothing_text->show(); | 1861 | m_nothing_text->show(); |
1506 | #ifdef HAVE_HWSTUB | 1862 | #ifdef HAVE_HWSTUB |
1507 | m_dev_selector->hide(); | 1863 | m_dev_selector->hide(); |
1864 | m_ctx_selector->hide(); | ||
1865 | m_ctx_manage_button->hide(); | ||
1508 | #endif | 1866 | #endif |
1509 | 1867 | ||
1510 | ChangeBackend(m_backend->CreateDummyIoBackend()); | 1868 | ChangeBackend(m_backend->CreateDummyIoBackend()); |
1511 | } | 1869 | } |
1512 | } | 1870 | } |
1513 | 1871 | ||
1514 | #ifdef HAVE_HWSTUB | 1872 | IoBackend *BackendSelector::GetBackend() |
1515 | void BackendSelector::OnDevListChanged2(bool arrived, struct libusb_device *dev) | ||
1516 | { | 1873 | { |
1517 | Q_UNUSED(arrived); | 1874 | return m_io_backend; |
1518 | Q_UNUSED(dev); | ||
1519 | OnDevListChanged(); | ||
1520 | } | 1875 | } |
1521 | 1876 | ||
1522 | void BackendSelector::OnDevListChanged() | 1877 | void BackendSelector::ChangeBackend(IoBackend *new_backend) |
1523 | { | 1878 | { |
1524 | ClearDevList(); | 1879 | /* WARNING: delete old backend *after* calling the signal, otherwise the old backend |
1525 | QList< HWStubDevice* > list = m_hwstub_helper.GetDevList(); | 1880 | * might get used after delete */ |
1526 | foreach(HWStubDevice *dev, list) | 1881 | emit OnSelect(new_backend); |
1527 | { | 1882 | delete m_io_backend; |
1528 | QString name = QString("Bus %1 Device %2: %3").arg(dev->GetBusNumber()) | 1883 | m_io_backend = new_backend; |
1529 | .arg(dev->GetDevAddress()).arg(dev->GetTargetInfo().bName); | ||
1530 | m_dev_selector->addItem(QIcon::fromTheme("multimedia-player"), name, | ||
1531 | QVariant::fromValue((void *)dev)); | ||
1532 | } | ||
1533 | if(list.size() > 0) | ||
1534 | m_dev_selector->setCurrentIndex(0); | ||
1535 | } | 1884 | } |
1536 | 1885 | ||
1537 | void BackendSelector::OnDevChanged(int index) | 1886 | #ifdef HAVE_HWSTUB |
1887 | void BackendSelector::OnContextSelChanged(int index) | ||
1538 | { | 1888 | { |
1889 | m_ctx_model->SetContext(m_ctx_manager->GetContext(index)); | ||
1890 | m_dev_selector->setCurrentIndex(0); | ||
1891 | } | ||
1892 | |||
1893 | void BackendSelector::OnDeviceSelChanged(int index) | ||
1894 | { | ||
1895 | /* if current selection is -1, because device was removed or a new context | ||
1896 | * was selected, select entry 0, which is dummy. Not that this will not | ||
1897 | * call activate(), we don't want to change the current backend if the user | ||
1898 | * is using another type of backend. */ | ||
1539 | if(index == -1) | 1899 | if(index == -1) |
1540 | return; | 1900 | m_dev_selector->setCurrentIndex(0); |
1541 | HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >()); | ||
1542 | delete m_io_backend; | ||
1543 | /* NOTE: make a copy of the HWStubDevice device because the one in the list | ||
1544 | * might get destroyed when clearing the list while the backend is still | ||
1545 | * active: this would result in a double free when the backend is also destroyed */ | ||
1546 | m_io_backend = m_backend->CreateHWStubIoBackend(new HWStubDevice(dev)); | ||
1547 | emit OnSelect(m_io_backend); | ||
1548 | } | 1901 | } |
1549 | 1902 | ||
1550 | void BackendSelector::ClearDevList() | 1903 | void BackendSelector::OnDeviceSelActivated(int index) |
1551 | { | 1904 | { |
1552 | while(m_dev_selector->count() > 0) | 1905 | auto dev = new HWStubDevice(m_ctx_model->GetDevice(index)); |
1906 | if(!dev->IsValid()) | ||
1553 | { | 1907 | { |
1554 | HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(0).value< void* >()); | ||
1555 | delete dev; | 1908 | delete dev; |
1556 | m_dev_selector->removeItem(0); | 1909 | ChangeBackend(m_backend->CreateDummyIoBackend()); |
1557 | } | 1910 | } |
1911 | else | ||
1912 | ChangeBackend(new HWStubIoBackend(dev)); | ||
1558 | } | 1913 | } |
1559 | #endif | 1914 | #endif |
1560 | 1915 | ||
1561 | IoBackend *BackendSelector::GetBackend() | ||
1562 | { | ||
1563 | return m_io_backend; | ||
1564 | } | ||
1565 | |||
1566 | void BackendSelector::ChangeBackend(IoBackend *new_backend) | ||
1567 | { | ||
1568 | /* WARNING: delete old backend *after* calling the signal, otherwise the old backend | ||
1569 | * might get used after delete */ | ||
1570 | emit OnSelect(new_backend); | ||
1571 | delete m_io_backend; | ||
1572 | m_io_backend = new_backend; | ||
1573 | } | ||
1574 | |||
1575 | /** | 1916 | /** |
1576 | * YTabWidget | 1917 | * YTabWidget |
1577 | */ | 1918 | */ |
1578 | YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent) | 1919 | YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent) |
1579 | :QTabWidget(parent) | 1920 | :QTabWidget(parent), m_other_button(0) |
1580 | { | 1921 | { |
1581 | if(bar != 0) | 1922 | if(bar != 0) |
1582 | setTabBar(bar); | 1923 | setTabBar(bar); |
1583 | m_tab_open_button = new QToolButton(this); | 1924 | m_tab_open_button = new QToolButton(this); |
1584 | m_tab_open_button->setIcon(QIcon::fromTheme("list-add")); | 1925 | m_tab_open_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd)); |
1585 | m_tab_open_button->setAutoRaise(true); | 1926 | m_tab_open_button->setAutoRaise(true); |
1586 | m_tab_open_button->setPopupMode(QToolButton::InstantPopup); | 1927 | m_tab_open_button->setPopupMode(QToolButton::InstantPopup); |
1587 | /* the arrow with an icon only is pretty ugly and QToolButton has no way | 1928 | /* the arrow with an icon only is pretty ugly and QToolButton has no way |
@@ -1592,8 +1933,8 @@ YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent) | |||
1592 | connect(m_tab_open_button, SIGNAL(clicked(bool)), this, SLOT(OnOpenButton(bool))); | 1933 | connect(m_tab_open_button, SIGNAL(clicked(bool)), this, SLOT(OnOpenButton(bool))); |
1593 | /* there is a quirk in the default QStyle: if the tab bar is empty, it | 1934 | /* there is a quirk in the default QStyle: if the tab bar is empty, it |
1594 | * returns the minimum size of the corner widget, which is 0 for tool buttons */ | 1935 | * returns the minimum size of the corner widget, which is 0 for tool buttons */ |
1595 | //setMinimumHeight(m_tab_open_button->height()); | 1936 | m_tab_open_button->setMinimumSize(m_tab_open_button->sizeHint()); |
1596 | //m_tab_open_button->setMinimumHeight(m_tab_open_button->sizeHint().height()); | 1937 | setMinimumSize(m_tab_open_button->sizeHint()); |
1597 | } | 1938 | } |
1598 | 1939 | ||
1599 | void YTabWidget::setTabOpenable(bool openable) | 1940 | void YTabWidget::setTabOpenable(bool openable) |
@@ -1613,6 +1954,28 @@ void YTabWidget::setTabOpenMenu(QMenu *menu) | |||
1613 | m_tab_open_button->setMenu(menu); | 1954 | m_tab_open_button->setMenu(menu); |
1614 | } | 1955 | } |
1615 | 1956 | ||
1957 | void YTabWidget::setOtherMenu(QMenu *menu) | ||
1958 | { | ||
1959 | if(menu == nullptr) | ||
1960 | { | ||
1961 | if(m_other_button) | ||
1962 | delete m_other_button; | ||
1963 | m_other_button = nullptr; | ||
1964 | } | ||
1965 | else | ||
1966 | { | ||
1967 | if(m_other_button == nullptr) | ||
1968 | { | ||
1969 | m_other_button = new QToolButton(this); | ||
1970 | m_other_button->setText("Menu"); | ||
1971 | m_other_button->setAutoRaise(true); | ||
1972 | m_other_button->setPopupMode(QToolButton::InstantPopup); | ||
1973 | setCornerWidget(m_other_button, Qt::TopRightCorner); | ||
1974 | } | ||
1975 | m_other_button->setMenu(menu); | ||
1976 | } | ||
1977 | } | ||
1978 | |||
1616 | /** | 1979 | /** |
1617 | * MessageWidget | 1980 | * MessageWidget |
1618 | */ | 1981 | */ |
@@ -1625,6 +1988,7 @@ MessageWidget::MessageWidget(QWidget *parent) | |||
1625 | m_icon->hide(); | 1988 | m_icon->hide(); |
1626 | m_text = new QLabel(this); | 1989 | m_text = new QLabel(this); |
1627 | m_text->setTextFormat(Qt::RichText); | 1990 | m_text->setTextFormat(Qt::RichText); |
1991 | m_text->setWordWrap(true); | ||
1628 | m_close = new QToolButton(this); | 1992 | m_close = new QToolButton(this); |
1629 | m_close->setText("close"); | 1993 | m_close->setText("close"); |
1630 | m_close->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton)); | 1994 | m_close->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton)); |
@@ -1702,6 +2066,102 @@ void MessageWidget::OnClose(bool clicked) | |||
1702 | hide(); | 2066 | hide(); |
1703 | } | 2067 | } |
1704 | 2068 | ||
2069 | /* | ||
2070 | * YIconManager | ||
2071 | */ | ||
2072 | YIconManager *YIconManager::m_singleton = nullptr; | ||
2073 | |||
2074 | YIconManager::YIconManager() | ||
2075 | { | ||
2076 | m_icon_name[ListAdd] = "list-add"; | ||
2077 | m_icon_name[ListRemove] = "list-remove"; | ||
2078 | m_icon_name[DocumentNew] = "document-new"; | ||
2079 | m_icon_name[DocumentEdit] = "document-edit"; | ||
2080 | m_icon_name[DocumentOpen] = "document-open"; | ||
2081 | m_icon_name[DocumentSave] = "document-save"; | ||
2082 | m_icon_name[DocumentSaveAs] = "document-save-as"; | ||
2083 | m_icon_name[Preferences] = "preferences-system"; | ||
2084 | m_icon_name[FolderNew] = "folder-new"; | ||
2085 | m_icon_name[Computer] = "computer"; | ||
2086 | m_icon_name[Cpu] = "cpu"; | ||
2087 | m_icon_name[DialogError] = "dialog-error"; | ||
2088 | m_icon_name[ViewRefresh] = "view-refresh"; | ||
2089 | m_icon_name[SytemRun] = "system-run"; | ||
2090 | m_icon_name[ApplicationExit] = "application-exit"; | ||
2091 | m_icon_name[HelpAbout] = "help-about"; | ||
2092 | m_icon_name[FormatTextBold] = "format-text-bold"; | ||
2093 | m_icon_name[FormatTextItalic] = "format-text-italic"; | ||
2094 | m_icon_name[FormatTextUnderline] = "format-text-underline"; | ||
2095 | m_icon_name[TextGeneric] = "text-x-generic"; | ||
2096 | m_icon_name[MultimediaPlayer] = "multimedia-player"; | ||
2097 | } | ||
2098 | |||
2099 | YIconManager::~YIconManager() | ||
2100 | { | ||
2101 | } | ||
2102 | |||
2103 | YIconManager *YIconManager::Get() | ||
2104 | { | ||
2105 | if(m_singleton == nullptr) | ||
2106 | m_singleton = new YIconManager(); | ||
2107 | return m_singleton; | ||
2108 | } | ||
2109 | |||
2110 | QIcon YIconManager::GetIcon(IconType type) | ||
2111 | { | ||
2112 | if(type < 0 || type >= MaxIcon) | ||
2113 | return QIcon(); | ||
2114 | if(QIcon::hasThemeIcon(m_icon_name[type])) | ||
2115 | return QIcon::fromTheme(m_icon_name[type]); | ||
2116 | /* render icon if needed */ | ||
2117 | if(m_icon[type].isNull()) | ||
2118 | Render(type); | ||
2119 | return m_icon[type]; | ||
2120 | } | ||
2121 | |||
2122 | namespace | ||
2123 | { | ||
2124 | void RenderListAdd(QIcon& icon) | ||
2125 | { | ||
2126 | QPixmap pix(64, 64); | ||
2127 | pix.fill(Qt::transparent); | ||
2128 | QPainter paint(&pix); | ||
2129 | paint.fillRect(30, 12, 4, 40, QColor(255, 0, 0)); | ||
2130 | paint.fillRect(12, 30, 40, 4, QColor(255, 0, 0)); | ||
2131 | icon = QIcon(pix); | ||
2132 | } | ||
2133 | |||
2134 | void RenderListRemove(QIcon& icon) | ||
2135 | { | ||
2136 | QPixmap pix(64, 64); | ||
2137 | pix.fill(Qt::transparent); | ||
2138 | QPainter paint(&pix); | ||
2139 | paint.setPen(QColor(255, 0, 0)); | ||
2140 | paint.drawLine(12, 12, 52, 52); | ||
2141 | paint.drawLine(12, 52, 52, 16); | ||
2142 | icon = QIcon(pix); | ||
2143 | } | ||
2144 | |||
2145 | void RenderUnknown(QIcon& icon) | ||
2146 | { | ||
2147 | QPixmap pix(64, 64); | ||
2148 | pix.fill(); | ||
2149 | QPainter paint(&pix); | ||
2150 | paint.fillRect(0, 0, 64, 64, QColor(255, 0, 0)); | ||
2151 | icon = QIcon(pix); | ||
2152 | } | ||
2153 | } | ||
2154 | |||
2155 | void YIconManager::Render(IconType type) | ||
2156 | { | ||
2157 | switch(type) | ||
2158 | { | ||
2159 | case ListAdd: RenderListAdd(m_icon[type]); break; | ||
2160 | case ListRemove: RenderListRemove(m_icon[type]); break; | ||
2161 | default: RenderUnknown(m_icon[type]); break; | ||
2162 | } | ||
2163 | } | ||
2164 | |||
1705 | /** | 2165 | /** |
1706 | * Misc | 2166 | * Misc |
1707 | */ | 2167 | */ |