Commit 0d0795d4 authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

Merge branch 'widgets' into 'master'

Widgets

See merge request !47
parents 51983682 6c4221b5
Pipeline #14529 passed with stages
in 8 minutes and 7 seconds
...@@ -44,13 +44,25 @@ IF(USE_QT4) ...@@ -44,13 +44,25 @@ IF(USE_QT4)
ELSE() ELSE()
SET(HEADERS SET(HEADERS
${HEADERS} ${HEADERS}
numberpadwidget.hh) numberpadwidget.hh
navigationactionmanager.hh
navigationmodel.hh
navigationwidget.hh
)
SET(SOURCES SET(SOURCES
${SOURCES} ${SOURCES}
numberpadwidget.cc) numberpadwidget.cc
navigationactionmanager.cc
navigationitem.cc
navigationmodel.cc
navigationwidget.cc
)
QT5_WRAP_CPP(MOC_FILES QT5_WRAP_CPP(MOC_FILES
${HEADERS} ${HEADERS}
) )
SET(HEADERS ${HEADERS}
navigationitem.hh
)
# #
# Process qt resource files # Process qt resource files
#QT5_ADD_RESOURCES(RESOURCE_RESULT #QT5_ADD_RESOURCES(RESOURCE_RESULT
......
...@@ -21,9 +21,18 @@ ELSE() ...@@ -21,9 +21,18 @@ ELSE()
QT5_WRAP_CPP(QMOC_FILES3 QT5_WRAP_CPP(QMOC_FILES3
radixnumberpadwidget.hh radixnumberpadwidget.hh
) )
QT5_WRAP_CPP(QMOC_FILES4
radixnavigationwidget.hh
)
TRIBITS_ADD_EXECUTABLE(radixnumberpadwidget TRIBITS_ADD_EXECUTABLE(radixnumberpadwidget
NOEXEPREFIX NOEXEPREFIX
SOURCES radixnumberpadwidget.cc ${QMOC_FILES3} SOURCES radixnumberpadwidget.cc ${QMOC_FILES3}
radixnumberpadwidget.hh
)
TRIBITS_ADD_EXECUTABLE(radixnavigationwidget
NOEXEPREFIX
SOURCES radixnavigationwidget.cc ${QMOC_FILES4}
radixnavigationwidget.hh
) )
ENDIF() ENDIF()
TRIBITS_ADD_EXECUTABLE(radixtabwidget TRIBITS_ADD_EXECUTABLE(radixtabwidget
......
/*
* @file: mainwindow.cpp
* @author: Jordan P. Lefebvre, lefebvrejp@ornl.gov
*
* Created on May 31, 2016, 10:52 PM
*/
#include "radixnavigationwidget.hh"
#include <iostream>
#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <limits>
#include "radixwidgets/navigationactionmanager.hh"
#include "radixwidgets/navigationitem.hh"
#include "radixwidgets/navigationmodel.hh"
#include "radixwidgets/navigationwidget.hh"
using namespace radix;
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
{
setGeometry(400, 250, 542, 390);
mWidget = new NavigationWidget(this);
NavigationModel* model = mWidget->navigationModel();
NavigationItem* root = model->rootItem();
auto hello = model->addItem("Hello", root);
auto world = model->addItem("World", root);
auto hidden_beneath = model->addItem("Hidden beneath", world);
NavigationActionManager* actions = mWidget->navigationActionManager();
actions->registerAction(hello, "Hello Function 1", []() {
std::cout << "Hello function 1 executed" << std::endl;
});
actions->registerAction(hidden_beneath, "Hidden Function", []() {
std::cout << "Hidden function executed" << std::endl;
});
actions->registerAction(hidden_beneath, "Hidden Function 2", []() {
std::cout << "Hidden function2 executed" << std::endl;
});
setCentralWidget(mWidget);
}
MainWindow::~MainWindow() {}
/******************************************************************************/
/******************************** MAIN PROGRAM ********************************/
/******************************************************************************/
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
mainWindow.raise();
return app.exec();
}
#ifndef RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#define RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#include <QMainWindow>
#include <QWidget>
#include "radixwidgets/navigationwidget.hh"
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
radix::NavigationWidget *mWidget;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // RADIX_RADIXWIDGETS_EXAMPLE_RADIXNAVIGATIONWIDGET_HH_
#include "radixwidgets/navigationactionmanager.hh"
#include <QHash>
#include <QMenu>
#include "radixbug/bug.hh"
namespace radix
{
class NavigationActionManager::PImpl
{
public:
QHash<NavigationItem *, QList<std::pair<QString, std::function<void()>>>>
item_functions;
~PImpl();
};
NavigationActionManager::PImpl::~PImpl() {}
NavigationActionManager::NavigationActionManager(QObject *parent)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
}
void NavigationActionManager::registerAction(NavigationItem *item, QString text,
std::function<void()> functor)
{
auto item_it = p->item_functions.find(item);
if (item_it == p->item_functions.end())
{
// create a new reference
p->item_functions.insert(item, {std::make_pair(text, functor)});
}
else
{
item_it.value().append(std::make_pair(text, functor));
}
}
void NavigationActionManager::itemActions(NavigationItem *item,
QMenu *menu) const
{
//
// Get the list of functors
auto functor_it = p->item_functions.find(item);
if (functor_it == p->item_functions.end()) return;
auto &list = functor_it.value();
for (int i = 0; i < list.length(); ++i)
{
menu->addAction(list[i].first, list[i].second);
}
}
} // namespace radix
#ifndef RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_
#define RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_
#include <QAction>
#include <QList>
#include <QObject>
#include <functional>
#include <memory>
#include "radixwidgets/navigationitem.hh"
namespace radix
{
class NavigationActionManager : public QObject
{
Q_OBJECT
public:
NavigationActionManager(QObject *parent = nullptr);
void registerAction(NavigationItem *item, QString text,
std::function<void()> functor);
void itemActions(NavigationItem *item, QMenu *menu) const;
private:
class PImpl;
std::unique_ptr<PImpl, void (*)(PImpl *)> p;
};
} // namespace radix
#endif /** RADIX_RADIXWIDGETS_NAVIGATIONACTIONMANAGER_HH_ */
#include "radixwidgets/navigationitem.hh"
#include "radixbug/bug.hh"
#include <QList>
namespace radix
{
class NavigationItem::PImpl
{
public:
NavigationItem *parent = nullptr;
QList<NavigationItem *> children;
QList<QVariant> data;
bool checked = false;
int type = 0;
~PImpl();
};
NavigationItem::PImpl::~PImpl() { qDeleteAll(children); }
NavigationItem::NavigationItem(QVariant data, NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
p->data.append(data);
}
NavigationItem::NavigationItem(QList<QVariant> data, NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
p->data = data;
}
NavigationItem::NavigationItem(NavigationItem *parentItem)
: p(new PImpl(), [](PImpl *impl) { delete impl; })
{
p->parent = parentItem;
}
int NavigationItem::type() const { return p->type; }
void NavigationItem::setType(int type) { p->type = type; }
void NavigationItem::addChild(NavigationItem *child)
{
p->children.append(child);
}
int NavigationItem::childCount() const { return p->children.size(); }
int NavigationItem::columnCount() const
{
// recursively find the largest number of columns from children
int count = p->data.size();
for (int ci = 0; ci < p->children.size(); ++ci)
{
count = std::max(count, p->children[ci]->columnCount());
}
return count;
}
QVariant NavigationItem::data(int column) const
{
if (column >= p->data.size()) return QVariant();
return p->data.value(column);
}
void NavigationItem::setData(int column, QVariant value)
{
int size = p->data.size();
for (int i = size; i <= column; ++i)
{
p->data.append(QVariant());
}
p->data[column] = value;
}
int NavigationItem::row() const
{
if (p->parent)
{
return p->parent->p->children.indexOf(const_cast<NavigationItem *>(this));
}
}
NavigationItem *NavigationItem::parentItem() { return p->parent; }
bool NavigationItem::isChecked() const { return p->checked; }
void NavigationItem::setChecked(bool checked) { p->checked = checked; }
NavigationItem *NavigationItem::child(int row)
{
return p->children.value(row);
}
} // namespace radix
#ifndef RADIX_RADIXWIDGETS_NAVIGATIONITEM_HH_
#define RADIX_RADIXWIDGETS_NAVIGATIONITEM_HH_
#include <QVariant>
#include <memory>
namespace radix
{
class NavigationItem
{
public:
NavigationItem(QVariant data, NavigationItem *parentItem = nullptr);
NavigationItem(QList<QVariant> data, NavigationItem *parentItem = nullptr);
NavigationItem(NavigationItem *parentItem = nullptr);
int type() const;
void setType(int type);
void addChild(NavigationItem *child);
NavigationItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
void setData(int column, QVariant value);
int row() const;
NavigationItem *parentItem();
bool isChecked() const;
void setChecked(bool checked);
private:
class PImpl;
std::unique_ptr<PImpl, void (*)(PImpl *)> p;
};
} // namespace radix
#endif
#include "radixwidgets/navigationmodel.hh"
#include "radixwidgets/navigationitem.hh"
#include "radixbug/bug.hh"
#include <QList>
namespace radix
{
class NavigationModel::PImpl
{
public:
NavigationItem* root = nullptr;
~PImpl();
};
NavigationModel::PImpl::~PImpl()
{
if (root) delete root;
}
NavigationModel::NavigationModel(QObject* parent)
: QAbstractItemModel(parent)
, p(new PImpl(), [](PImpl* impl) { delete impl; })
{
p->root = new NavigationItem();
}
QVariant NavigationModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid()) return QVariant();
NavigationItem* item = static_cast<NavigationItem*>(index.internalPointer());
if (Qt::CheckStateRole == role && index.column() == 0)
return static_cast<int>(item->isChecked() ? Qt::Checked : Qt::Unchecked);
if (role != Qt::DisplayRole) return QVariant();
return item->data(index.column());
}
bool NavigationModel::setData(const QModelIndex& index, const QVariant& value,
int role)
{
if (Qt::CheckStateRole == role)
{
NavigationItem* item =
static_cast<NavigationItem*>(index.internalPointer());
item->setChecked(value.toBool());
// signal selection/deselection
if (item->isChecked())
emit itemChecked(index);
else
emit itemUnChecked(index);
return true;
}
return false;
}
Qt::ItemFlags NavigationModel::flags(const QModelIndex& index) const
{
if (!index.isValid()) return QAbstractItemModel::flags(index);
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (index.column() == 0) flags |= Qt::ItemIsUserCheckable;
return flags;
}
QVariant NavigationModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return p->root->data(section);
return QVariant();
}
QModelIndex NavigationModel::index(int row, int column,
const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent)) return QModelIndex();
NavigationItem* parentItem;
if (!parent.isValid())
parentItem = p->root;
else
parentItem = static_cast<NavigationItem*>(parent.internalPointer());
NavigationItem* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex NavigationModel::parent(const QModelIndex& index) const
{
if (!index.isValid()) return QModelIndex();
NavigationItem* childItem =
static_cast<NavigationItem*>(index.internalPointer());
NavigationItem* parentItem = childItem->parentItem();
if (parentItem == p->root) return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int NavigationModel::rowCount(const QModelIndex& parent) const
{
NavigationItem* parentItem;
if (parent.column() > 0) return 0;
if (!parent.isValid())
parentItem = p->root;
else
parentItem = static_cast<NavigationItem*>(parent.internalPointer());
return parentItem->childCount();
}
int NavigationModel::columnCount(const QModelIndex& parent) const
{
if (parent.isValid())
return static_cast<NavigationItem*>(parent.internalPointer())
->columnCount();
else
return p->root->columnCount();
}
NavigationItem* NavigationModel::rootItem() { return p->root; }
NavigationItem* NavigationModel::addItem(QVariant value, NavigationItem* parent)
{
beginResetModel();
NavigationItem* newItem = new NavigationItem(value, parent);
parent->addChild(newItem);
endResetModel();
return newItem;
}
} // namespace radix
#ifndef RADIX_RADIXWIDGETS_NAVIGATIONMODEL_HH_
#define RADIX_RADIXWIDGETS_NAVIGATIONMODEL_HH_
#include <QAbstractItemModel>
#include <QObject>
#include <memory>
namespace radix
{
// Forward declaration
class NavigationItem;
class NavigationModel : public QAbstractItemModel
{
Q_OBJECT
public:
NavigationModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
NavigationItem *rootItem();
NavigationItem *addItem(QVariant value, NavigationItem *parent);
signals:
void itemChecked(const QModelIndex &index);
void itemUnChecked(const QModelIndex &index);
private:
class PImpl;
std::unique_ptr<PImpl, void (*)(PImpl *)> p;
};
} // namespace radix
#endif
#include "radixwidgets/navigationwidget.hh"
#include "radixwidgets/navigationactionmanager.hh"
#include "radixwidgets/navigationitem.hh"
#include "radixwidgets/navigationmodel.hh"
#include "radixbug/bug.hh"
#include <QClipboard>
#include <QEvent>
#include <QFileDialog>
#include <QFileInfo>
#include <QHeaderView>
#include <QKeyEvent>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QShortcut>
#include <QStandardItemModel>
#include <QTextDocument>
#include <QToolTip>
#include <QTreeView>
#include <QVBoxLayout>
#include <QtDebug>
namespace radix
{
class NavigationItemSortFilterProxyModel::PImpl
{
public:
QHash<QModelIndex, bool> seen;
};
NavigationItemSortFilterProxyModel::NavigationItemSortFilterProxyModel(
QObject* parent)
: QSortFilterProxyModel(parent)
, p(new PImpl(), [](PImpl* impl) { delete impl; })
{
}
bool NavigationItemSortFilterProxyModel::accepts(const QModelIndex& index) const
{
const QString& text = index.data().toString();
const QRegExp& regex = filterRegExp();
bool accept = text.contains(regex);
for (int i = 0, ie = sourceModel()->rowCount(index); i < ie; i++)
{
if (accepts(sourceModel()->index(i, 0, index)))
{