Newer
Older
Import / applications / MakePDF / Framework / GenericTableUI.h
#ifndef GENERIC_TABLE_UI_H
#define GENERIC_TABLE_UI_H


#include <QAbstractItemModel>
#include <QTableView>
#include <QItemDelegate>
#include <QFileInfo>
#include <QEvent>
#include <QMimeData>
#include <QUrl>
#include <QDragEnterEvent>
#include "GenericTable.h"


class GenericTableView : public QTableView
{
public:
  GenericTableView() : QTableView(nullptr), m_genericTable(nullptr)
  {
    setDragDropMode(QAbstractItemView::InternalMove);
  }

  void init(GenericTableBase* a_table, QWidget* a_parent)
  {
    setParent(a_parent);
    m_genericTable = a_table;
    setAcceptDrops(m_genericTable->m_readOnly ? false : true);
  }

  void dragEnterEvent(QDragEnterEvent *event)
  {
    if (!m_genericTable->m_readOnly)
    {
      event->setDropAction(Qt::LinkAction);
      event->accept();
    }
  }

  void dropEvent(QDropEvent *event)
  {
    if (event->mimeData()->hasUrls() && !m_genericTable->m_readOnly)
    {
      QList<QUrl> urls = event->mimeData()->urls();
      for (int i = 0; i < urls.length(); i++)
      {
        m_genericTable->dropData(urls[i].toLocalFile().toUtf8());
      }
    }
    event->accept();
  }

  void currentChanged(const QModelIndex &current, const QModelIndex &/*previous*/)
  {
    m_genericTable->m_currentRow = current.row();
  }

private:
  GenericTableBase *m_genericTable;
};


class GenericTableUI : public QAbstractTableModel
{
public:
  GenericTableUI() : QAbstractTableModel(nullptr), m_view(nullptr), m_genericTable(nullptr)
  {
  }

  void init(GenericTableBase* a_table, QTableView* a_view)
  {
    setParent(a_view);
    m_genericTable = a_table;
    m_view = a_view;
    m_view->setModel(this);
    m_genericTable->RegisterCallbackOnChange(updateCallback, this);
    if (m_genericTable->m_columnNames.size())
    {
      //for (int i = 0; i < m_genericTable->m_columnNames.size() - 1; i++)
      //	m_view->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
#if QT_VERSION >= 0x050000
      m_view->horizontalHeader()->setSectionResizeMode((int)m_genericTable->m_columnNames.size() - 1, QHeaderView::Stretch);
#else
      m_view->horizontalHeader()->setResizeMode((int)m_genericTable->m_columnNames.size() - 1, QHeaderView::Stretch);
#endif
    }
  }

  ~GenericTableUI()
  {
  }

  /*
   void setItemDelegate(QAbstractItemDelegate* a_delegate)
  {
    //m_view->setItemDelegate(a_delegate);
  }
  */

private:
  bool isValid(int row, int col) const
  {
    return (row >= 0 && col >= 0 && row < int(m_genericTable->size()) && col < int(m_genericTable->m_columnNames.size())) ? true : false;
  }

  virtual Qt::ItemFlags flags(const QModelIndex &index) const
  {
    if (!index.isValid() || !isValid(index.row(), index.column()))
      return Qt::NoItemFlags;
    Qt::ItemFlags editable = m_genericTable->m_readOnly ? Qt::NoItemFlags : Qt::ItemIsEditable;
    editable = Qt::ItemIsEditable;
    QVariant::Type type = m_genericTable->m_columnTypes[index.column()];
    if (type == QVariant::Url)
      return Qt::ItemIsSelectable | Qt::ItemIsEnabled; // Make URLs non-editable
    if (type == QVariant::Bool)
      return editable | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled; // Make bools checkable
    return editable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
  }

  virtual int rowCount(const QModelIndex &/*parent = QModelIndex()*/) const
  {
    return (int)m_genericTable->size();
  }

  virtual int columnCount(const QModelIndex &/*parent = QModelIndex()*/) const
  {
    return (int)m_genericTable->m_columnNames.size();
  }

  virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
  {
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section < int(m_genericTable->m_columnNames.size()))
    {
      return QString(m_genericTable->m_columnNames[section].c_str());
    }
    return QAbstractTableModel::headerData(section, orientation, role);
  }

  bool setData(const QModelIndex &index, const QVariant &value, int /*role*/)
  {
    if (!index.isValid() || !isValid(index.row(), index.column()))
      return false;
    m_genericTable->setValue(index.row(), index.column(), value);
    return true;
  }

  virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
  {
    if (!index.isValid() || !isValid(index.row(), index.column()) || (role != Qt::DisplayRole && role != Qt::CheckStateRole) )
      return QVariant();
    return m_genericTable->value(index.row(), index.column());
  }

  void reload()
  {
#if QT_VERSION >= 0x050000
    beginResetModel();
    endResetModel();
#endif
    beginInsertRows(QModelIndex(), 0, (int)m_genericTable->size());
    endInsertRows();
    m_view->scrollToBottom();
  }

  static void updateCallback(void *a_data)
  {
    GenericTableUI* obj = (GenericTableUI*)a_data;
    obj->reload();
  }

private:
  QTableView *m_view;
  GenericTableBase *m_genericTable;
};


#endif // GENERIC_TABLE_UI_H