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 | |
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')
-rw-r--r-- | utils/regtools/qeditor/backend.cpp | 553 | ||||
-rw-r--r-- | utils/regtools/qeditor/backend.h | 141 | ||||
-rw-r--r-- | utils/regtools/qeditor/mainwindow.cpp | 38 | ||||
-rw-r--r-- | utils/regtools/qeditor/qeditor.pro | 3 | ||||
-rw-r--r-- | utils/regtools/qeditor/regdisplaypanel.cpp | 35 | ||||
-rw-r--r-- | utils/regtools/qeditor/regedit.cpp | 136 | ||||
-rw-r--r-- | utils/regtools/qeditor/regedit.h | 5 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 38 | ||||
-rw-r--r-- | utils/regtools/qeditor/utils.cpp | 594 | ||||
-rw-r--r-- | utils/regtools/qeditor/utils.h | 178 |
10 files changed, 1393 insertions, 328 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp index 5f006b0aa7..a8264c6e50 100644 --- a/utils/regtools/qeditor/backend.cpp +++ b/utils/regtools/qeditor/backend.cpp | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <QTextStream> | 22 | #include <QTextStream> |
23 | #include <QDebug> | 23 | #include <QDebug> |
24 | #include <QFileInfo> | 24 | #include <QFileInfo> |
25 | #include <QFont> | ||
25 | #include "backend.h" | 26 | #include "backend.h" |
26 | 27 | ||
27 | /** | 28 | /** |
@@ -337,110 +338,436 @@ QString FileIoBackend::GetFileName() | |||
337 | 338 | ||
338 | #ifdef HAVE_HWSTUB | 339 | #ifdef HAVE_HWSTUB |
339 | /** | 340 | /** |
340 | * HWStubDevice | 341 | * HWStubManager |
341 | */ | 342 | */ |
342 | HWStubDevice::HWStubDevice(struct libusb_device *dev) | 343 | HWStubManager *HWStubManager::g_inst = nullptr; |
344 | |||
345 | HWStubManager::HWStubManager() | ||
343 | { | 346 | { |
344 | Init(dev); | 347 | Add("Default", QString::fromStdString(hwstub::uri::default_uri().full_uri())); |
345 | } | 348 | } |
346 | 349 | ||
347 | HWStubDevice::HWStubDevice(const HWStubDevice *dev) | 350 | HWStubManager::~HWStubManager() |
348 | { | 351 | { |
349 | Init(dev->m_dev); | ||
350 | } | 352 | } |
351 | 353 | ||
352 | void HWStubDevice::Init(struct libusb_device *dev) | 354 | HWStubManager *HWStubManager::Get() |
353 | { | 355 | { |
354 | libusb_ref_device(dev); | 356 | if(g_inst == nullptr) |
355 | m_dev = dev; | 357 | g_inst = new HWStubManager(); |
356 | m_handle = 0; | 358 | return g_inst; |
357 | m_hwdev = 0; | ||
358 | m_valid = Probe(); | ||
359 | } | 359 | } |
360 | 360 | ||
361 | HWStubDevice::~HWStubDevice() | 361 | bool HWStubManager::Add(const QString& name, const QString& uri) |
362 | { | ||
363 | struct Context ctx; | ||
364 | ctx.name = name; | ||
365 | ctx.uri = uri; | ||
366 | ctx.context = hwstub::uri::create_context(uri.toStdString()); | ||
367 | if(!ctx.context) | ||
368 | return false; | ||
369 | ctx.context->start_polling(); | ||
370 | beginInsertRows(QModelIndex(), m_list.size(), m_list.size()); | ||
371 | m_list.push_back(ctx); | ||
372 | endInsertRows(); | ||
373 | return true; | ||
374 | } | ||
375 | |||
376 | void HWStubManager::Clear() | ||
362 | { | 377 | { |
363 | Close(); | 378 | m_list.clear(); |
364 | libusb_unref_device(m_dev); | ||
365 | } | 379 | } |
366 | 380 | ||
367 | int HWStubDevice::GetBusNumber() | 381 | int HWStubManager::rowCount(const QModelIndex& parent) const |
368 | { | 382 | { |
369 | return libusb_get_bus_number(m_dev); | 383 | Q_UNUSED(parent); |
384 | return m_list.size(); | ||
370 | } | 385 | } |
371 | 386 | ||
372 | int HWStubDevice::GetDevAddress() | 387 | int HWStubManager::columnCount(const QModelIndex& parent) const |
373 | { | 388 | { |
374 | return libusb_get_device_address(m_dev); | 389 | Q_UNUSED(parent); |
390 | return 2; | ||
375 | } | 391 | } |
376 | 392 | ||
377 | bool HWStubDevice::Probe() | 393 | std::shared_ptr< hwstub::context > HWStubManager::GetContext(int row) |
378 | { | 394 | { |
379 | if(!Open()) | 395 | if(row < 0 || (size_t)row >= m_list.size()) |
380 | return false; | 396 | return std::shared_ptr< hwstub::context >(); |
381 | // get target | 397 | else |
382 | int ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_TARGET, &m_hwdev_target, sizeof(m_hwdev_target)); | 398 | return m_list[row].context; |
383 | if(ret != sizeof(m_hwdev_target)) | 399 | } |
384 | goto Lerr; | 400 | |
385 | // get STMP information | 401 | QVariant HWStubManager::data(const QModelIndex& index, int role) const |
386 | if(m_hwdev_target.dID == HWSTUB_TARGET_STMP) | 402 | { |
403 | if(index.row() < 0 || (size_t)index.row() >= m_list.size()) | ||
404 | return QVariant(); | ||
405 | int section = index.column(); | ||
406 | const Context& ctx = m_list[index.row()]; | ||
407 | if(section == GetNameColumn()) | ||
387 | { | 408 | { |
388 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_STMP, &m_hwdev_stmp, sizeof(m_hwdev_stmp)); | 409 | if(role == Qt::DisplayRole || role == Qt::EditRole) |
389 | if(ret != sizeof(m_hwdev_stmp)) | 410 | return QVariant(ctx.name); |
390 | goto Lerr; | ||
391 | } | 411 | } |
392 | else if(m_hwdev_target.dID == HWSTUB_TARGET_PP) | 412 | else if(section == GetUriColumn()) |
393 | { | 413 | { |
394 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_PP, &m_hwdev_pp, sizeof(m_hwdev_pp)); | 414 | if(role == Qt::DisplayRole) |
395 | if(ret != sizeof(m_hwdev_pp)) | 415 | return QVariant(ctx.uri); |
396 | goto Lerr; | ||
397 | } | 416 | } |
398 | Close(); | 417 | return QVariant(); |
399 | return true; | 418 | } |
400 | 419 | ||
401 | Lerr: | 420 | QVariant HWStubManager::headerData(int section, Qt::Orientation orientation, int role) const |
402 | Close(); | 421 | { |
403 | return false; | 422 | if(orientation == Qt::Vertical) |
423 | return QVariant(); | ||
424 | if(role != Qt::DisplayRole) | ||
425 | return QVariant(); | ||
426 | if(section == GetNameColumn()) | ||
427 | return QVariant("Name"); | ||
428 | else if(section == GetUriColumn()) | ||
429 | return QVariant("URI"); | ||
430 | return QVariant(); | ||
431 | } | ||
432 | |||
433 | Qt::ItemFlags HWStubManager::flags(const QModelIndex& index) const | ||
434 | { | ||
435 | Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; | ||
436 | int section = index.column(); | ||
437 | if(section == GetNameColumn()) | ||
438 | flags |= Qt::ItemIsEditable; | ||
439 | return flags; | ||
404 | } | 440 | } |
405 | 441 | ||
406 | bool HWStubDevice::Open() | 442 | bool HWStubManager::setData(const QModelIndex& index, const QVariant& value, int role) |
407 | { | 443 | { |
408 | if(libusb_open(m_dev, &m_handle)) | 444 | if(role != Qt::EditRole) |
409 | return false; | 445 | return false; |
410 | m_hwdev = hwstub_open(m_handle); | 446 | if(index.row() < 0 || (size_t)index.row() >= m_list.size()) |
411 | if(m_hwdev == 0) | ||
412 | { | ||
413 | libusb_close(m_handle); | ||
414 | m_handle = 0; | ||
415 | return false; | 447 | return false; |
416 | } | 448 | if(index.column() != GetNameColumn()) |
449 | return false; | ||
450 | m_list[index.row()].name = value.toString(); | ||
451 | emit dataChanged(index, index); | ||
417 | return true; | 452 | return true; |
418 | } | 453 | } |
419 | 454 | ||
420 | void HWStubDevice::Close() | 455 | int HWStubManager::GetNameColumn() const |
421 | { | 456 | { |
422 | if(m_hwdev) | 457 | return 0; |
423 | hwstub_release(m_hwdev); | ||
424 | m_hwdev = 0; | ||
425 | if(m_handle) | ||
426 | libusb_close(m_handle); | ||
427 | m_handle = 0; | ||
428 | } | 458 | } |
429 | 459 | ||
430 | bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer) | 460 | int HWStubManager::GetUriColumn() const |
461 | { | ||
462 | return 1; | ||
463 | } | ||
464 | |||
465 | QString HWStubManager::GetFriendlyName(std::shared_ptr< hwstub::device > device) | ||
466 | { | ||
467 | /* try to open the device */ | ||
468 | std::shared_ptr< hwstub::handle > handle; | ||
469 | hwstub::error err = device->open(handle); | ||
470 | if(err != hwstub::error::SUCCESS) | ||
471 | goto Lfallback; | ||
472 | /* get target descriptor */ | ||
473 | struct hwstub_target_desc_t target_desc; | ||
474 | err = handle->get_target_desc(target_desc); | ||
475 | if(err != hwstub::error::SUCCESS) | ||
476 | goto Lfallback; | ||
477 | return QString::fromStdString(target_desc.bName); | ||
478 | |||
479 | /* fallback: don't open the device */ | ||
480 | Lfallback: | ||
481 | hwstub::usb::device *udev = dynamic_cast< hwstub::usb::device* >(device.get()); | ||
482 | if(udev) | ||
483 | { | ||
484 | return QString("USB Bus %1 Device %2: ID %3:%4") | ||
485 | .arg(udev->get_bus_number()).arg(udev->get_address(), 3, 10, QChar('0')) | ||
486 | .arg(udev->get_vid(), 4, 16, QChar('0')).arg(udev->get_pid(), 4, 16, QChar('0')); | ||
487 | } | ||
488 | else | ||
489 | return QString("<Unknown device>"); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * HWStubContextModel | ||
494 | */ | ||
495 | HWStubContextModel::HWStubContextModel(QObject *parent) | ||
496 | :QAbstractTableModel(parent), m_has_dummy(false) | ||
497 | { | ||
498 | } | ||
499 | |||
500 | HWStubContextModel::~HWStubContextModel() | ||
501 | { | ||
502 | SetContext(std::shared_ptr< hwstub::context >()); | ||
503 | } | ||
504 | |||
505 | void HWStubContextModel::SetContext(std::shared_ptr< hwstub::context > context) | ||
506 | { | ||
507 | int first_row = m_has_dummy ? 1: 0; | ||
508 | /* clear previous model if any */ | ||
509 | if(m_list.size() > 0) | ||
510 | { | ||
511 | beginRemoveRows(QModelIndex(), first_row, first_row + m_list.size() - 1); | ||
512 | m_list.clear(); | ||
513 | endRemoveRows(); | ||
514 | } | ||
515 | /* don't forget to unregister callback if context still exists */ | ||
516 | std::shared_ptr< hwstub::context > ctx = m_context.lock(); | ||
517 | if(ctx) | ||
518 | ctx->unregister_callback(m_callback_ref); | ||
519 | /* get new context */ | ||
520 | m_context = context; | ||
521 | if(context) | ||
522 | { | ||
523 | /* register new callback */ | ||
524 | m_callback_ref = context->register_callback( | ||
525 | std::bind(&HWStubContextModel::OnDevChangeLow, this, std::placeholders::_1, | ||
526 | std::placeholders::_2, std::placeholders::_3)); | ||
527 | /* get dev list */ | ||
528 | std::vector< std::shared_ptr< hwstub::device > > list; | ||
529 | hwstub::error err = context->get_device_list(list); | ||
530 | if(err == hwstub::error::SUCCESS) | ||
531 | { | ||
532 | beginInsertRows(QModelIndex(), first_row, first_row + list.size() - 1); | ||
533 | for(auto& d : list) | ||
534 | { | ||
535 | Device dev; | ||
536 | dev.name = GetFriendlyName(d); | ||
537 | dev.device = d; | ||
538 | m_list.push_back(dev); | ||
539 | } | ||
540 | endInsertRows(); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
545 | void HWStubContextModel::EnableDummy(bool en, const QString& text) | ||
546 | { | ||
547 | /* if needed, create/remove raw */ | ||
548 | if(m_has_dummy && !en) | ||
549 | { | ||
550 | /* remove row */ | ||
551 | beginRemoveRows(QModelIndex(), 0, 0); | ||
552 | m_has_dummy = false; | ||
553 | endRemoveRows(); | ||
554 | } | ||
555 | else if(!m_has_dummy && en) | ||
556 | { | ||
557 | /* add row */ | ||
558 | beginInsertRows(QModelIndex(), 0, 0); | ||
559 | m_has_dummy = true; | ||
560 | m_dummy_text = text; | ||
561 | endInsertRows(); | ||
562 | } | ||
563 | else if(en) | ||
564 | { | ||
565 | /* text change only */ | ||
566 | emit dataChanged(index(0, GetNameColumn()), index(0, GetNameColumn())); | ||
567 | } | ||
568 | } | ||
569 | |||
570 | int HWStubContextModel::rowCount(const QModelIndex& parent) const | ||
571 | { | ||
572 | Q_UNUSED(parent); | ||
573 | return m_list.size() + (m_has_dummy ? 1 : 0); | ||
574 | } | ||
575 | |||
576 | int HWStubContextModel::columnCount(const QModelIndex& parent) const | ||
577 | { | ||
578 | Q_UNUSED(parent); | ||
579 | return 1; | ||
580 | } | ||
581 | |||
582 | QVariant HWStubContextModel::data(const QModelIndex& index, int role) const | ||
583 | { | ||
584 | int first_row = m_has_dummy ? 1: 0; | ||
585 | /* special case for dummy */ | ||
586 | if(m_has_dummy && index.row() == 0) | ||
587 | { | ||
588 | int section = index.column(); | ||
589 | if(section == GetNameColumn()) | ||
590 | { | ||
591 | if(role == Qt::DisplayRole) | ||
592 | return QVariant(m_dummy_text); | ||
593 | else if(role == Qt::FontRole) | ||
594 | { | ||
595 | QFont font; | ||
596 | font.setItalic(true); | ||
597 | return QVariant(font); | ||
598 | } | ||
599 | } | ||
600 | return QVariant(); | ||
601 | } | ||
602 | |||
603 | if(index.row() < first_row || (size_t)index.row() >= first_row + m_list.size()) | ||
604 | return QVariant(); | ||
605 | int section = index.column(); | ||
606 | if(section == GetNameColumn()) | ||
607 | { | ||
608 | if(role == Qt::DisplayRole) | ||
609 | return QVariant(m_list[index.row() - first_row].name); | ||
610 | } | ||
611 | return QVariant(); | ||
612 | } | ||
613 | |||
614 | QVariant HWStubContextModel::headerData(int section, Qt::Orientation orientation, int role) const | ||
615 | { | ||
616 | if(orientation == Qt::Vertical) | ||
617 | return QVariant(); | ||
618 | if(role != Qt::DisplayRole) | ||
619 | return QVariant(); | ||
620 | if(section == GetNameColumn()) | ||
621 | return QVariant("Friendly name"); | ||
622 | return QVariant(); | ||
623 | } | ||
624 | |||
625 | Qt::ItemFlags HWStubContextModel::flags(const QModelIndex& index) const | ||
626 | { | ||
627 | Q_UNUSED(index); | ||
628 | return Qt::ItemIsSelectable | Qt::ItemIsEnabled; | ||
629 | } | ||
630 | |||
631 | int HWStubContextModel::GetNameColumn() const | ||
632 | { | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | std::shared_ptr< hwstub::device > HWStubContextModel::GetDevice(int row) | ||
637 | { | ||
638 | int first_row = m_has_dummy ? 1: 0; | ||
639 | /* special case for dummy */ | ||
640 | if(row < first_row || (size_t)row >= first_row + m_list.size()) | ||
641 | return std::shared_ptr< hwstub::device >(); | ||
642 | else | ||
643 | return m_list[row - first_row].device; | ||
644 | } | ||
645 | |||
646 | QString HWStubContextModel::GetFriendlyName(std::shared_ptr< hwstub::device > device) | ||
431 | { | 647 | { |
432 | if(!m_hwdev) | 648 | return HWStubManager::GetFriendlyName(device); |
649 | } | ||
650 | |||
651 | namespace | ||
652 | { | ||
653 | struct dev_change_t | ||
654 | { | ||
655 | std::shared_ptr< hwstub::context > ctx; | ||
656 | bool arrived; | ||
657 | std::shared_ptr< hwstub::device > device; | ||
658 | }; | ||
659 | } | ||
660 | |||
661 | void HWStubContextModel::OnDevChangeLow(std::shared_ptr< hwstub::context > ctx, | ||
662 | bool arrived, std::shared_ptr< hwstub::device > device) | ||
663 | { | ||
664 | /* calling Qt function from non-Qt thread is unsafe. Since the polling thread | ||
665 | * is a pthread, the safest way to use Qt invoke mecanism to make it run | ||
666 | * on the event loop */ | ||
667 | dev_change_t *evt = new dev_change_t; | ||
668 | evt->ctx = ctx; | ||
669 | evt->arrived = arrived; | ||
670 | evt->device = device; | ||
671 | QMetaObject::invokeMethod(this, "OnDevChangeUnsafe", Q_ARG(void *, (void *)evt)); | ||
672 | } | ||
673 | |||
674 | void HWStubContextModel::OnDevChangeUnsafe(void *data) | ||
675 | { | ||
676 | dev_change_t *evt = (dev_change_t *)data; | ||
677 | OnDevChange(evt->ctx, evt->arrived, evt->device); | ||
678 | delete evt; | ||
679 | } | ||
680 | |||
681 | void HWStubContextModel::OnDevChange(std::shared_ptr< hwstub::context > ctx, bool arrived, | ||
682 | std::shared_ptr< hwstub::device > device) | ||
683 | { | ||
684 | int first_row = m_has_dummy ? 1: 0; | ||
685 | Q_UNUSED(ctx); | ||
686 | if(arrived) | ||
687 | { | ||
688 | Device dev; | ||
689 | dev.name = GetFriendlyName(device); | ||
690 | dev.device = device; | ||
691 | beginInsertRows(QModelIndex(), first_row + m_list.size(), | ||
692 | first_row + m_list.size()); | ||
693 | m_list.push_back(dev); | ||
694 | endInsertRows(); | ||
695 | } | ||
696 | else | ||
697 | { | ||
698 | /* find device in the list */ | ||
699 | auto it = m_list.begin(); | ||
700 | int idx = 0; | ||
701 | for(; it != m_list.end(); ++it, ++idx) | ||
702 | if(it->device == device) | ||
703 | break; | ||
704 | if(it == m_list.end()) | ||
705 | return; | ||
706 | /* remove it */ | ||
707 | beginRemoveRows(QModelIndex(), first_row + idx, first_row + idx); | ||
708 | m_list.erase(it); | ||
709 | endRemoveRows(); | ||
710 | } | ||
711 | } | ||
712 | |||
713 | /** | ||
714 | * HWStubDevice | ||
715 | */ | ||
716 | HWStubDevice::HWStubDevice(std::shared_ptr< hwstub::device > device) | ||
717 | { | ||
718 | m_valid = Probe(device); | ||
719 | } | ||
720 | |||
721 | HWStubDevice::~HWStubDevice() | ||
722 | { | ||
723 | } | ||
724 | |||
725 | bool HWStubDevice::Probe(std::shared_ptr<hwstub::device> device) | ||
726 | { | ||
727 | if(!device) | ||
433 | return false; | 728 | return false; |
434 | int ret = hwstub_rw_mem_atomic(m_hwdev, 1, addr, buffer, length); | 729 | hwstub::error err = device->open(m_handle); |
435 | return ret >= 0 && (size_t)ret == length; | 730 | if(err != hwstub::error::SUCCESS) |
731 | return false; | ||
732 | // get target information | ||
733 | err = m_handle->get_target_desc(m_hwdev_target); | ||
734 | if(err != hwstub::error::SUCCESS) | ||
735 | return false; | ||
736 | // get STMP/PP information | ||
737 | if(m_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
738 | { | ||
739 | err = m_handle->get_stmp_desc(m_hwdev_stmp); | ||
740 | if(err != hwstub::error::SUCCESS) | ||
741 | return false; | ||
742 | } | ||
743 | else if(m_hwdev_target.dID == HWSTUB_TARGET_PP) | ||
744 | { | ||
745 | err = m_handle->get_pp_desc(m_hwdev_pp); | ||
746 | if(err != hwstub::error::SUCCESS) | ||
747 | return false; | ||
748 | } | ||
749 | else if(m_hwdev_target.dID == HWSTUB_TARGET_JZ) | ||
750 | { | ||
751 | err = m_handle->get_jz_desc(m_hwdev_jz); | ||
752 | if(err != hwstub::error::SUCCESS) | ||
753 | return false; | ||
754 | } | ||
755 | m_name = HWStubManager::GetFriendlyName(device); | ||
756 | return true; | ||
757 | } | ||
758 | |||
759 | bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer) | ||
760 | { | ||
761 | size_t len = length; | ||
762 | hwstub::error err = m_handle->read(addr, buffer, len, true); | ||
763 | return err == hwstub::error::SUCCESS && len == length; | ||
436 | } | 764 | } |
437 | 765 | ||
438 | bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer) | 766 | bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer) |
439 | { | 767 | { |
440 | if(!m_hwdev) | 768 | size_t len = length; |
441 | return false; | 769 | hwstub::error err = m_handle->write(addr, buffer, len, true); |
442 | int ret = hwstub_rw_mem_atomic(m_hwdev, 0, addr, buffer, length); | 770 | return err == hwstub::error::SUCCESS && len == length; |
443 | return ret >= 0 && (size_t)ret == length; | ||
444 | } | 771 | } |
445 | 772 | ||
446 | bool HWStubDevice::IsValid() | 773 | bool HWStubDevice::IsValid() |
@@ -448,6 +775,10 @@ bool HWStubDevice::IsValid() | |||
448 | return m_valid; | 775 | return m_valid; |
449 | } | 776 | } |
450 | 777 | ||
778 | QString HWStubDevice::GetFriendlyName() | ||
779 | { | ||
780 | return m_name; | ||
781 | } | ||
451 | 782 | ||
452 | /** | 783 | /** |
453 | * HWStubIoBackend | 784 | * HWStubIoBackend |
@@ -456,7 +787,7 @@ bool HWStubDevice::IsValid() | |||
456 | HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) | 787 | HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) |
457 | { | 788 | { |
458 | m_dev = dev; | 789 | m_dev = dev; |
459 | m_dev->Open(); | 790 | |
460 | struct hwstub_target_desc_t target = m_dev->GetTargetInfo(); | 791 | struct hwstub_target_desc_t target = m_dev->GetTargetInfo(); |
461 | if(target.dID == HWSTUB_TARGET_STMP) | 792 | if(target.dID == HWSTUB_TARGET_STMP) |
462 | { | 793 | { |
@@ -470,6 +801,13 @@ HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) | |||
470 | else | 801 | else |
471 | m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0')); | 802 | m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0')); |
472 | } | 803 | } |
804 | else if(target.dID == HWSTUB_TARGET_JZ) | ||
805 | { | ||
806 | struct hwstub_jz_desc_t jz = m_dev->GetJZInfo(); | ||
807 | m_soc = QString("jz%1").arg(jz.wChipID, 4, 16, QChar('0')); | ||
808 | if(jz.bRevision != 0) | ||
809 | m_soc.append(QChar(jz.bRevision).toLower()); | ||
810 | } | ||
473 | else if(target.dID == HWSTUB_TARGET_RK27) | 811 | else if(target.dID == HWSTUB_TARGET_RK27) |
474 | m_soc = "rk27x"; | 812 | m_soc = "rk27x"; |
475 | else if(target.dID == HWSTUB_TARGET_PP) | 813 | else if(target.dID == HWSTUB_TARGET_PP) |
@@ -549,95 +887,6 @@ bool HWStubIoBackend::Reload() | |||
549 | return true; | 887 | return true; |
550 | } | 888 | } |
551 | 889 | ||
552 | /** | ||
553 | * HWStubBackendHelper | ||
554 | */ | ||
555 | HWStubBackendHelper::HWStubBackendHelper() | ||
556 | { | ||
557 | #ifdef LIBUSB_NO_HOTPLUG | ||
558 | m_hotplug = false; | ||
559 | #else | ||
560 | m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); | ||
561 | if(m_hotplug) | ||
562 | { | ||
563 | int evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | | ||
564 | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT; | ||
565 | m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback( | ||
566 | NULL, (libusb_hotplug_event)evt, LIBUSB_HOTPLUG_ENUMERATE, | ||
567 | LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, | ||
568 | &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), | ||
569 | &m_hotplug_handle); | ||
570 | } | ||
571 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
572 | } | ||
573 | |||
574 | HWStubBackendHelper::~HWStubBackendHelper() | ||
575 | { | ||
576 | #ifndef LIBUSB_NO_HOTPLUG | ||
577 | if(m_hotplug) | ||
578 | libusb_hotplug_deregister_callback(NULL, m_hotplug_handle); | ||
579 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
580 | } | ||
581 | |||
582 | QList< HWStubDevice* > HWStubBackendHelper::GetDevList() | ||
583 | { | ||
584 | QList< HWStubDevice* > list; | ||
585 | libusb_device **dev_list; | ||
586 | ssize_t cnt = hwstub_get_device_list(NULL, &dev_list); | ||
587 | for(int i = 0; i < cnt; i++) | ||
588 | { | ||
589 | HWStubDevice *dev = new HWStubDevice(dev_list[i]); | ||
590 | /* filter out non-hwstub devices */ | ||
591 | if(dev->IsValid()) | ||
592 | list.push_back(dev); | ||
593 | else | ||
594 | delete dev; | ||
595 | } | ||
596 | libusb_free_device_list(dev_list, 1); | ||
597 | return list; | ||
598 | } | ||
599 | |||
600 | #ifndef LIBUSB_NO_HOTPLUG | ||
601 | void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev) | ||
602 | { | ||
603 | /* signal it */ | ||
604 | emit OnDevListChanged(arrived, dev); | ||
605 | } | ||
606 | |||
607 | int HWStubBackendHelper::HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev, | ||
608 | libusb_hotplug_event event, void *user_data) | ||
609 | { | ||
610 | Q_UNUSED(ctx); | ||
611 | HWStubBackendHelper *helper = reinterpret_cast< HWStubBackendHelper* >(user_data); | ||
612 | switch(event) | ||
613 | { | ||
614 | case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: helper->OnHotPlug(true, dev); break; | ||
615 | case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: helper->OnHotPlug(false, dev); break; | ||
616 | default: break; | ||
617 | } | ||
618 | return 0; | ||
619 | } | ||
620 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
621 | |||
622 | bool HWStubBackendHelper::HasHotPlugSupport() | ||
623 | { | ||
624 | return m_hotplug; | ||
625 | } | ||
626 | |||
627 | namespace | ||
628 | { | ||
629 | class lib_usb_init | ||
630 | { | ||
631 | public: | ||
632 | lib_usb_init() | ||
633 | { | ||
634 | libusb_init(NULL); | ||
635 | } | ||
636 | }; | ||
637 | |||
638 | lib_usb_init __lib_usb_init; | ||
639 | } | ||
640 | |||
641 | #endif /* HAVE_HWSTUB */ | 890 | #endif /* HAVE_HWSTUB */ |
642 | 891 | ||
643 | /** | 892 | /** |
diff --git a/utils/regtools/qeditor/backend.h b/utils/regtools/qeditor/backend.h index 17eeb44533..19e2cb5616 100644 --- a/utils/regtools/qeditor/backend.h +++ b/utils/regtools/qeditor/backend.h | |||
@@ -28,7 +28,9 @@ | |||
28 | #include <QMetaType> | 28 | #include <QMetaType> |
29 | #include <QAbstractItemModel> | 29 | #include <QAbstractItemModel> |
30 | #ifdef HAVE_HWSTUB | 30 | #ifdef HAVE_HWSTUB |
31 | #include "hwstub.h" | 31 | #include "hwstub.hpp" |
32 | #include "hwstub_usb.hpp" | ||
33 | #include "hwstub_uri.hpp" | ||
32 | #endif | 34 | #endif |
33 | #include "soc_desc.hpp" | 35 | #include "soc_desc.hpp" |
34 | 36 | ||
@@ -139,41 +141,124 @@ protected: | |||
139 | }; | 141 | }; |
140 | 142 | ||
141 | #ifdef HAVE_HWSTUB | 143 | #ifdef HAVE_HWSTUB |
144 | /* HWStub context manager: provides a centralized place to add/remove/get | ||
145 | * contexts */ | ||
146 | class HWStubManager : public QAbstractTableModel | ||
147 | { | ||
148 | Q_OBJECT | ||
149 | protected: | ||
150 | HWStubManager(); | ||
151 | public: | ||
152 | virtual ~HWStubManager(); | ||
153 | /* Get manager */ | ||
154 | static HWStubManager *Get(); | ||
155 | /* Clear the context list */ | ||
156 | void Clear(); | ||
157 | bool Add(const QString& name, const QString& uri); | ||
158 | /* Model */ | ||
159 | virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; | ||
160 | virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; | ||
161 | virtual QVariant data(const QModelIndex& index, int role) const; | ||
162 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; | ||
163 | virtual Qt::ItemFlags flags(const QModelIndex& index) const; | ||
164 | virtual bool setData(const QModelIndex& index, const QVariant& value, int role); | ||
165 | /* return predefined columns */ | ||
166 | int GetNameColumn() const; | ||
167 | int GetUriColumn() const; | ||
168 | std::shared_ptr< hwstub::context > GetContext(int row); | ||
169 | /* return a friendly name for a device */ | ||
170 | static QString GetFriendlyName(std::shared_ptr< hwstub::device > device); | ||
171 | |||
172 | protected: | ||
173 | struct Context | ||
174 | { | ||
175 | std::shared_ptr< hwstub::context > context; | ||
176 | QString name; | ||
177 | QString uri; | ||
178 | }; | ||
179 | |||
180 | std::vector< Context > m_list; /* list of context */ | ||
181 | static HWStubManager *g_inst; /* unique instance */ | ||
182 | }; | ||
183 | |||
184 | /* HWStub context model: provides access to the device list using Qt MVC model. */ | ||
185 | class HWStubContextModel : public QAbstractTableModel | ||
186 | { | ||
187 | Q_OBJECT | ||
188 | public: | ||
189 | HWStubContextModel(QObject *parent = 0); | ||
190 | virtual ~HWStubContextModel(); | ||
191 | void SetContext(std::shared_ptr< hwstub::context > context); | ||
192 | /* Model */ | ||
193 | virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; | ||
194 | virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; | ||
195 | virtual QVariant data(const QModelIndex& index, int role) const; | ||
196 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; | ||
197 | virtual Qt::ItemFlags flags(const QModelIndex& index) const; | ||
198 | /* return predefined columns */ | ||
199 | int GetNameColumn() const; | ||
200 | std::shared_ptr< hwstub::device > GetDevice(int row); | ||
201 | /* Add an entry in the model for "no selection", which will correspond to | ||
202 | * a dummy device. This function also allows the text to be customised. */ | ||
203 | void EnableDummy(bool en, const QString& text = ""); | ||
204 | |||
205 | private slots: | ||
206 | void OnDevChangeUnsafe(void *data); | ||
207 | protected: | ||
208 | QString GetFriendlyName(std::shared_ptr< hwstub::device > device); | ||
209 | void OnDevChangeLow(std::shared_ptr< hwstub::context > ctx, bool arrived, | ||
210 | std::shared_ptr< hwstub::device > device); | ||
211 | void OnDevChange(std::shared_ptr< hwstub::context > ctx, bool arrived, | ||
212 | std::shared_ptr< hwstub::device > device); | ||
213 | |||
214 | struct Device | ||
215 | { | ||
216 | QString name; | ||
217 | std::shared_ptr< hwstub::device > device; | ||
218 | }; | ||
219 | |||
220 | std::vector< Device > m_list; | ||
221 | std::weak_ptr< hwstub::context > m_context; | ||
222 | hwstub::context::callback_ref_t m_callback_ref; | ||
223 | bool m_has_dummy; | ||
224 | QString m_dummy_text; | ||
225 | }; | ||
226 | |||
227 | /* Abstract Virtual Class from where TCP and USB backend | ||
228 | * child classes are derived | ||
229 | */ | ||
142 | class HWStubDevice | 230 | class HWStubDevice |
143 | { | 231 | { |
144 | public: | 232 | public: |
145 | HWStubDevice(struct libusb_device *dev); | 233 | HWStubDevice(std::shared_ptr<hwstub::device> device); |
146 | HWStubDevice(const HWStubDevice *dev); | 234 | virtual ~HWStubDevice(); |
147 | ~HWStubDevice(); | 235 | |
236 | QString GetFriendlyName(); | ||
148 | bool IsValid(); | 237 | bool IsValid(); |
149 | bool Open(); | 238 | /* Calls below are cached */ |
150 | void Close(); | ||
151 | int GetBusNumber(); | ||
152 | int GetDevAddress(); | ||
153 | /* Calls below are cached and do not require the device to be opened */ | ||
154 | inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; } | 239 | inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; } |
155 | inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; } | 240 | inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; } |
156 | inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; } | 241 | inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; } |
157 | inline struct hwstub_pp_desc_t GetPPInfo() { return m_hwdev_pp; } | 242 | inline struct hwstub_pp_desc_t GetPPInfo() { return m_hwdev_pp; } |
158 | /* Calls below require the device to be opened */ | 243 | inline struct hwstub_jz_desc_t GetJZInfo() { return m_hwdev_jz; } |
159 | bool ReadMem(soc_addr_t addr, size_t length, void *buffer); | 244 | bool ReadMem(soc_addr_t addr, size_t length, void *buffer); |
160 | bool WriteMem(soc_addr_t addr, size_t length, void *buffer); | 245 | bool WriteMem(soc_addr_t addr, size_t length, void *buffer); |
161 | 246 | ||
162 | protected: | 247 | protected: |
163 | bool Probe(); | 248 | bool Probe(std::shared_ptr<hwstub::device> device); |
164 | void Init(struct libusb_device *dev); | ||
165 | 249 | ||
250 | std::shared_ptr<hwstub::handle> m_handle; | ||
166 | bool m_valid; | 251 | bool m_valid; |
167 | struct libusb_device *m_dev; | ||
168 | libusb_device_handle *m_handle; | ||
169 | struct hwstub_device_t *m_hwdev; | 252 | struct hwstub_device_t *m_hwdev; |
170 | struct hwstub_version_desc_t m_hwdev_ver; | 253 | struct hwstub_version_desc_t m_hwdev_ver; |
171 | struct hwstub_target_desc_t m_hwdev_target; | 254 | struct hwstub_target_desc_t m_hwdev_target; |
172 | struct hwstub_stmp_desc_t m_hwdev_stmp; | 255 | struct hwstub_stmp_desc_t m_hwdev_stmp; |
173 | struct hwstub_pp_desc_t m_hwdev_pp; | 256 | struct hwstub_pp_desc_t m_hwdev_pp; |
257 | struct hwstub_jz_desc_t m_hwdev_jz; | ||
258 | QString m_name; | ||
174 | }; | 259 | }; |
175 | 260 | ||
176 | /** NOTE the HWStub backend is never dirty: all writes are immediately committed */ | 261 | /** NOTE the HWStub backend is never dirty: all wrnew ites are immediately committed */ |
177 | class HWStubIoBackend : public IoBackend | 262 | class HWStubIoBackend : public IoBackend |
178 | { | 263 | { |
179 | Q_OBJECT | 264 | Q_OBJECT |
@@ -197,32 +282,6 @@ protected: | |||
197 | QString m_soc; | 282 | QString m_soc; |
198 | HWStubDevice *m_dev; | 283 | HWStubDevice *m_dev; |
199 | }; | 284 | }; |
200 | |||
201 | #if LIBUSB_API_VERSION < 0x01000102 | ||
202 | #define LIBUSB_NO_HOTPLUG | ||
203 | #endif | ||
204 | |||
205 | class HWStubBackendHelper : public QObject | ||
206 | { | ||
207 | Q_OBJECT | ||
208 | public: | ||
209 | HWStubBackendHelper(); | ||
210 | ~HWStubBackendHelper(); | ||
211 | bool HasHotPlugSupport(); | ||
212 | QList< HWStubDevice* > GetDevList(); | ||
213 | |||
214 | signals: | ||
215 | void OnDevListChanged(bool arrived, struct libusb_device *dev); | ||
216 | |||
217 | protected: | ||
218 | #ifndef LIBUSB_NO_HOTPLUG | ||
219 | void OnHotPlug(bool arrived, struct libusb_device *dev); | ||
220 | static int HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev, | ||
221 | libusb_hotplug_event event, void *user_data); | ||
222 | libusb_hotplug_callback_handle m_hotplug_handle; | ||
223 | #endif | ||
224 | bool m_hotplug; | ||
225 | }; | ||
226 | #endif | 285 | #endif |
227 | 286 | ||
228 | class SocFile | 287 | class SocFile |
diff --git a/utils/regtools/qeditor/mainwindow.cpp b/utils/regtools/qeditor/mainwindow.cpp index 8b83be6bae..69138a91b7 100644 --- a/utils/regtools/qeditor/mainwindow.cpp +++ b/utils/regtools/qeditor/mainwindow.cpp | |||
@@ -107,12 +107,18 @@ void DocumentTabWidget::OnCloseTab(int index) | |||
107 | MainWindow::MainWindow(Backend *backend) | 107 | MainWindow::MainWindow(Backend *backend) |
108 | :m_backend(backend) | 108 | :m_backend(backend) |
109 | { | 109 | { |
110 | QAction *new_regtab_act = new QAction(QIcon::fromTheme("document-new"), tr("Register &Tab"), this); | 110 | QAction *new_regtab_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentNew), |
111 | QAction *new_regedit_act = new QAction(QIcon::fromTheme("document-edit"), tr("Register &Editor"), this); | 111 | tr("Register &Tab"), this); |
112 | QAction *load_desc_act = new QAction(QIcon::fromTheme("document-open"), tr("&Soc Description"), this); | 112 | QAction *new_regedit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentEdit), |
113 | QAction *quit_act = new QAction(QIcon::fromTheme("application-exit"), tr("&Quit"), this); | 113 | tr("Register &Editor"), this); |
114 | QAction *about_act = new QAction(QIcon::fromTheme("help-about"), tr("&About"), this); | 114 | QAction *load_desc_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen), |
115 | QAction *about_qt_act = new QAction(QIcon::fromTheme("help-about"), tr("About &Qt"), this); | 115 | tr("&Soc Description"), this); |
116 | QAction *quit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::ApplicationExit), | ||
117 | tr("&Quit"), this); | ||
118 | QAction *about_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout), | ||
119 | tr("&About"), this); | ||
120 | QAction *about_qt_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout), | ||
121 | tr("About &Qt"), this); | ||
116 | 122 | ||
117 | connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab())); | 123 | connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab())); |
118 | connect(new_regedit_act, SIGNAL(triggered()), this, SLOT(OnNewRegEdit())); | 124 | connect(new_regedit_act, SIGNAL(triggered()), this, SLOT(OnNewRegEdit())); |
@@ -121,9 +127,10 @@ MainWindow::MainWindow(Backend *backend) | |||
121 | connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout())); | 127 | connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout())); |
122 | connect(about_qt_act, SIGNAL(triggered()), this, SLOT(OnAboutQt())); | 128 | connect(about_qt_act, SIGNAL(triggered()), this, SLOT(OnAboutQt())); |
123 | 129 | ||
124 | QMenu *file_menu = menuBar()->addMenu(tr("&File")); | 130 | QMenu *app_menu = new QMenu; |
125 | QMenu *new_submenu = file_menu->addMenu(QIcon::fromTheme("document-new"), "&New"); | 131 | QMenu *file_menu = app_menu->addMenu(tr("&File")); |
126 | QMenu *load_submenu = file_menu->addMenu(QIcon::fromTheme("document-open"), "&Load"); | 132 | QMenu *new_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentNew), "&New"); |
133 | QMenu *load_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen), "&Load"); | ||
127 | file_menu->addAction(quit_act); | 134 | file_menu->addAction(quit_act); |
128 | 135 | ||
129 | new_submenu->addAction(new_regtab_act); | 136 | new_submenu->addAction(new_regtab_act); |
@@ -131,17 +138,24 @@ MainWindow::MainWindow(Backend *backend) | |||
131 | 138 | ||
132 | load_submenu->addAction(load_desc_act); | 139 | load_submenu->addAction(load_desc_act); |
133 | 140 | ||
134 | QMenu *about_menu = menuBar()->addMenu(tr("&About")); | 141 | QMenu *about_menu = app_menu->addMenu(tr("&About")); |
135 | about_menu->addAction(about_act); | 142 | about_menu->addAction(about_act); |
136 | about_menu->addAction(about_qt_act); | 143 | about_menu->addAction(about_qt_act); |
137 | 144 | ||
138 | m_tab = new DocumentTabWidget(); | 145 | m_tab = new DocumentTabWidget(); |
139 | m_tab->setTabOpenable(true); | 146 | m_tab->setTabOpenable(true); |
140 | m_tab->setTabOpenMenu(new_submenu); | 147 | m_tab->setTabOpenMenu(new_submenu); |
148 | m_tab->setOtherMenu(app_menu); | ||
141 | 149 | ||
142 | setCentralWidget(m_tab); | 150 | setCentralWidget(m_tab); |
143 | 151 | ||
144 | ReadSettings(); | 152 | ReadSettings(); |
153 | #ifdef HAVE_HWSTUB | ||
154 | /* acquire hwstub manager */ | ||
155 | HWStubManager::Get()->setParent(this); | ||
156 | #endif | ||
157 | /* acquire icon manager */ | ||
158 | YIconManager::Get()->setParent(this); | ||
145 | 159 | ||
146 | OnNewRegTab(); | 160 | OnNewRegTab(); |
147 | } | 161 | } |
@@ -167,12 +181,12 @@ void MainWindow::OnAbout() | |||
167 | .arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION); | 181 | .arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION); |
168 | QMessageBox::about(this, "About", | 182 | QMessageBox::about(this, "About", |
169 | "<h1>QEditor</h1>" | 183 | "<h1>QEditor</h1>" |
170 | "<h2>Version "APP_VERSION"</h2>" | 184 | "<h2>Version " APP_VERSION "</h2>" |
171 | "<p>Written by Amaury Pouly</p>" | 185 | "<p>Written by Amaury Pouly</p>" |
172 | "<p>Libraries:</p>" | 186 | "<p>Libraries:</p>" |
173 | "<ul><li>soc_desc: " + soc_desc_ver + "</li>" | 187 | "<ul><li>soc_desc: " + soc_desc_ver + "</li>" |
174 | #ifdef HAVE_HWSTUB | 188 | #ifdef HAVE_HWSTUB |
175 | "<li>hwstub: "HWSTUB_VERSION"</li>" | 189 | "<li>hwstub: " HWSTUB_VERSION "</li>" |
176 | #else | 190 | #else |
177 | "<li>hwstub: not compiled in</li>" | 191 | "<li>hwstub: not compiled in</li>" |
178 | #endif | 192 | #endif |
diff --git a/utils/regtools/qeditor/qeditor.pro b/utils/regtools/qeditor/qeditor.pro index 0ec7c3dde1..5414f34e72 100644 --- a/utils/regtools/qeditor/qeditor.pro +++ b/utils/regtools/qeditor/qeditor.pro | |||
@@ -5,8 +5,9 @@ HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h \ | |||
5 | SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp \ | 5 | SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp \ |
6 | std_analysers.cpp settings.cpp utils.cpp regdisplaypanel.cpp regedit.cpp | 6 | std_analysers.cpp settings.cpp utils.cpp regdisplaypanel.cpp regedit.cpp |
7 | LIBS += -L../lib/ -lsocdesc -lxml2 | 7 | LIBS += -L../lib/ -lsocdesc -lxml2 |
8 | INCLUDEPATH += ../include/ ../../hwstub/lib | 8 | INCLUDEPATH += ../include/ ../../hwstub/include |
9 | DEPENDPATH += ../ | 9 | DEPENDPATH += ../ |
10 | CONFIG += c++11 | ||
10 | 11 | ||
11 | libsocdesc.commands = cd ../lib && make | 12 | libsocdesc.commands = cd ../lib && make |
12 | QMAKE_EXTRA_TARGETS += libsocdesc | 13 | QMAKE_EXTRA_TARGETS += libsocdesc |
diff --git a/utils/regtools/qeditor/regdisplaypanel.cpp b/utils/regtools/qeditor/regdisplaypanel.cpp index a72d280d6c..1c2f1db9a9 100644 --- a/utils/regtools/qeditor/regdisplaypanel.cpp +++ b/utils/regtools/qeditor/regdisplaypanel.cpp | |||
@@ -46,7 +46,7 @@ SocDisplayPanel::SocDisplayPanel(QWidget *parent, IoBackend *io_backend, | |||
46 | right_layout->addWidget(m_desc, 0); | 46 | right_layout->addWidget(m_desc, 0); |
47 | right_layout->addStretch(1); | 47 | right_layout->addStretch(1); |
48 | 48 | ||
49 | setTitle("System-on-Chip Description"); | 49 | setTitle(""); |
50 | setLayout(right_layout); | 50 | setLayout(right_layout); |
51 | } | 51 | } |
52 | 52 | ||
@@ -108,7 +108,7 @@ NodeDisplayPanel::NodeDisplayPanel(QWidget *parent, IoBackend *io_backend, | |||
108 | right_layout->addWidget(m_inst_desc, 0); | 108 | right_layout->addWidget(m_inst_desc, 0); |
109 | right_layout->addStretch(1); | 109 | right_layout->addStretch(1); |
110 | 110 | ||
111 | setTitle("Device Description"); | 111 | setTitle(""); |
112 | setLayout(right_layout); | 112 | setLayout(right_layout); |
113 | } | 113 | } |
114 | 114 | ||
@@ -126,6 +126,21 @@ QWidget *NodeDisplayPanel::GetWidget() | |||
126 | * RegDisplayPanel | 126 | * RegDisplayPanel |
127 | */ | 127 | */ |
128 | 128 | ||
129 | namespace | ||
130 | { | ||
131 | QString access_string(soc_desc::access_t acc, QString dflt = "") | ||
132 | { | ||
133 | switch(acc) | ||
134 | { | ||
135 | case soc_desc::UNSPECIFIED: return dflt; | ||
136 | case soc_desc::READ_ONLY: return "Read only"; | ||
137 | case soc_desc::READ_WRITE: return "Read-write"; | ||
138 | case soc_desc::WRITE_ONLY: return "Write-only"; | ||
139 | default: return ""; | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
129 | RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, | 144 | RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, |
130 | const soc_desc::node_inst_t& ref) | 145 | const soc_desc::node_inst_t& ref) |
131 | :QGroupBox(parent), m_io_backend(io_backend), m_node(ref), m_reg_font(font()) | 146 | :QGroupBox(parent), m_io_backend(io_backend), m_node(ref), m_reg_font(font()) |
@@ -139,16 +154,18 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, | |||
139 | m_reg_font.setKerning(false); | 154 | m_reg_font.setKerning(false); |
140 | 155 | ||
141 | QString reg_name = helper.GetPath(ref); | 156 | QString reg_name = helper.GetPath(ref); |
142 | QStringList names; | 157 | QStringList names, access; |
143 | QVector< soc_addr_t > addresses; | 158 | QVector< soc_addr_t > addresses; |
144 | names.append(reg_name); | 159 | names.append(reg_name); |
145 | addresses.append(ref.addr()); | 160 | addresses.append(ref.addr()); |
161 | access.append(access_string(ref.node().reg().get()->access)); | ||
146 | 162 | ||
147 | std::vector< soc_desc::variant_ref_t > variants = ref.node().reg().variants(); | 163 | std::vector< soc_desc::variant_ref_t > variants = ref.node().reg().variants(); |
148 | for(size_t i = 0; i < variants.size(); i++) | 164 | for(size_t i = 0; i < variants.size(); i++) |
149 | { | 165 | { |
150 | names.append(reg_name + "/" + QString::fromStdString(variants[i].get()->type)); | 166 | names.append(reg_name + "/" + QString::fromStdString(variants[i].get()->type)); |
151 | addresses.append(ref.addr() + variants[i].get()->offset); | 167 | addresses.append(ref.addr() + variants[i].get()->offset); |
168 | access.append(access_string(ref.node().reg().get()->access, access[0])); | ||
152 | } | 169 | } |
153 | 170 | ||
154 | QString str; | 171 | QString str; |
@@ -169,10 +186,20 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, | |||
169 | label_addr->setTextFormat(Qt::RichText); | 186 | label_addr->setTextFormat(Qt::RichText); |
170 | label_addr->setText(str_addr); | 187 | label_addr->setText(str_addr); |
171 | 188 | ||
189 | QString str_acc; | ||
190 | str_acc += "<table align=left>"; | ||
191 | for(int i = 0; i < names.size(); i++) | ||
192 | str_acc += "<tr><td><b>" + access[i] + "</b></td></tr>"; | ||
193 | str_acc += "</table>"; | ||
194 | QLabel *label_access = new QLabel; | ||
195 | label_access->setTextFormat(Qt::RichText); | ||
196 | label_access->setText(str_acc); | ||
197 | |||
172 | QHBoxLayout *top_layout = new QHBoxLayout; | 198 | QHBoxLayout *top_layout = new QHBoxLayout; |
173 | top_layout->addStretch(); | 199 | top_layout->addStretch(); |
174 | top_layout->addWidget(label_names); | 200 | top_layout->addWidget(label_names); |
175 | top_layout->addWidget(label_addr); | 201 | top_layout->addWidget(label_addr); |
202 | top_layout->addWidget(label_access); | ||
176 | top_layout->addStretch(); | 203 | top_layout->addStretch(); |
177 | 204 | ||
178 | m_raw_val_name = new QLabel; | 205 | m_raw_val_name = new QLabel; |
@@ -250,7 +277,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, | |||
250 | right_layout->addWidget(m_value_table); | 277 | right_layout->addWidget(m_value_table); |
251 | right_layout->addStretch(); | 278 | right_layout->addStretch(); |
252 | 279 | ||
253 | setTitle("Register Description"); | 280 | setTitle(""); |
254 | m_viewport = new QWidget; | 281 | m_viewport = new QWidget; |
255 | m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | 282 | m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
256 | m_viewport->setLayout(right_layout); | 283 | m_viewport->setLayout(right_layout); |
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp index 826452fdbd..bf86792c1e 100644 --- a/utils/regtools/qeditor/regedit.cpp +++ b/utils/regtools/qeditor/regedit.cpp | |||
@@ -107,14 +107,15 @@ SocEditPanel::SocEditPanel(const soc_desc::soc_ref_t& ref, QWidget *parent) | |||
107 | for(size_t i = 0; i < authors.size(); i++) | 107 | for(size_t i = 0; i < authors.size(); i++) |
108 | { | 108 | { |
109 | QTableWidgetItem *item = new QTableWidgetItem( | 109 | QTableWidgetItem *item = new QTableWidgetItem( |
110 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | 110 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", SocEditPanelDelType); |
111 | item->setToolTip("Remove this author"); | ||
111 | item->setFlags(Qt::ItemIsEnabled); | 112 | item->setFlags(Qt::ItemIsEnabled); |
112 | m_authors_list->setItem(i, 0, item); | 113 | m_authors_list->setItem(i, 0, item); |
113 | item = new QTableWidgetItem(QString::fromStdString(authors[i])); | 114 | item = new QTableWidgetItem(QString::fromStdString(authors[i])); |
114 | m_authors_list->setItem(i, 1, item); | 115 | m_authors_list->setItem(i, 1, item); |
115 | } | 116 | } |
116 | QTableWidgetItem *new_item = new QTableWidgetItem( | 117 | QTableWidgetItem *new_item = new QTableWidgetItem( |
117 | QIcon::fromTheme("list-add"), "", SocEditPanelAddType); | 118 | YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", SocEditPanelAddType); |
118 | new_item->setFlags(Qt::ItemIsEnabled); | 119 | new_item->setFlags(Qt::ItemIsEnabled); |
119 | m_authors_list->setItem(authors.size(), 0, new_item); | 120 | m_authors_list->setItem(authors.size(), 0, new_item); |
120 | new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType); | 121 | new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType); |
@@ -188,7 +189,8 @@ void SocEditPanel::OnAuthorActivated(QTableWidgetItem *item) | |||
188 | m_ref.get()->author.push_back("Anonymous"); | 189 | m_ref.get()->author.push_back("Anonymous"); |
189 | m_authors_list->insertRow(row); | 190 | m_authors_list->insertRow(row); |
190 | QTableWidgetItem *item = new QTableWidgetItem( | 191 | QTableWidgetItem *item = new QTableWidgetItem( |
191 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | 192 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", SocEditPanelDelType); |
193 | item->setToolTip("Remove this author"); | ||
192 | item->setFlags(Qt::ItemIsEnabled); | 194 | item->setFlags(Qt::ItemIsEnabled); |
193 | m_authors_list->setItem(row, 0, item); | 195 | m_authors_list->setItem(row, 0, item); |
194 | item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back())); | 196 | item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back())); |
@@ -386,7 +388,8 @@ NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref, | |||
386 | for(size_t i = 0; i < addrs.size(); i++) | 388 | for(size_t i = 0; i < addrs.size(); i++) |
387 | { | 389 | { |
388 | QTableWidgetItem *item = new QTableWidgetItem( | 390 | QTableWidgetItem *item = new QTableWidgetItem( |
389 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); | 391 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", NodeInstEditPanelDelType); |
392 | item->setToolTip("Remove this address"); | ||
390 | item->setFlags(Qt::ItemIsEnabled); | 393 | item->setFlags(Qt::ItemIsEnabled); |
391 | addr_list->setItem(i, 0, item); | 394 | addr_list->setItem(i, 0, item); |
392 | item = new QTableWidgetItem(); | 395 | item = new QTableWidgetItem(); |
@@ -394,7 +397,7 @@ NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref, | |||
394 | addr_list->setItem(i, 1, item); | 397 | addr_list->setItem(i, 1, item); |
395 | } | 398 | } |
396 | QTableWidgetItem *new_item = new QTableWidgetItem( | 399 | QTableWidgetItem *new_item = new QTableWidgetItem( |
397 | QIcon::fromTheme("list-add"), "", NodeInstEditPanelAddType); | 400 | YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", NodeInstEditPanelAddType); |
398 | new_item->setFlags(Qt::ItemIsEnabled); | 401 | new_item->setFlags(Qt::ItemIsEnabled); |
399 | addr_list->setItem(addrs.size(), 0, new_item); | 402 | addr_list->setItem(addrs.size(), 0, new_item); |
400 | new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType); | 403 | new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType); |
@@ -535,7 +538,8 @@ void NodeInstanceEditPanel::OnAddressActivated(QTableWidgetItem *item) | |||
535 | GetInstance().range.list.push_back(new_addr); | 538 | GetInstance().range.list.push_back(new_addr); |
536 | table->insertRow(row); | 539 | table->insertRow(row); |
537 | QTableWidgetItem *item = new QTableWidgetItem( | 540 | QTableWidgetItem *item = new QTableWidgetItem( |
538 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); | 541 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", NodeInstEditPanelDelType); |
542 | item->setToolTip("Remove this address"); | ||
539 | item->setFlags(Qt::ItemIsEnabled); | 543 | item->setFlags(Qt::ItemIsEnabled); |
540 | table->setItem(row, 0, item); | 544 | table->setItem(row, 0, item); |
541 | item = new QTableWidgetItem(); | 545 | item = new QTableWidgetItem(); |
@@ -828,7 +832,8 @@ RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget * | |||
828 | for(size_t i = 0; i < field.enum_.size(); i++) | 832 | for(size_t i = 0; i < field.enum_.size(); i++) |
829 | { | 833 | { |
830 | QTableWidgetItem *item = new QTableWidgetItem( | 834 | QTableWidgetItem *item = new QTableWidgetItem( |
831 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | 835 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegFieldEditPanelDelType); |
836 | item->setToolTip("Remove this enum"); | ||
832 | item->setFlags(Qt::ItemIsEnabled); | 837 | item->setFlags(Qt::ItemIsEnabled); |
833 | m_enum_table->setItem(i, 0, item); | 838 | m_enum_table->setItem(i, 0, item); |
834 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name)); | 839 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name)); |
@@ -840,7 +845,7 @@ RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget * | |||
840 | m_enum_table->setItem(i, 3, item); | 845 | m_enum_table->setItem(i, 3, item); |
841 | } | 846 | } |
842 | QTableWidgetItem *new_item = new QTableWidgetItem( | 847 | QTableWidgetItem *new_item = new QTableWidgetItem( |
843 | QIcon::fromTheme("list-add"), "", RegFieldEditPanelAddType); | 848 | YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", RegFieldEditPanelAddType); |
844 | new_item->setFlags(Qt::ItemIsEnabled); | 849 | new_item->setFlags(Qt::ItemIsEnabled); |
845 | m_enum_table->setItem(field.enum_.size(), 0, new_item); | 850 | m_enum_table->setItem(field.enum_.size(), 0, new_item); |
846 | new_item = new QTableWidgetItem("New field..."); | 851 | new_item = new QTableWidgetItem("New field..."); |
@@ -875,6 +880,13 @@ void RegFieldEditPanel::UpdateWidth() | |||
875 | m_range_validator->setWidth(m_ref.reg().get()->width); | 880 | m_range_validator->setWidth(m_ref.reg().get()->width); |
876 | } | 881 | } |
877 | 882 | ||
883 | void RegFieldEditPanel::UpdateRange() | ||
884 | { | ||
885 | soc_desc::field_t *field = m_ref.get(); | ||
886 | m_range_edit->setText(m_range_validator->generate( | ||
887 | field->pos + field->width - 1, field->pos)); | ||
888 | } | ||
889 | |||
878 | void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item) | 890 | void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item) |
879 | { | 891 | { |
880 | if(item->type() == RegFieldEditPanelDelType) | 892 | if(item->type() == RegFieldEditPanelDelType) |
@@ -895,7 +907,8 @@ void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item) | |||
895 | field.enum_.push_back(new_enum); | 907 | field.enum_.push_back(new_enum); |
896 | m_enum_table->insertRow(row); | 908 | m_enum_table->insertRow(row); |
897 | QTableWidgetItem *item = new QTableWidgetItem( | 909 | QTableWidgetItem *item = new QTableWidgetItem( |
898 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | 910 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegFieldEditPanelDelType); |
911 | item->setToolTip("Remove this enum"); | ||
899 | item->setFlags(Qt::ItemIsEnabled); | 912 | item->setFlags(Qt::ItemIsEnabled); |
900 | m_enum_table->setItem(row, 0, item); | 913 | m_enum_table->setItem(row, 0, item); |
901 | item = new QTableWidgetItem(QString::fromStdString(new_enum.name)); | 914 | item = new QTableWidgetItem(QString::fromStdString(new_enum.name)); |
@@ -977,7 +990,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
977 | 990 | ||
978 | m_value_model = new RegFieldTableModel(this); // view takes ownership | 991 | m_value_model = new RegFieldTableModel(this); // view takes ownership |
979 | m_value_model->SetRegister(*ref.get()); | 992 | m_value_model->SetRegister(*ref.get()); |
980 | m_value_model->SetReadOnly(true); | 993 | m_value_model->SetReadOnly(false); |
981 | 994 | ||
982 | m_sexy_display2 = new Unscroll<YRegDisplay>(this); | 995 | m_sexy_display2 = new Unscroll<YRegDisplay>(this); |
983 | m_sexy_display2->setFont(m_reg_font); | 996 | m_sexy_display2->setFont(m_reg_font); |
@@ -1016,29 +1029,61 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1016 | width_group_layout->addWidget(reg_size_32); | 1029 | width_group_layout->addWidget(reg_size_32); |
1017 | width_group_layout->addWidget(reg_size_16); | 1030 | width_group_layout->addWidget(reg_size_16); |
1018 | width_group_layout->addWidget(reg_size_8); | 1031 | width_group_layout->addWidget(reg_size_8); |
1019 | width_group_layout->addStretch(0); | ||
1020 | QGroupBox *width_group = new QGroupBox("Width"); | 1032 | QGroupBox *width_group = new QGroupBox("Width"); |
1021 | width_group->setLayout(width_group_layout); | 1033 | width_group->setLayout(width_group_layout); |
1022 | 1034 | ||
1035 | m_reg_access_group = new QButtonGroup(this); | ||
1036 | QRadioButton *reg_dflt = new QRadioButton("Unspecified"); | ||
1037 | QRadioButton *reg_rw = new QRadioButton("Read-Write"); | ||
1038 | QRadioButton *reg_ro = new QRadioButton("Read-Only"); | ||
1039 | QRadioButton *reg_wo = new QRadioButton("Write-Only"); | ||
1040 | m_reg_access_group->addButton(reg_dflt, soc_desc::UNSPECIFIED); | ||
1041 | m_reg_access_group->addButton(reg_rw, soc_desc::READ_WRITE); | ||
1042 | m_reg_access_group->addButton(reg_ro, soc_desc::READ_ONLY); | ||
1043 | m_reg_access_group->addButton(reg_wo, soc_desc::WRITE_ONLY); | ||
1044 | if(m_reg_access_group->button(m_ref.get()->access)) | ||
1045 | m_reg_access_group->button(m_ref.get()->access)->click(); | ||
1046 | QVBoxLayout *access_group_layout = new QVBoxLayout; | ||
1047 | access_group_layout->addWidget(reg_dflt); | ||
1048 | access_group_layout->addWidget(reg_rw); | ||
1049 | access_group_layout->addWidget(reg_ro); | ||
1050 | access_group_layout->addWidget(reg_wo); | ||
1051 | QGroupBox *access_group = new QGroupBox("Access"); | ||
1052 | access_group->setLayout(access_group_layout); | ||
1053 | |||
1054 | QVBoxLayout *width_access_layout = new QVBoxLayout; | ||
1055 | width_access_layout->addWidget(width_group); | ||
1056 | width_access_layout->addWidget(access_group); | ||
1057 | width_access_layout->addStretch(0); | ||
1058 | |||
1023 | m_variant_table = new QTableWidget; | 1059 | m_variant_table = new QTableWidget; |
1024 | m_variant_table->setColumnCount(3); | 1060 | m_variant_table->setColumnCount(4); |
1025 | m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | 1061 | m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); |
1026 | m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type")); | 1062 | m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type")); |
1027 | m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset")); | 1063 | m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset")); |
1064 | m_variant_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Access")); | ||
1028 | m_variant_table->verticalHeader()->setVisible(false); | 1065 | m_variant_table->verticalHeader()->setVisible(false); |
1029 | m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | 1066 | m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
1030 | m_variant_delegate = new SocFieldItemDelegate(this); | 1067 | m_variant_delegate = new SocFieldItemDelegate(this); |
1031 | m_variant_delegate->setItemEditorFactory(new QItemEditorFactory); | 1068 | m_variant_delegate->setItemEditorFactory(new QItemEditorFactory); |
1032 | m_variant_editor = new SocFieldEditorCreator; | 1069 | m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, |
1033 | m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_variant_editor); | 1070 | new SocFieldEditorCreator); |
1034 | m_variant_table->setItemDelegate(m_variant_delegate); | 1071 | m_variant_table->setItemDelegate(m_variant_delegate); |
1072 | m_access_delegate = new SocAccessItemDelegate("Unspecified", this); | ||
1073 | m_access_delegate->setItemEditorFactory(new QItemEditorFactory); | ||
1074 | // FIXME see QTBUG-30392 | ||
1075 | m_access_delegate->itemEditorFactory()->registerEditor( | ||
1076 | (QVariant::Type)qMetaTypeId< soc_desc::access_t >(), | ||
1077 | new SocAccessEditorCreator); | ||
1078 | m_variant_table->setItemDelegateForColumn(3, m_access_delegate); | ||
1035 | 1079 | ||
1036 | std::vector< soc_desc::variant_ref_t > variants = m_ref.variants(); | 1080 | std::vector< soc_desc::variant_ref_t > variants = m_ref.variants(); |
1037 | m_variant_table->setRowCount(variants.size() + 1); | 1081 | m_variant_table->setRowCount(variants.size() + 1); |
1038 | for(size_t i = 0; i < variants.size(); i++) | 1082 | for(size_t i = 0; i < variants.size(); i++) |
1039 | { | 1083 | { |
1040 | QTableWidgetItem *item = new QTableWidgetItem( | 1084 | QTableWidgetItem *item = new QTableWidgetItem( |
1041 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); | 1085 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegVariantEditPanelDelType); |
1086 | item->setToolTip("Remove this variant"); | ||
1042 | item->setFlags(Qt::ItemIsEnabled); | 1087 | item->setFlags(Qt::ItemIsEnabled); |
1043 | m_variant_table->setItem(i, 0, item); | 1088 | m_variant_table->setItem(i, 0, item); |
1044 | item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type)); | 1089 | item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type)); |
@@ -1046,9 +1091,12 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1046 | item = new QTableWidgetItem(); | 1091 | item = new QTableWidgetItem(); |
1047 | item->setData(Qt::EditRole, QVariant(variants[i].get()->offset)); | 1092 | item->setData(Qt::EditRole, QVariant(variants[i].get()->offset)); |
1048 | m_variant_table->setItem(i, 2, item); | 1093 | m_variant_table->setItem(i, 2, item); |
1094 | item = new QTableWidgetItem(); | ||
1095 | item->setData(Qt::EditRole, QVariant::fromValue(variants[i].get()->access)); | ||
1096 | m_variant_table->setItem(i, 3, item); | ||
1049 | } | 1097 | } |
1050 | QTableWidgetItem *new_item = new QTableWidgetItem( | 1098 | QTableWidgetItem *new_item = new QTableWidgetItem( |
1051 | QIcon::fromTheme("list-add"), "", RegVariantEditPanelAddType); | 1099 | YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", RegVariantEditPanelAddType); |
1052 | new_item->setFlags(Qt::ItemIsEnabled); | 1100 | new_item->setFlags(Qt::ItemIsEnabled); |
1053 | m_variant_table->setItem(variants.size(), 0, new_item); | 1101 | m_variant_table->setItem(variants.size(), 0, new_item); |
1054 | new_item = new QTableWidgetItem("New variant..."); | 1102 | new_item = new QTableWidgetItem("New variant..."); |
@@ -1069,7 +1117,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1069 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | 1117 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); |
1070 | 1118 | ||
1071 | QHBoxLayout *top_info_layout = new QHBoxLayout; | 1119 | QHBoxLayout *top_info_layout = new QHBoxLayout; |
1072 | top_info_layout->addWidget(width_group); | 1120 | top_info_layout->addLayout(width_access_layout); |
1073 | top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table)); | 1121 | top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table)); |
1074 | top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); | 1122 | top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); |
1075 | 1123 | ||
@@ -1087,9 +1135,9 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1087 | main_layout->addWidget(m_view_tab, 2); | 1135 | main_layout->addWidget(m_view_tab, 2); |
1088 | 1136 | ||
1089 | m_delete_action = new QAction("&Delete", this); | 1137 | m_delete_action = new QAction("&Delete", this); |
1090 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); | 1138 | m_delete_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListRemove)); |
1091 | m_new_action = new QAction("&New field", this); | 1139 | m_new_action = new QAction("&New field", this); |
1092 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | 1140 | m_new_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd)); |
1093 | 1141 | ||
1094 | setLayout(main_layout); | 1142 | setLayout(main_layout); |
1095 | 1143 | ||
@@ -1101,6 +1149,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1101 | connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this, | 1149 | connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this, |
1102 | SLOT(OnRegDisplayContextMenu(QPoint))); | 1150 | SLOT(OnRegDisplayContextMenu(QPoint))); |
1103 | connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int))); | 1151 | connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int))); |
1152 | connect(m_reg_access_group, SIGNAL(buttonClicked(int)), this, SLOT(OnAccessChanged(int))); | ||
1104 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete())); | 1153 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete())); |
1105 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew())); | 1154 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew())); |
1106 | connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, | 1155 | connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, |
@@ -1110,6 +1159,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | |||
1110 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | 1159 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); |
1111 | connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int))); | 1160 | connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int))); |
1112 | connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate())); | 1161 | connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate())); |
1162 | connect(m_value_model, SIGNAL(OnBitrangeModified(int)), this, SLOT(OnBitrangeModified(int))); | ||
1113 | } | 1163 | } |
1114 | 1164 | ||
1115 | void RegEditPanel::UpdateWidthRestrictions() | 1165 | void RegEditPanel::UpdateWidthRestrictions() |
@@ -1148,6 +1198,22 @@ void RegEditPanel::OnWidthChanged(int w) | |||
1148 | OnModified(); | 1198 | OnModified(); |
1149 | } | 1199 | } |
1150 | 1200 | ||
1201 | void RegEditPanel::OnBitrangeModified(int index) | ||
1202 | { | ||
1203 | soc_desc::register_t reg = m_value_model->GetRegister(); | ||
1204 | m_ref.get()->field[index].pos = reg.field[index].pos; | ||
1205 | m_ref.get()->field[index].width = reg.field[index].width; | ||
1206 | for(int i = 0; i < m_fields_tab->count(); i++) | ||
1207 | dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i))->UpdateRange(); | ||
1208 | OnModified(); | ||
1209 | } | ||
1210 | |||
1211 | void RegEditPanel::OnAccessChanged(int acc) | ||
1212 | { | ||
1213 | m_ref.get()->access = (soc_desc::access_t)acc; | ||
1214 | OnModified(); | ||
1215 | } | ||
1216 | |||
1151 | void RegEditPanel::OnDescEdited() | 1217 | void RegEditPanel::OnDescEdited() |
1152 | { | 1218 | { |
1153 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); | 1219 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); |
@@ -1169,9 +1235,11 @@ void RegEditPanel::OnVariantActivated(QTableWidgetItem *item) | |||
1169 | soc_desc::variant_t& variant = *m_ref.create_variant().get(); | 1235 | soc_desc::variant_t& variant = *m_ref.create_variant().get(); |
1170 | variant.type = "untyped"; | 1236 | variant.type = "untyped"; |
1171 | variant.offset = 0; | 1237 | variant.offset = 0; |
1238 | variant.access = soc_desc::UNSPECIFIED; | ||
1172 | m_variant_table->insertRow(row); | 1239 | m_variant_table->insertRow(row); |
1173 | QTableWidgetItem *item = new QTableWidgetItem( | 1240 | QTableWidgetItem *item = new QTableWidgetItem( |
1174 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); | 1241 | YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegVariantEditPanelDelType); |
1242 | item->setToolTip("Remove this variant"); | ||
1175 | item->setFlags(Qt::ItemIsEnabled); | 1243 | item->setFlags(Qt::ItemIsEnabled); |
1176 | m_variant_table->setItem(row, 0, item); | 1244 | m_variant_table->setItem(row, 0, item); |
1177 | item = new QTableWidgetItem(QString::fromStdString(variant.type)); | 1245 | item = new QTableWidgetItem(QString::fromStdString(variant.type)); |
@@ -1179,6 +1247,9 @@ void RegEditPanel::OnVariantActivated(QTableWidgetItem *item) | |||
1179 | item = new QTableWidgetItem(); | 1247 | item = new QTableWidgetItem(); |
1180 | item->setData(Qt::EditRole, QVariant(variant.offset)); | 1248 | item->setData(Qt::EditRole, QVariant(variant.offset)); |
1181 | m_variant_table->setItem(row, 2, item); | 1249 | m_variant_table->setItem(row, 2, item); |
1250 | item = new QTableWidgetItem(); | ||
1251 | item->setData(Qt::EditRole, QVariant::fromValue(variant.access)); | ||
1252 | m_variant_table->setItem(row, 3, item); | ||
1182 | OnModified(); | 1253 | OnModified(); |
1183 | } | 1254 | } |
1184 | } | 1255 | } |
@@ -1193,6 +1264,8 @@ void RegEditPanel::OnVariantValueChanged(QTableWidgetItem *item) | |||
1193 | var.type = item->text().toStdString(); | 1264 | var.type = item->text().toStdString(); |
1194 | else if(item->column() == 2) | 1265 | else if(item->column() == 2) |
1195 | var.offset = item->data(Qt::EditRole).value< soc_word_t >(); | 1266 | var.offset = item->data(Qt::EditRole).value< soc_word_t >(); |
1267 | else if(item->column() == 3) | ||
1268 | var.access = item->data(Qt::EditRole).value< soc_desc::access_t >(); | ||
1196 | OnModified(); | 1269 | OnModified(); |
1197 | } | 1270 | } |
1198 | 1271 | ||
@@ -1346,20 +1419,22 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
1346 | m_file_edit->setReadOnly(true); | 1419 | m_file_edit->setReadOnly(true); |
1347 | m_file_open = new QToolButton(this); | 1420 | m_file_open = new QToolButton(this); |
1348 | m_file_open->setText("Open"); | 1421 | m_file_open->setText("Open"); |
1349 | m_file_open->setIcon(QIcon::fromTheme("document-open")); | 1422 | m_file_open->setIcon(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen)); |
1350 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1423 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
1351 | QMenu *file_open_menu = new QMenu(this); | 1424 | QMenu *file_open_menu = new QMenu(this); |
1352 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); | 1425 | QAction *new_act = file_open_menu->addAction(YIconManager::Get()->GetIcon(YIconManager::DocumentNew), |
1426 | "New..."); | ||
1353 | m_file_open->setPopupMode(QToolButton::MenuButtonPopup); | 1427 | m_file_open->setPopupMode(QToolButton::MenuButtonPopup); |
1354 | m_file_open->setMenu(file_open_menu); | 1428 | m_file_open->setMenu(file_open_menu); |
1355 | 1429 | ||
1356 | m_file_save = new QToolButton(this); | 1430 | m_file_save = new QToolButton(this); |
1357 | m_file_save->setText("Save"); | 1431 | m_file_save->setText("Save"); |
1358 | m_file_save->setIcon(QIcon::fromTheme("document-save")); | 1432 | m_file_save->setIcon(YIconManager::Get()->GetIcon(YIconManager::DocumentSave)); |
1359 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1433 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
1360 | m_file_save->setPopupMode(QToolButton::MenuButtonPopup); | 1434 | m_file_save->setPopupMode(QToolButton::MenuButtonPopup); |
1361 | QMenu *file_save_menu = new QMenu(this); | 1435 | QMenu *file_save_menu = new QMenu(this); |
1362 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); | 1436 | QAction *saveas_act = file_save_menu->addAction(YIconManager::Get()->GetIcon(YIconManager::DocumentSaveAs), |
1437 | "Save as..."); | ||
1363 | m_file_save->setMenu(file_save_menu); | 1438 | m_file_save->setMenu(file_save_menu); |
1364 | 1439 | ||
1365 | QHBoxLayout *file_group_layout = new QHBoxLayout(); | 1440 | QHBoxLayout *file_group_layout = new QHBoxLayout(); |
@@ -1375,11 +1450,11 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
1375 | m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu); | 1450 | m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu); |
1376 | 1451 | ||
1377 | m_delete_action = new QAction("&Delete", this); | 1452 | m_delete_action = new QAction("&Delete", this); |
1378 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); | 1453 | m_delete_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListRemove)); |
1379 | m_new_action = new QAction("&New", this); | 1454 | m_new_action = new QAction("&New", this); |
1380 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | 1455 | m_new_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd)); |
1381 | m_create_action = new QAction("&Create register", this); | 1456 | m_create_action = new QAction("&Create register", this); |
1382 | m_create_action->setIcon(QIcon::fromTheme("folder-new")); | 1457 | m_create_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::FolderNew)); |
1383 | 1458 | ||
1384 | m_splitter->addWidget(m_soc_tree); | 1459 | m_splitter->addWidget(m_soc_tree); |
1385 | m_splitter->setStretchFactor(0, 0); | 1460 | m_splitter->setStretchFactor(0, 0); |
@@ -1605,8 +1680,8 @@ QIcon RegEdit::GetIconFromType(int type) | |||
1605 | { | 1680 | { |
1606 | switch(type) | 1681 | switch(type) |
1607 | { | 1682 | { |
1608 | case SocTreeSocType: return QIcon::fromTheme("computer"); | 1683 | case SocTreeSocType: return YIconManager::Get()->GetIcon(YIconManager::Computer); |
1609 | case SocTreeNodeType: return QIcon::fromTheme("cpu"); | 1684 | case SocTreeNodeType: return YIconManager::Get()->GetIcon(YIconManager::Cpu); |
1610 | case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight); | 1685 | case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight); |
1611 | default: return QIcon(); | 1686 | default: return QIcon(); |
1612 | } | 1687 | } |
@@ -1627,7 +1702,7 @@ void RegEdit::FixupItem(QTreeWidgetItem *item) | |||
1627 | UpdateName(item); | 1702 | UpdateName(item); |
1628 | if(!ValidateName(item->text(0))) | 1703 | if(!ValidateName(item->text(0))) |
1629 | { | 1704 | { |
1630 | item->setIcon(0, QIcon::fromTheme("dialog-error")); | 1705 | item->setIcon(0, YIconManager::Get()->GetIcon(YIconManager::DialogError)); |
1631 | if(item->text(0).size() == 0) | 1706 | if(item->text(0).size() == 0) |
1632 | { | 1707 | { |
1633 | MakeItalic(item, true); | 1708 | MakeItalic(item, true); |
@@ -1688,6 +1763,7 @@ void RegEdit::OnSocItemCreate() | |||
1688 | return; | 1763 | return; |
1689 | soc_desc::register_t reg; | 1764 | soc_desc::register_t reg; |
1690 | reg.width = 32; | 1765 | reg.width = 32; |
1766 | reg.access = soc_desc::UNSPECIFIED; | ||
1691 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); | 1767 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); |
1692 | node.get()->register_.push_back(reg); | 1768 | node.get()->register_.push_back(reg); |
1693 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg()); | 1769 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg()); |
diff --git a/utils/regtools/qeditor/regedit.h b/utils/regtools/qeditor/regedit.h index 2540500f29..893ec73421 100644 --- a/utils/regtools/qeditor/regedit.h +++ b/utils/regtools/qeditor/regedit.h | |||
@@ -165,6 +165,7 @@ public: | |||
165 | RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent = 0); | 165 | RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent = 0); |
166 | soc_desc::field_ref_t GetField(); | 166 | soc_desc::field_ref_t GetField(); |
167 | void UpdateWidth(); | 167 | void UpdateWidth(); |
168 | void UpdateRange(); | ||
168 | 169 | ||
169 | signals: | 170 | signals: |
170 | void OnModified(); | 171 | void OnModified(); |
@@ -203,12 +204,14 @@ protected slots: | |||
203 | void OnRegFieldDelete(); | 204 | void OnRegFieldDelete(); |
204 | void OnRegFieldNew(); | 205 | void OnRegFieldNew(); |
205 | void OnWidthChanged(int size); | 206 | void OnWidthChanged(int size); |
207 | void OnAccessChanged(int access); | ||
206 | void OnFieldModified(); | 208 | void OnFieldModified(); |
207 | void OnDescEdited(); | 209 | void OnDescEdited(); |
208 | void OnVariantActivated(QTableWidgetItem *item); | 210 | void OnVariantActivated(QTableWidgetItem *item); |
209 | void OnVariantValueChanged(QTableWidgetItem *item); | 211 | void OnVariantValueChanged(QTableWidgetItem *item); |
210 | void OnFieldRemove(int index); | 212 | void OnFieldRemove(int index); |
211 | void OnFieldCreate(); | 213 | void OnFieldCreate(); |
214 | void OnBitrangeModified(int index); | ||
212 | 215 | ||
213 | protected: | 216 | protected: |
214 | void DoModify(); | 217 | void DoModify(); |
@@ -228,8 +231,10 @@ protected: | |||
228 | QAction *m_delete_action; | 231 | QAction *m_delete_action; |
229 | QPoint m_menu_point; | 232 | QPoint m_menu_point; |
230 | SocFieldItemDelegate *m_variant_delegate; | 233 | SocFieldItemDelegate *m_variant_delegate; |
234 | SocAccessItemDelegate *m_access_delegate; | ||
231 | SocFieldEditorCreator *m_variant_editor; | 235 | SocFieldEditorCreator *m_variant_editor; |
232 | QButtonGroup *m_reg_size_group; | 236 | QButtonGroup *m_reg_size_group; |
237 | QButtonGroup *m_reg_access_group; | ||
233 | }; | 238 | }; |
234 | 239 | ||
235 | class RegEdit : public QWidget, public DocumentTab | 240 | class RegEdit : public QWidget, public DocumentTab |
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp index 2653908d41..c6a1f41ee9 100644 --- a/utils/regtools/qeditor/regtab.cpp +++ b/utils/regtools/qeditor/regtab.cpp | |||
@@ -75,10 +75,11 @@ RegTab::RegTab(Backend *backend, QWidget *parent) | |||
75 | QVBoxLayout *left_layout = new QVBoxLayout; | 75 | QVBoxLayout *left_layout = new QVBoxLayout; |
76 | left->setLayout(left_layout); | 76 | left->setLayout(left_layout); |
77 | 77 | ||
78 | QGroupBox *top_group = new QGroupBox("SOC selection"); | 78 | QGroupBox *top_group = new QGroupBox(""); |
79 | QVBoxLayout *top_group_layout = new QVBoxLayout; | 79 | QHBoxLayout *top_group_layout = new QHBoxLayout; |
80 | m_soc_selector = new QComboBox; | 80 | m_soc_selector = new QComboBox; |
81 | top_group_layout->addWidget(m_soc_selector); | 81 | top_group_layout->addWidget(new QLabel("SOC:")); |
82 | top_group_layout->addWidget(m_soc_selector, 1); | ||
82 | top_group->setLayout(top_group_layout); | 83 | top_group->setLayout(top_group_layout); |
83 | 84 | ||
84 | m_reg_tree = new QTreeWidget(); | 85 | m_reg_tree = new QTreeWidget(); |
@@ -96,7 +97,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent) | |||
96 | left_layout->addWidget(m_type_selector); | 97 | left_layout->addWidget(m_type_selector); |
97 | 98 | ||
98 | m_right_panel = new QVBoxLayout; | 99 | m_right_panel = new QVBoxLayout; |
99 | QGroupBox *data_sel_group = new QGroupBox("Data selection"); | 100 | QGroupBox *data_sel_group = new QGroupBox(""); |
100 | QHBoxLayout *data_sel_layout = new QHBoxLayout; | 101 | QHBoxLayout *data_sel_layout = new QHBoxLayout; |
101 | m_backend_selector = new BackendSelector(m_backend, this); | 102 | m_backend_selector = new BackendSelector(m_backend, this); |
102 | m_backend_selector->SetNothingMessage("<i>Select a data source to analyse its content.</i>"); | 103 | m_backend_selector->SetNothingMessage("<i>Select a data source to analyse its content.</i>"); |
@@ -108,6 +109,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent) | |||
108 | m_data_sel_reload = new QPushButton(this); | 109 | m_data_sel_reload = new QPushButton(this); |
109 | m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); | 110 | m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); |
110 | m_data_sel_reload->setToolTip("Reload data"); | 111 | m_data_sel_reload->setToolTip("Reload data"); |
112 | data_sel_layout->addWidget(new QLabel("Data:")); | ||
111 | data_sel_layout->addWidget(m_backend_selector); | 113 | data_sel_layout->addWidget(m_backend_selector); |
112 | data_sel_layout->addWidget(m_readonly_check); | 114 | data_sel_layout->addWidget(m_readonly_check); |
113 | data_sel_layout->addWidget(m_data_soc_label); | 115 | data_sel_layout->addWidget(m_data_soc_label); |
@@ -146,7 +148,9 @@ RegTab::RegTab(Backend *backend, QWidget *parent) | |||
146 | connect(m_type_selector, SIGNAL(currentChanged(int)), this, SLOT(OnTypeChanged(int))); | 148 | connect(m_type_selector, SIGNAL(currentChanged(int)), this, SLOT(OnTypeChanged(int))); |
147 | 149 | ||
148 | m_msg_select_id = SetMessage(MessageWidget::Information, | 150 | m_msg_select_id = SetMessage(MessageWidget::Information, |
149 | "You can browse the registers. Select a data source to analyse the values."); | 151 | "You can browse the registers using the left panel. " |
152 | "Select a data source at the top to analyse the values. " | ||
153 | "You can also use the analyzers available in the left panel, if any."); | ||
150 | m_msg_error_id = 0; | 154 | m_msg_error_id = 0; |
151 | 155 | ||
152 | QList< SocFileRef > socs = m_backend->GetSocFileList(); | 156 | QList< SocFileRef > socs = m_backend->GetSocFileList(); |
@@ -215,8 +219,7 @@ void RegTab::UpdateTabName() | |||
215 | else if(hwstub) | 219 | else if(hwstub) |
216 | { | 220 | { |
217 | HWStubDevice *dev = hwstub->GetDevice(); | 221 | HWStubDevice *dev = hwstub->GetDevice(); |
218 | SetTabName(QString("HWStub %1.%2").arg(dev->GetBusNumber()) | 222 | SetTabName(dev->GetFriendlyName()); |
219 | .arg(dev->GetDevAddress())); | ||
220 | } | 223 | } |
221 | #endif | 224 | #endif |
222 | else | 225 | else |
@@ -231,11 +234,21 @@ void RegTab::OnBackendSelect(IoBackend *backend) | |||
231 | HideMessage(m_msg_select_id); | 234 | HideMessage(m_msg_select_id); |
232 | HideMessage(m_msg_error_id); | 235 | HideMessage(m_msg_error_id); |
233 | m_io_backend = backend; | 236 | m_io_backend = backend; |
234 | SetReadOnlyIndicator(); | 237 | /* Check if the backend is valid, otherwise it might confuse the user */ |
235 | SetDataSocName(m_io_backend->GetSocName()); | 238 | if(m_io_backend->IsValid()) |
236 | OnDataSocActivated(m_io_backend->GetSocName()); | 239 | { |
237 | OnDataChanged(); | 240 | SetReadOnlyIndicator(); |
238 | UpdateTabName(); | 241 | SetDataSocName(m_io_backend->GetSocName()); |
242 | OnDataSocActivated(m_io_backend->GetSocName()); | ||
243 | OnDataChanged(); | ||
244 | UpdateTabName(); | ||
245 | } | ||
246 | /* But don't display it for the dummy backend either */ | ||
247 | else if(dynamic_cast< DummyIoBackend * >(m_io_backend) == 0) | ||
248 | { | ||
249 | m_msg_error_id = SetMessage(MessageWidget::Error, | ||
250 | "Data source is not available."); | ||
251 | } | ||
239 | } | 252 | } |
240 | 253 | ||
241 | void RegTab::SetReadOnlyIndicator() | 254 | void RegTab::SetReadOnlyIndicator() |
@@ -267,6 +280,7 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current) | |||
267 | 280 | ||
268 | void RegTab::DisplayNode(const soc_desc::node_inst_t& ref) | 281 | void RegTab::DisplayNode(const soc_desc::node_inst_t& ref) |
269 | { | 282 | { |
283 | HideMessage(m_msg_select_id); | ||
270 | if(ref.node().is_root()) | 284 | if(ref.node().is_root()) |
271 | SetPanel(new SocDisplayPanel(this, m_io_backend, ref.soc())); | 285 | SetPanel(new SocDisplayPanel(this, m_io_backend, ref.soc())); |
272 | else if(ref.node().reg().valid()) | 286 | else if(ref.node().reg().valid()) |
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 | */ |
diff --git a/utils/regtools/qeditor/utils.h b/utils/regtools/qeditor/utils.h index 026466fae0..83992274b7 100644 --- a/utils/regtools/qeditor/utils.h +++ b/utils/regtools/qeditor/utils.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <QScrollBar> | 40 | #include <QScrollBar> |
41 | #include <QGroupBox> | 41 | #include <QGroupBox> |
42 | #include <QSortFilterProxyModel> | 42 | #include <QSortFilterProxyModel> |
43 | #include <QDebug> | ||
43 | #include "settings.h" | 44 | #include "settings.h" |
44 | #include "backend.h" | 45 | #include "backend.h" |
45 | 46 | ||
@@ -180,6 +181,50 @@ protected: | |||
180 | soc_desc::field_t m_field; | 181 | soc_desc::field_t m_field; |
181 | }; | 182 | }; |
182 | 183 | ||
184 | Q_DECLARE_METATYPE(soc_desc::access_t) | ||
185 | |||
186 | class SocAccessItemDelegate: public QStyledItemDelegate | ||
187 | { | ||
188 | public: | ||
189 | SocAccessItemDelegate(const QString& unspec_text, QObject *parent = 0) | ||
190 | :QStyledItemDelegate(parent), m_unspec_text(unspec_text) {} | ||
191 | |||
192 | virtual QString displayText(const QVariant& value, const QLocale& locale) const; | ||
193 | protected: | ||
194 | QString m_unspec_text; | ||
195 | }; | ||
196 | |||
197 | class SocAccessEditor : public QComboBox | ||
198 | { | ||
199 | Q_OBJECT | ||
200 | Q_PROPERTY(soc_desc::access_t access READ access WRITE setAccess USER true) | ||
201 | public: | ||
202 | SocAccessEditor(const QString& unspec_text, QWidget *parent = 0); | ||
203 | virtual ~SocAccessEditor(); | ||
204 | |||
205 | soc_desc::access_t access() const; | ||
206 | void setAccess(soc_desc::access_t acc); | ||
207 | |||
208 | protected slots: | ||
209 | /* bla */ | ||
210 | |||
211 | protected: | ||
212 | soc_desc::access_t m_access; | ||
213 | }; | ||
214 | |||
215 | class SocAccessEditorCreator : public QItemEditorCreatorBase | ||
216 | { | ||
217 | public: | ||
218 | SocAccessEditorCreator(const QString& unspec_text = "Unspecified") | ||
219 | :m_unspec_text(unspec_text) {} | ||
220 | |||
221 | virtual QWidget *createWidget(QWidget *parent) const; | ||
222 | virtual QByteArray valuePropertyName() const; | ||
223 | |||
224 | protected: | ||
225 | QString m_unspec_text; | ||
226 | }; | ||
227 | |||
183 | class SocFieldCachedValue | 228 | class SocFieldCachedValue |
184 | { | 229 | { |
185 | public: | 230 | public: |
@@ -209,8 +254,11 @@ public: | |||
209 | SocFieldBitRange(int first, int last):m_first_bit(first), m_last_bit(last) {} | 254 | SocFieldBitRange(int first, int last):m_first_bit(first), m_last_bit(last) {} |
210 | unsigned GetFirstBit() const { return m_first_bit; } | 255 | unsigned GetFirstBit() const { return m_first_bit; } |
211 | unsigned GetLastBit() const { return m_last_bit; } | 256 | unsigned GetLastBit() const { return m_last_bit; } |
257 | void SetFirstBit(unsigned bit) { m_first_bit = bit; } | ||
258 | void SetLastBit(unsigned bit) { m_last_bit = bit; } | ||
212 | 259 | ||
213 | bool operator<(const SocFieldBitRange& o) const; | 260 | bool operator<(const SocFieldBitRange& o) const; |
261 | bool operator!=(const SocFieldBitRange& o) const; | ||
214 | protected: | 262 | protected: |
215 | unsigned m_first_bit, m_last_bit; | 263 | unsigned m_first_bit, m_last_bit; |
216 | }; | 264 | }; |
@@ -301,6 +349,7 @@ public: | |||
301 | 349 | ||
302 | signals: | 350 | signals: |
303 | void OnValueModified(int index); | 351 | void OnValueModified(int index); |
352 | void OnBitrangeModified(int index); | ||
304 | 353 | ||
305 | protected: | 354 | protected: |
306 | void RecomputeTheme(); | 355 | void RecomputeTheme(); |
@@ -337,19 +386,79 @@ protected: | |||
337 | bool lessThan(const QModelIndex& left, const QModelIndex& right) const; | 386 | bool lessThan(const QModelIndex& left, const QModelIndex& right) const; |
338 | }; | 387 | }; |
339 | 388 | ||
389 | class YRegDisplay; | ||
390 | class YRegDisplayItemDelegate; | ||
391 | |||
392 | class YRegDisplayItemEditor : public QWidget | ||
393 | { | ||
394 | Q_OBJECT | ||
395 | public: | ||
396 | YRegDisplayItemEditor(QWidget *parent, YRegDisplay *display, | ||
397 | YRegDisplayItemDelegate *delegate, QModelIndex bitrange_index, | ||
398 | QModelIndex name_index); | ||
399 | virtual ~YRegDisplayItemEditor(); | ||
400 | void setEditorData(QModelIndex bitrange_index, QModelIndex name_index); | ||
401 | void getEditorData(QVariant& name, QVariant& birange); | ||
402 | |||
403 | protected: | ||
404 | virtual void paintEvent(QPaintEvent *event); | ||
405 | virtual void mouseMoveEvent(QMouseEvent *event); | ||
406 | virtual void mousePressEvent(QMouseEvent *event); | ||
407 | virtual void mouseReleaseEvent(QMouseEvent *event); | ||
408 | virtual void leaveEvent(QEvent *event); | ||
409 | |||
410 | enum Zone | ||
411 | { | ||
412 | NoZone, | ||
413 | MoveZone, | ||
414 | ResizeLeftZone, | ||
415 | ResizeRightZone | ||
416 | }; | ||
417 | |||
418 | Zone GetZone(const QPoint& pt); | ||
419 | |||
420 | YRegDisplayItemDelegate *m_display_delegate; | ||
421 | YRegDisplay *m_display; | ||
422 | QModelIndex m_bitrange_index, m_name_index; | ||
423 | enum | ||
424 | { | ||
425 | Idle, | ||
426 | InResizeZone, | ||
427 | InMoveZone, | ||
428 | Moving, | ||
429 | ResizingLeft, | ||
430 | ResizingRight, | ||
431 | }m_state; | ||
432 | int m_col_width; | ||
433 | int m_resize_margin; | ||
434 | int m_move_offset; | ||
435 | SocFieldBitRange m_bitrange; | ||
436 | }; | ||
437 | |||
340 | class YRegDisplayItemDelegate : public QStyledItemDelegate | 438 | class YRegDisplayItemDelegate : public QStyledItemDelegate |
341 | { | 439 | { |
440 | Q_OBJECT | ||
441 | friend class YRegDisplayItemEditor; | ||
342 | public: | 442 | public: |
343 | YRegDisplayItemDelegate(QObject *parent = 0); | 443 | YRegDisplayItemDelegate(QObject *parent = 0); |
344 | virtual void paint(QPainter * painter, const QStyleOptionViewItem& option, | 444 | virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, |
345 | const QModelIndex & index) const; | 445 | const QModelIndex& index) const; |
446 | virtual void MyPaint(QPainter *painter, const QStyleOptionViewItemV4& option) const; | ||
346 | virtual QSize sizeHint(const QStyleOptionViewItem& option, | 447 | virtual QSize sizeHint(const QStyleOptionViewItem& option, |
347 | const QModelIndex & index) const; | 448 | const QModelIndex& index) const; |
449 | /* don't bother using the item factory and such, we only use this delegate | ||
450 | * for very specific models anyway */ | ||
451 | virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, | ||
452 | const QModelIndex& index) const; | ||
453 | virtual void setEditorData(QWidget *editor, const QModelIndex& index) const; | ||
454 | virtual void setModelData(QWidget *editor, QAbstractItemModel *model, | ||
455 | const QModelIndex& index) const; | ||
348 | }; | 456 | }; |
349 | 457 | ||
350 | class YRegDisplay : public QAbstractItemView | 458 | class YRegDisplay : public QAbstractItemView |
351 | { | 459 | { |
352 | Q_OBJECT | 460 | Q_OBJECT |
461 | friend class YRegDisplayItemEditor; | ||
353 | public: | 462 | public: |
354 | YRegDisplay(QWidget *parent = 0); | 463 | YRegDisplay(QWidget *parent = 0); |
355 | virtual QModelIndex indexAt(const QPoint& point) const; | 464 | virtual QModelIndex indexAt(const QPoint& point) const; |
@@ -360,6 +469,8 @@ public: | |||
360 | void setWidth(int nr_bits); | 469 | void setWidth(int nr_bits); |
361 | /* returns the bit column at a point, or -1 if none except if closest=true */ | 470 | /* returns the bit column at a point, or -1 if none except if closest=true */ |
362 | int bitColumnAt(const QPoint& point, bool closest = true) const; | 471 | int bitColumnAt(const QPoint& point, bool closest = true) const; |
472 | /* return rect for a bitrange */ | ||
473 | QRect BitrangeRect(const SocFieldBitRange& range) const; | ||
363 | 474 | ||
364 | protected slots: | 475 | protected slots: |
365 | virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); | 476 | virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); |
@@ -509,18 +620,20 @@ protected: | |||
509 | QLineEdit *m_data_sel_edit; | 620 | QLineEdit *m_data_sel_edit; |
510 | #ifdef HAVE_HWSTUB | 621 | #ifdef HAVE_HWSTUB |
511 | QComboBox *m_dev_selector; | 622 | QComboBox *m_dev_selector; |
512 | HWStubBackendHelper m_hwstub_helper; | 623 | QComboBox *m_ctx_selector; |
624 | QPushButton *m_ctx_manage_button; | ||
625 | HWStubContextModel *m_ctx_model; | ||
626 | HWStubManager *m_ctx_manager; | ||
513 | #endif | 627 | #endif |
514 | QLabel *m_nothing_text; | 628 | QLabel *m_nothing_text; |
515 | 629 | ||
516 | private slots: | 630 | private slots: |
631 | void OnDataSelChanged(int index); | ||
517 | #ifdef HAVE_HWSTUB | 632 | #ifdef HAVE_HWSTUB |
518 | void OnDevListChanged(); | 633 | void OnContextSelChanged(int index); |
519 | void OnDevChanged(int index); | 634 | void OnDeviceSelChanged(int index); |
520 | void OnDevListChanged2(bool, struct libusb_device *); | 635 | void OnDeviceSelActivated(int index); |
521 | void ClearDevList(); | ||
522 | #endif | 636 | #endif |
523 | void OnDataSelChanged(int index); | ||
524 | }; | 637 | }; |
525 | 638 | ||
526 | class MessageWidget : public QFrame | 639 | class MessageWidget : public QFrame |
@@ -567,6 +680,7 @@ public: | |||
567 | inline bool tabOpenable() const { return m_tab_openable; } | 680 | inline bool tabOpenable() const { return m_tab_openable; } |
568 | void setTabOpenable(bool openable); | 681 | void setTabOpenable(bool openable); |
569 | void setTabOpenMenu(QMenu *menu); | 682 | void setTabOpenMenu(QMenu *menu); |
683 | void setOtherMenu(QMenu *menu); | ||
570 | 684 | ||
571 | signals: | 685 | signals: |
572 | void tabOpenRequested(); | 686 | void tabOpenRequested(); |
@@ -577,6 +691,52 @@ protected slots: | |||
577 | protected: | 691 | protected: |
578 | bool m_tab_openable; | 692 | bool m_tab_openable; |
579 | QToolButton *m_tab_open_button; | 693 | QToolButton *m_tab_open_button; |
694 | QToolButton *m_other_button; | ||
695 | }; | ||
696 | |||
697 | class YIconManager : public QObject | ||
698 | { | ||
699 | Q_OBJECT | ||
700 | protected: | ||
701 | YIconManager(); | ||
702 | public: | ||
703 | virtual ~YIconManager(); | ||
704 | /* list of icons */ | ||
705 | enum IconType | ||
706 | { | ||
707 | ListAdd = 0, | ||
708 | ListRemove, | ||
709 | DocumentNew, | ||
710 | DocumentEdit, | ||
711 | DocumentOpen, | ||
712 | DocumentSave, | ||
713 | DocumentSaveAs, | ||
714 | Preferences, | ||
715 | FolderNew, | ||
716 | Computer, | ||
717 | Cpu, | ||
718 | DialogError, | ||
719 | ViewRefresh, | ||
720 | SytemRun, | ||
721 | ApplicationExit, | ||
722 | HelpAbout, | ||
723 | FormatTextBold, | ||
724 | FormatTextItalic, | ||
725 | FormatTextUnderline, | ||
726 | TextGeneric, | ||
727 | MultimediaPlayer, | ||
728 | MaxIcon | ||
729 | }; | ||
730 | /* return instance */ | ||
731 | static YIconManager *Get(); | ||
732 | QIcon GetIcon(IconType it); | ||
733 | |||
734 | protected: | ||
735 | void Render(IconType type); | ||
736 | |||
737 | static YIconManager *m_singleton; // single instance | ||
738 | QIcon m_icon[MaxIcon]; /* list add icon */ | ||
739 | QString m_icon_name[MaxIcon]; /* icon name from theme */ | ||
580 | }; | 740 | }; |
581 | 741 | ||
582 | class Misc | 742 | class Misc |