11#include < string.h>
22#include < algorithm>
3+ #include < QtGui/QClipboard>
4+ #include < QtGui/QGuiApplication>
5+ #include < QtCore/QStringList>
36#include " strings.h"
47#include " view.h"
58#include " fontsettings.h"
@@ -193,12 +196,53 @@ StringsTreeView::StringsTreeView(StringsWidget* parent, TriageView* view, Binary
193196 setRootIsDecorated (false );
194197 setUniformRowHeights (true );
195198 setSortingEnabled (true );
199+ setSelectionMode (QAbstractItemView::ExtendedSelection);
200+ setSelectionBehavior (QAbstractItemView::SelectRows);
201+ setAllColumnsShowFocus (true );
196202 sortByColumn (0 , Qt::AscendingOrder);
197203
198204 setFont (getMonospaceFont (this ));
199205
200206 connect (selectionModel (), &QItemSelectionModel::currentChanged, this , &StringsTreeView::stringSelected);
201207 connect (this , &QTreeView::doubleClicked, this , &StringsTreeView::stringDoubleClicked);
208+
209+ m_actionHandler.bindAction (" Copy" , UIAction ([this ]() { copySelection (); }, [this ]() { return canCopySelection (); }));
210+ }
211+
212+ void StringsTreeView::copySelection ()
213+ {
214+ if (!model () || !selectionModel ())
215+ return ;
216+
217+ QModelIndexList rows = selectionModel ()->selectedRows ();
218+ if (rows.isEmpty ())
219+ return ;
220+
221+ std::sort (rows.begin (), rows.end (), [](const QModelIndex& a, const QModelIndex& b) { return a.row () < b.row (); });
222+
223+ QStringList lines;
224+ for (const QModelIndex& rowIndex : rows)
225+ {
226+ QStringList cells;
227+ for (int column = 0 ; column < m_model->columnCount (QModelIndex ()); column++)
228+ {
229+ if (isColumnHidden (column))
230+ continue ;
231+
232+ QModelIndex idx = m_model->index (rowIndex.row (), column, QModelIndex ());
233+ cells << m_model->data (idx, Qt::DisplayRole).toString ();
234+ }
235+ lines << cells.join (" \t " );
236+ }
237+
238+ if (QClipboard* clipboard = QGuiApplication::clipboard ())
239+ clipboard->setText (lines.join (" \n " ));
240+ }
241+
242+
243+ bool StringsTreeView::canCopySelection () const
244+ {
245+ return !selectionModel ()->selectedRows ().isEmpty ();
202246}
203247
204248
@@ -275,6 +319,12 @@ void StringsTreeView::keyPressEvent(QKeyEvent* event)
275319 if (sel.size () != 0 )
276320 stringDoubleClicked (sel[0 ]);
277321 }
322+ else if (event->matches (QKeySequence::Copy))
323+ {
324+ copySelection ();
325+ event->accept ();
326+ return ;
327+ }
278328 QTreeView::keyPressEvent (event);
279329}
280330
@@ -295,4 +345,4 @@ StringsWidget::StringsWidget(QWidget* parent, TriageView* view, BinaryViewRef da
295345void StringsWidget::showFilter (const QString& filter)
296346{
297347 m_filter->showFilter (filter);
298- }
348+ }
0 commit comments