@@ -17,6 +17,9 @@ limitations under the License.
1717#include < QPainter>
1818#include < QHeaderView>
1919#include < QLineEdit>
20+ #include < QGuiApplication>
21+ #include < QMimeData>
22+ #include < QClipboard>
2023#include " stackwidget.h"
2124#include " fmt/format.h"
2225
@@ -409,6 +412,18 @@ DebugStackWidget::DebugStackWidget(const QString& name, ViewFrame* view, BinaryV
409412 layout->addWidget (m_table);
410413 setLayout (layout);
411414
415+ m_actionHandler.setupActionHandler (this );
416+ m_contextMenuManager = new ContextMenuManager (this );
417+ m_menu = new Menu ();
418+
419+ m_menu->addAction (" Copy" , " Options" , MENU_ORDER_NORMAL);
420+ m_actionHandler.bindAction (" Copy" , UIAction ([&]() { copy (); }, [&]() { return selectionNotEmpty (); }));
421+
422+ QString actionName = QString::fromStdString (" Copy All Stack Entries" );
423+ UIAction::registerAction (actionName);
424+ m_menu->addAction (actionName, " Options" , MENU_ORDER_NORMAL);
425+ m_actionHandler.bindAction (actionName, UIAction ([this ]() { copyAll (); }));
426+
412427 updateContent ();
413428}
414429
@@ -421,6 +436,101 @@ void DebugStackWidget::notifyStackChanged(std::vector<DebugStackItem> stackItems
421436}
422437
423438
439+ void DebugStackWidget::contextMenuEvent (QContextMenuEvent* event)
440+ {
441+ showContextMenu ();
442+ }
443+
444+
445+ void DebugStackWidget::showContextMenu ()
446+ {
447+ m_contextMenuManager->show (m_menu, &m_actionHandler);
448+ }
449+
450+
451+ bool DebugStackWidget::selectionNotEmpty ()
452+ {
453+ QModelIndexList sel = m_table->selectionModel ()->selectedRows ();
454+ return !sel.empty ();
455+ }
456+
457+
458+ void DebugStackWidget::copy ()
459+ {
460+ QModelIndexList sel = m_table->selectionModel ()->selectedRows ();
461+ if (sel.empty ())
462+ return ;
463+
464+ QString text;
465+ for (int i = 0 ; i < sel.size (); i++)
466+ {
467+ if (i > 0 )
468+ text += " \n " ;
469+
470+ int row = sel[i].row ();
471+ if (row < 0 || row >= m_model->rowCount ())
472+ continue ;
473+
474+ DebugStackItem item = m_model->getRow (row);
475+
476+ // Format: Offset Address Value Hint
477+ QString offsetStr;
478+ ptrdiff_t offset = item.offset ();
479+ if (offset < 0 )
480+ offsetStr = QString::asprintf (" -0x%" PRIx64, (uint64_t )-offset);
481+ else
482+ offsetStr = QString::asprintf (" 0x%" PRIx64, (uint64_t )offset);
483+
484+ text += QString::asprintf (" %s 0x%" PRIx64 " 0x%" PRIx64 " %s" ,
485+ offsetStr.toStdString ().c_str (),
486+ item.address (),
487+ item.value (),
488+ item.hint ().c_str ());
489+ }
490+
491+ auto * clipboard = QGuiApplication::clipboard ();
492+ clipboard->clear ();
493+ auto * mime = new QMimeData ();
494+ mime->setText (text);
495+ clipboard->setMimeData (mime);
496+ }
497+
498+
499+ void DebugStackWidget::copyAll ()
500+ {
501+ QString text;
502+ int rowCount = m_model->rowCount ();
503+
504+ for (int row = 0 ; row < rowCount; row++)
505+ {
506+ if (row > 0 )
507+ text += " \n " ;
508+
509+ DebugStackItem item = m_model->getRow (row);
510+
511+ // Format: Offset Address Value Hint
512+ QString offsetStr;
513+ ptrdiff_t offset = item.offset ();
514+ if (offset < 0 )
515+ offsetStr = QString::asprintf (" -0x%" PRIx64, (uint64_t )-offset);
516+ else
517+ offsetStr = QString::asprintf (" 0x%" PRIx64, (uint64_t )offset);
518+
519+ text += QString::asprintf (" %s 0x%" PRIx64 " 0x%" PRIx64 " %s" ,
520+ offsetStr.toStdString ().c_str (),
521+ item.address (),
522+ item.value (),
523+ item.hint ().c_str ());
524+ }
525+
526+ auto * clipboard = QGuiApplication::clipboard ();
527+ clipboard->clear ();
528+ auto * mime = new QMimeData ();
529+ mime->setText (text);
530+ clipboard->setMimeData (mime);
531+ }
532+
533+
424534// void DebugStackWidget::notifyFontChanged()
425535// {
426536// m_delegate->updateFonts();
0 commit comments