<commit_before>/**
 * 2016-09-19
 * Try to use QThread, but it involves signal and slot. So, I choose C++11 thread instead, for simpler implementation
 * TODO: Need to redesign the "read" and "write" when item change. Not every time it is "write".
 */
#include <iostream>
#include <cstdio>
#include <chrono>
#include <thread>
#include <mutex>
#include <QApplication>
#include <QtUiTools>

#include "med.hpp"

using namespace std;

class MainUi : public QObject {
  Q_OBJECT

public:
  MainUi() {
    loadUiFiles();
  }
  Med med;
  std::thread* refreshThread;
  std::mutex scanUpdateMutex;
  std::mutex addressUpdateMutex;

  static void refresh(MainUi* mainUi) {
    while(1) {
      //mainUi->refreshScanTreeWidget();
      //mainUi->refreshAddressTreeWidget();
      std::this_thread::sleep_for(chrono::milliseconds(800));
    }
  }

  void refreshScanTreeWidget() {
    QTreeWidget* scanTreeWidget = this->mainWindow->findChild<QTreeWidget*>("scanTreeWidget");
    QTreeWidgetItemIterator it(scanTreeWidget);
    scanUpdateMutex.lock();
    while(*it) {
      try {
        int index = scanTreeWidget->indexOfTopLevelItem(*it);<commit_msg>Tree model<commit_after>/**
 * 2016-09-19
 * Try to use QThread, but it involves signal and slot. So, I choose C++11 thread instead, for simpler implementation
 * TODO: Need to redesign the "read" and "write" when item change. Not every time it is "write".
 */
#include <iostream>
#include <cstdio>
#include <chrono>
#include <thread>
#include <mutex>
#include <QApplication>
#include <QtUiTools>

#include "med.hpp"

using namespace std;

class TreeItem {
public:
  explicit TreeItem(const QList<QVariant> &data, TreeItem* parent = 0) {
    this->parentItem = parent;
    this->itemData = data;
  }
  ~TreeItem() {
    qDeleteAll(childItems);
  }

  void appendChild(TreeItem* item) {
    childItems.append(item);
  }

  TreeItem* child(int row) {
    return childItems.value(row);
  }

  int childCount() const {
    return childItems.count();
  }

  int row() const {
    if(parentItem)
      return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
    return 0;
  }
  int columnCount() const {
    return itemData.count();
  }
  TreeItem* parent() {
    return parentItem;
  }
  QVariant data(int column) const {
    return itemData.value(column);
  }

private:
  TreeItem* parentItem;
  QList<QVariant> itemData;
  QList<TreeItem*> childItems;
};

class TreeModel : public QAbstractItemModel {
  Q_OBJECT
public:
  explicit TreeModel(const QString &data, QObject* parent = 0) {
    QList<QVariant> rootData;
    rootData << "Title" << "Summary";
    rootItem = new TreeItem(rootData);
    setupModelData(data.split(QString("\n")), rootItem);
  }
  ~TreeModel() {
    delete rootItem;
  }

  QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE {
    if (!index.isValid())
      return QVariant();
    if (role != Qt::DisplayRole)
      return QVariant();

    TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
    return item->data(index.column());
  }

  Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE {
    if (!index.isValid())
      return 0;
    return QAbstractItemModel::flags(index);
  }

  QVariant headerData(int section, Qt::Orientation orientation,
                      int role = Qt::DisplayRole) const Q_DECL_OVERRIDE {
    if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
      return rootItem->data(section);
    return QVariant();
  }

  QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE {
    if(!hasIndex(row, column, parent))
      return QModelIndex();
    TreeItem* parentItem;
    if(!parent.isValid())
      parentItem = rootItem;
    else
      parentItem = static_cast<TreeItem*>(parent.internalPointer());
    TreeItem* childItem = parentItem->child(row);
    if(childItem)
      return createIndex(row, column, childItem);
    else
      return QModelIndex();
  }

  QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE {
    if(!index.isValid())
      return QModelIndex();
    TreeItem* childItem = static_cast<TreeItem*>(index.internalPointer());
    TreeItem* parentItem = childItem->parent();
    if(parentItem == rootItem)
      return QModelIndex();
    return createIndex(parentItem->row(), 0, parentItem);
  }

  int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE {
    TreeItem* parentItem;
    if(parent.column() > 0)
      return 0;
    if(!parent.isValid())
      parentItem = rootItem;
    else
      parentItem = static_cast<TreeItem*>(parent.internalPointer());
    return parentItem->childCount();
  }

  int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE {
    if (parent.isValid())
      return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
    return rootItem->columnCount();
  }

private:
  void setupModelData(const QStringList &lines, TreeItem* parent);
  TreeItem* rootItem;
};



class MainUi : public QObject {
  Q_OBJECT

public:
  MainUi() {
    loadUiFiles();
  }
  Med med;
  std::thread* refreshThread;
  std::mutex scanUpdateMutex;
  std::mutex addressUpdateMutex;

  static void refresh(MainUi* mainUi) {
    while(1) {
      //mainUi->refreshScanTreeWidget();
      //mainUi->refreshAddressTreeWidget();
      std::this_thread::sleep_for(chrono::milliseconds(800));
    }
  }

  void refreshScanTreeWidget() {
    QTreeWidget* scanTreeWidget = this->mainWindow->findChild<QTreeWidget*>("scanTreeWidget");
    QTreeWidgetItemIterator it(scanTreeWidget);
    scanUpdateMutex.lock();
    while(*it) {
      try {
        int index = scanTreeWidget->indexOfTopLevelItem(*it);
{'fraction_non_alphanumeric': 0.12635821941815634, 'fraction_numerical': 0.006133894146512443, 'mean_word_length': 3.8903170522707797, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 51, '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': '2045412', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1771, 'n_words': 427}