<commit_before>import logging
import re
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QDoubleValidator
from PyQt5.QtWidgets import \
  QWidget, QLabel, QVBoxLayout, QHBoxLayout, QGridLayout, \
  QLineEdit, QFrame, QCheckBox, QSpinBox, QPushButton, \
  QButtonGroup, QRadioButton, QComboBox, QTableWidgetItem, \
  QAbstractScrollArea, QHeaderView, QApplication

from tools import CubicSpline, ToolBase, FitTool, IADTool
from commonwidgets import TableWidget


class ToolWidgetBase(QWidget):
  plotRequested = pyqtSignal(ToolBase, bool, name='plotRequested')

  def __init__(self):
    super().__init__()
    self.tool = self.toolClass()
    self.tool.cleared.connect(self.clear)
    self.tool.added.connect(self.add)

  def name(self):
    return self.toolClass.name

  def label(self):
    return self.toolClass.label

  def clear(self):
    raise NotImplementedError()

  def add(self, data):
    raise NotImplementedError()


class FitToolWidget(ToolWidgetBase):
  toolClass = FitTool

  def __init__(self):
    super().__init__()

  def clear(self):
    pass

  def add(self, data):
    pass


class IADToolWidget(ToolWidgetBase):
  toolClass = IADTool
  columnLabels = ['Name', 'IAD X', 'IAD Y', 'X offset', 'Weight center', 'Peak x', 'Peak y']

  def __init__(self):
    super().__init__()

    vbox = QVBoxLayout()
    self.setLayout(vbox)

    self.linesTable = TableWidget()
    self.linesTable.cellChanged.connect(self.linesTableCellChanged)
    vbox.addWidget(self.linesTable)

    self.linesTableCopyButton = QPushButton('Copy')
    self.linesTableCopyButton.clicked.connect(lambda c: self.copyLinesTable())
    hbox = QHBoxLayout()
    hbox.addWidget(self.linesTableCopyButton)
    hbox.addStretch(1)
    vbox.addLayout(hbox)

    vbox.addStretch(1)
    line = QFrame()
    line.setFrameShape(QFrame.HLine)
    line.setFrameShadow(QFrame.Sunken)
    vbox.addWidget(line)


    self.optionsGrid = QGridLayout()
    vbox.addLayout(self.optionsGrid)

    self.interpComboBox = QComboBox()
    self.interpComboBox.currentIndexChanged.connect(self.interpSelected)
    self.interpOptionsLayout = QVBoxLayout()
    self.interpOptionsLayout.setContentsMargins(40, 0, 0, 0)
    self.interpCheckBox = QCheckBox('Interpolation')
    self.interpCheckBox.setChecked(False)
    self.interpStateChanged(Qt.Unchecked)
    self.interpCheckBox.stateChanged.connect(self.interpStateChanged)
    self.optionsGrid.addWidget(self.interpCheckBox, 0, 0)
    self.optionsGrid.addWidget(self.interpComboBox, 0, 1)
    self.optionsGrid.addLayout(self.interpOptionsLayout, 1, 0, 1, 2)

    self.interpOptions = []
    for interp in [CubicSpline()]:
      opt = interp.getOptionsWidget()
      self.interpComboBox.addItem(interp.label, [interp, opt])
      if opt:
        self.interpOptionsLayout.addWidget(opt)
        self.interpOptions.append(opt)
    self.interpComboBox.setCurrentIndex(0)

    self.WCthreshold = QLineEdit()
    self.WCthreshold.setValidator(QDoubleValidator())
    self.WCthreshold.textChanged.connect(lambda t: self.toolSetWCthreshold)
    self.WCthreshold.setText('%g' % self.tool.threshold)
    self.optionsGrid.addWidget(QLabel('Weight center threshold'), 2, 0)
    self.optionsGrid.addWidget(self.WCthreshold, 2, 1)

    for l, f in [('Plot original', self.plotOriginal),
                 ('Plot with X offset', self.plotXoffset),
                 ('Plot differences', self.plotDifferences),
                 ('Plot IAD', self.plotIAD)]:
      btn = QPushButton(l)
      btn.clicked.connect(f)
      vbox.addWidget(btn)

    self.tool.xoffUpdated.connect(self.updateXoff)
    self.tool.iadYUpdated.connect(self.updateIADy)
    self.tool.peaksUpdated.connect(self.updatePeaks)

  def copyLinesTable(self):
    rows = [self.columnLabels]
    for r in range(self.linesTable.rowCount()):
      row = [self.linesTable.cellWidget(r, 0).text()]
      for c in range(1, self.linesTable.columnCount()):
        row.append(self.linesTable.item(r, c).text())
      rows.append(row)
    QApplication.clipboard().setText('\n'.join(['\t'.join(r) for r in rows]))

  def linesTableCellChanged(self, r, c):<commit_msg>[IAD] Add copy lines button<commit_after>import logging
import re
import numpy as np
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QDoubleValidator
from PyQt5.QtWidgets import \
  QWidget, QLabel, QVBoxLayout, QHBoxLayout, QGridLayout, \
  QLineEdit, QCheckBox, QSpinBox, QPushButton, \
  QButtonGroup, QRadioButton, QComboBox, QTableWidgetItem, \
  QAbstractScrollArea, QHeaderView, QApplication

from tools import CubicSpline, ToolBase, FitTool, IADTool
from commonwidgets import TableWidget, HSeparator


class ToolWidgetBase(QWidget):
  plotRequested = pyqtSignal(ToolBase, bool, name='plotRequested')

  def __init__(self):
    super().__init__()
    self.tool = self.toolClass()
    self.tool.cleared.connect(self.clear)
    self.tool.added.connect(self.add)

  def name(self):
    return self.toolClass.name

  def label(self):
    return self.toolClass.label

  def clear(self):
    raise NotImplementedError()

  def add(self, data):
    raise NotImplementedError()


class FitToolWidget(ToolWidgetBase):
  toolClass = FitTool

  def __init__(self):
    super().__init__()

  def clear(self):
    pass

  def add(self, data):
    pass


class IADToolWidget(ToolWidgetBase):
  toolClass = IADTool
  columnLabels = ['Name', 'IAD X', 'IAD Y', 'X offset', 'Weight center', 'Peak x', 'Peak y']

  def __init__(self):
    super().__init__()

    vbox = QVBoxLayout()
    self.setLayout(vbox)

    self.linesTable = TableWidget()
    self.linesTable.cellChanged.connect(self.linesTableCellChanged)
    vbox.addWidget(self.linesTable)

    self.copyResultButton = QPushButton('Copy result')
    self.copyResultButton.clicked.connect(lambda c: self.copyResult())
    self.copyLinesButton = QPushButton('Copy lines')
    self.copyLinesButton.clicked.connect(lambda c: self.copyLines())
    hbox = QHBoxLayout()
    hbox.addWidget(self.copyResultButton)
    hbox.addWidget(self.copyLinesButton)
    hbox.addStretch(1)
    vbox.addLayout(hbox)

    vbox.addStretch(1)
    vbox.addWidget(HSeparator())


    self.optionsGrid = QGridLayout()
    vbox.addLayout(self.optionsGrid)

    self.interpComboBox = QComboBox()
    self.interpComboBox.currentIndexChanged.connect(self.interpSelected)
    self.interpOptionsLayout = QVBoxLayout()
    self.interpOptionsLayout.setContentsMargins(40, 0, 0, 0)
    self.interpCheckBox = QCheckBox('Interpolation')
    self.interpCheckBox.setChecked(False)
    self.interpStateChanged(Qt.Unchecked)
    self.interpCheckBox.stateChanged.connect(self.interpStateChanged)
    self.optionsGrid.addWidget(self.interpCheckBox, 0, 0)
    self.optionsGrid.addWidget(self.interpComboBox, 0, 1)
    self.optionsGrid.addLayout(self.interpOptionsLayout, 1, 0, 1, 2)

    self.interpOptions = []
    for interp in [CubicSpline()]:
      opt = interp.getOptionsWidget()
      self.interpComboBox.addItem(interp.label, [interp, opt])
      if opt:
        self.interpOptionsLayout.addWidget(opt)
        self.interpOptions.append(opt)
    self.interpComboBox.setCurrentIndex(0)

    self.WCthreshold = QLineEdit()
    self.WCthreshold.setValidator(QDoubleValidator())
    self.WCthreshold.textChanged.connect(lambda t: self.toolSetWCthreshold)
    self.WCthreshold.setText('%g' % self.tool.threshold)
    self.optionsGrid.addWidget(QLabel('Weight center threshold'), 2, 0)
    self.optionsGrid.addWidget(self.WCthreshold, 2, 1)

    for l, f in [('Plot original', self.plotOriginal),
                 ('Plot with X offset', self.plotXoffset),
                 ('Plot differences', self.plotDifferences),
                 ('Plot IAD', self.plotIAD)]:
      btn = QPushButton(l)
      btn.clicked.connect(f)
      vbox.addWidget(btn)

    self.tool.xoffUpdated.connect(self.updateXoff)
    self.tool.iadYUpdated.connect(self.updateIADy)
    self.tool.peaksUpdated.connect(self.updatePeaks)

  def copyResult(self):
    rows = [self.columnLabels]
    for r in range(self.linesTable.rowCount()):
      row = [self.linesTable.cellWidget(r, 0).text()]
      for c in range(1, self.linesTable.columnCount()):
        row.append(self.linesTable.item(r, c).text().strip())
      rows.append(row)
    QApplication.clipboard().setText('\n'.join(['\t'.join(r) for r in rows]))

  def copyLines(self):
    dx = self.tool.interp.dx.value()
    xoff = list(map(int, np.round(np.array(self.tool.xoff)/dx)))
    lines = self.tool.getLines('orig')

    x = lines[0].x
    x = np.concatenate((np.array(range(min(xoff), 0))*dx + x[0],
                        x,
                        np.array(range(1, max(xoff)+1))*dx + x[-1]))
    y = []
    for i, l in enumerate(lines):
      y_ = [''] * (xoff[i]-min(xoff))
      y_ += list(l.y)
      y_ += [''] * (max(xoff) - xoff[i])
      y.append(y_)

    rows = [['x'] + [l.name for l in lines]]
    rows += list(zip(*([x] + y)))
    print(rows[0])
    print(rows[1])
    QApplication.clipboard().setText('\n'.join(['\t'.join(map(str, r)) for r in rows]))

  def linesTableCellChanged(self, r, c):
{'fraction_non_alphanumeric': 0.12731073943661972, 'fraction_numerical': 0.006382042253521127, 'mean_word_length': 3.761131482451545, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3349103', 'n_tokens_mistral': 3140, 'n_tokens_neox': 3017, 'n_words': 550}