Commit ae9ce0c7 authored by Jan Möbius's avatar Jan Möbius

Matthias:

Postprocessor manager for multiple postprocessors

refs #1736

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@17520 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 14d0a11d
......@@ -563,6 +563,9 @@ Core::init() {
connect( coreWidget_->examiner_widgets_[i], SIGNAL( viewChanged() ),
coreWidget_->examiner_widgets_[i], SLOT( updateGL() ) ,Qt::DirectConnection);
// Set post processor
PostProcessorDialog::loadSavedPostProcessors(i);
// ====================================================
// Set renderer
// ====================================================
......
......@@ -631,6 +631,9 @@ public:
/// Show a dialog in which the viewMode can be changed
void slotViewChangeDialog();
/// update the content of the specified examiner
void slotUpdateExaminer(unsigned _id);
public slots :
/// Set the view Mode to the given Mode
......
......@@ -64,6 +64,9 @@ void CoreWidget::slotShowPostProcessorManager() {
postProcessorDialog_ = new PostProcessorDialog();
}
connect(postProcessorDialog_,SIGNAL(updateExaminer(unsigned)),this,SLOT(slotUpdateExaminer(unsigned)));
postProcessorDialog_->show();
}
......
......@@ -515,3 +515,8 @@ void CoreWidget::slotApplyStereoSettings(int /*_tmpParam*/) {
examiner_widgets_[i]->updateGL();
}
}
void CoreWidget::slotUpdateExaminer(unsigned _id)
{
examiner_widgets_[_id]->updateGL();
}
......@@ -40,102 +40,204 @@
* *
\*===========================================================================*/
#if QT_VERSION >= 0x050000
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include "postProcessorWidget.hh"
#include <QMessageBox>
#include <functional>
#include <algorithm>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/RendererInfo.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
PostProcessorDialog::PostProcessorDialog(QWidget *parent)
: QDialog(parent)
PostProcessorDialog::PostProcessorDialog(QWidget *_parent)
: QDialog(_parent)
{
setupUi(this);
list->setContextMenuPolicy(Qt::CustomContextMenu);
activeList->setContextMenuPolicy(Qt::CustomContextMenu);
connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(list,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(slotContextMenu(const QPoint&)));
connect(list,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(slotContextMenuActivate(const QPoint&)));
connect(activeList,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(slotContextMenuDeactivate(const QPoint&)));
connect(activateButton,SIGNAL(clicked()),this,SLOT(slotActivatePostProcessor()));
connect(deactivateButton,SIGNAL(clicked()),this,SLOT(slotDeactivatePostProcessor()));
connect(upButton,SIGNAL(clicked()),this,SLOT(slotMoveUp()));
connect(downButton,SIGNAL(clicked()),this,SLOT(slotMoveDown()));
connect(saveButton,SIGNAL(clicked()),this,SLOT(slotSaveActive()));
//set icons
QString iconPath = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
closeButton->setIcon( QIcon(iconPath + "window-close.png"));
saveButton->setIcon( QIcon(iconPath + "document-save.png"));
}
void PostProcessorDialog::closeEvent(QCloseEvent *event)
void PostProcessorDialog::closeEvent(QCloseEvent *_event)
{
event->accept();
_event->accept();
accept();
}
void PostProcessorDialog::showEvent ( QShowEvent * ) {
update();
void PostProcessorDialog::showEvent ( QShowEvent * )
{
initWindow();
}
void PostProcessorDialog::update()
void PostProcessorDialog::initWindow()
{
currentExaminer_ = PluginFunctions::activeExaminer();
list->clear();
activeList->clear();
activeRowToRow_.clear();
for ( unsigned int i = 0 ; i < postProcessorManager().available() ; ++i) {
//first, fill already activated processors in the right order
for (int i = 0; i < postProcessorManager().numActive(currentExaminer_); ++i)
{
unsigned int id = postProcessorManager().activeId(currentExaminer_, i);
activeRowToRow_.push_back(id);
QListWidgetItem *activeItem = new QListWidgetItem("");
activeList->addItem(activeItem);
QFrame* frame = createFrame(*postProcessorManager()[id]);
activeItem->setSizeHint(frame->sizeHint());
activeList->setItemWidget(activeItem,frame);
}
//list all available post processors (hidden, if active)
for ( unsigned int i = 0 ; i < postProcessorManager().available() ; ++i)
{
// Get and check post processor
PostProcessorInfo* processor = postProcessorManager()[i];
if ( ! processor )
continue;
QFrame* frame = new QFrame();
QHBoxLayout* hlayout = new QHBoxLayout;
QFrame* frame = createFrame(*processor);
QListWidgetItem *item = new QListWidgetItem("");
item->setSizeHint( frame->sizeHint() );
list->addItem(item);
list->setItemWidget(item, frame);
//is the postProcess active? if so, hide it
bool found = false;
for (std::vector<unsigned>::iterator iter = activeRowToRow_.begin(); iter != activeRowToRow_.end() && !found; ++iter)
found = (*iter == i);
if ( found )
list->setRowHidden(list->row(item),true);
}
QLabel* name = new QLabel( processor->name );
QFont font;
font.setBold(true);
font.setPointSize(10);
name->setFont(font);
QLabel* version = new QLabel( processor->version );
hlayout->addWidget(name);
hlayout->addStretch();
hlayout->addWidget(version);
}
QVBoxLayout* vlayout = new QVBoxLayout;
void PostProcessorDialog::slotActivatePostProcessor()
{
QList<QListWidgetItem*> selectedItems = list->selectedItems();
QLabel* description = new QLabel( processor->description );
descriptions_.push_back(description);
for (int i=0; i < selectedItems.size(); ++i)
{
QListWidgetItem* item = selectedItems[i];
const int currentRow = list->row( item );
vlayout->addLayout(hlayout,20);
vlayout->addWidget(description);
frame->setLayout(vlayout);
postProcessorManager().append( currentRow, currentExaminer_);
QListWidgetItem *item = new QListWidgetItem("");
frames_.push_back(frame);
item->setSizeHint( QSize (100,50) );
//disable in aviable list
item->setHidden(true);
item->setSelected(false);
list->addItem(item);
list->setItemWidget(item, frame);
//add to active list
QListWidgetItem *activeItem = new QListWidgetItem("");
activeList->addItem(activeItem);
activeItem->setSelected(true);
if ( postProcessorManager().activeId(PluginFunctions::activeExaminer()) == i )
item->setBackground( Qt::green );
QFrame* frame = createFrame(*postProcessorManager()[currentRow]);
activeItem->setSizeHint( frame->sizeHint() );
activeList->setItemWidget(activeItem,frame);
activeRowToRow_.push_back(currentRow);
}
emit updateExaminer(currentExaminer_);
}
void PostProcessorDialog::slotActivatePostProcessor() {
for (int i=0; i < list->selectedItems().size(); ++i)
void PostProcessorDialog::slotDeactivatePostProcessor()
{
QList<QListWidgetItem*> selectedItems = activeList->selectedItems();
for (int i=0; i < selectedItems.size(); ++i)
{
QListWidgetItem* widget = list->selectedItems()[i];
QListWidgetItem* activeItem = selectedItems[i];
const unsigned chainPos = activeList->row(activeItem);
const unsigned activeID = activeRowToRow_[chainPos];
QListWidgetItem* item = list->item(activeID);
//remove postprocessor
postProcessorManager().remove(currentExaminer_, chainPos);
//enable in aviable list
item->setHidden(false);
item->setSelected(true);
postProcessorManager().setActive( list->row( widget ), PluginFunctions::activeExaminer());
//remove from active list
//update active row ids
for (unsigned i = chainPos; i < activeRowToRow_.size()-1; ++i)
activeRowToRow_[i] = activeRowToRow_[i+1];
//from qt doc: Items removed from a list widget will not be managed by Qt, and will need to be deleted manually.
activeItem = activeList->takeItem(activeList->row(activeItem));
delete activeItem;
}
activeRowToRow_.erase( activeRowToRow_.end()-selectedItems.size(), activeRowToRow_.end());
emit updateExaminer(currentExaminer_);
}
void PostProcessorDialog::slotMovePostProcessor(unsigned _from,unsigned _to)
{
if (_from >= static_cast<unsigned>(activeList->count()))
return;
if (_to >= static_cast<unsigned>(activeList->count()))
_to = activeList->count()-1;
if (_from == _to)
return;
update();
//swap widget
QListWidgetItem* activeItem = activeList->takeItem(_from);
activeList->insertItem(_to,activeItem);
QFrame* frame = createFrame(*postProcessorManager()[activeRowToRow_[_from]]);
activeItem->setSizeHint(frame->sizeHint());
activeList->setItemWidget(activeItem,frame);
activeList->setItemSelected(activeItem,true);
//swap postprocessor
const int chainPos = _from;
const int activeID = activeRowToRow_[_from];
postProcessorManager().remove(currentExaminer_, _from);
postProcessorManager().insert(activeID,_to,currentExaminer_);
//swap active ID to current chain position map
int inc = (_from > _to)? -1: +1;
for(unsigned int currentRow = _from;currentRow != _to; currentRow += inc)
std::swap(activeRowToRow_[currentRow+inc],activeRowToRow_[currentRow]);
emit updateExaminer(currentExaminer_);
}
void PostProcessorDialog::slotContextMenu(const QPoint& _point)
void PostProcessorDialog::slotContextMenuActivate(const QPoint& _point)
{
if (!list->count())
return;
......@@ -146,7 +248,138 @@ void PostProcessorDialog::slotContextMenu(const QPoint& _point)
action = menu->addAction(tr("Activate"));
connect(action,SIGNAL(triggered(bool)),this,SLOT(slotActivatePostProcessor()));
menu->exec(list->mapToGlobal(_point),0);
}
void PostProcessorDialog::slotContextMenuDeactivate(const QPoint& _point)
{
if (!activeList->count())
return;
QMenu *menu = new QMenu(activeList);
QAction* action = 0;
action = menu->addAction(tr("Up"));
connect(action,SIGNAL(triggered(bool)),this,SLOT(slotMoveUp()));
action = menu->addAction(tr("Down"));
connect(action,SIGNAL(triggered(bool)),this,SLOT(slotMoveDown()));
action = menu->addAction(tr("Deactivate"));
connect(action,SIGNAL(triggered(bool)),this,SLOT(slotDeactivatePostProcessor()));
menu->exec(activeList->mapToGlobal(_point),0);
}
QFrame* PostProcessorDialog::createFrame(const PostProcessorInfo& _pPI)
{
QFrame* frame = new QFrame();
QHBoxLayout* hlayout = new QHBoxLayout;
QLabel* name = new QLabel( _pPI.name );
QFont font;
font.setBold(true);
font.setPointSize(10);
name->setFont(font);
QLabel* version = new QLabel( _pPI.version );
hlayout->addWidget(name);
hlayout->addStretch();
hlayout->addWidget(version);
QVBoxLayout* vlayout = new QVBoxLayout;
QLabel* description = new QLabel( _pPI.description );
vlayout->addLayout(hlayout,20);
vlayout->addWidget(description);
frame->setLayout(vlayout);
frame->adjustSize();
return frame;
}
template<typename TCmp>
class QListWidgetRowCmp
{
QListWidget* list_;
public:
QListWidgetRowCmp(QListWidget* _list):list_(_list){}
bool operator()(QListWidgetItem* left, QListWidgetItem* right)
{
return TCmp()(list_->row(left) , list_->row(right));
}
};
void PostProcessorDialog::slotMoveDown()
{
int start = 0;
QList<QListWidgetItem*> selectedItems = activeList->selectedItems();
//sort list, so the top is the last element
std::sort(selectedItems.begin(), selectedItems.end(), QListWidgetRowCmp<std::greater<int> >(activeList));
//dont move the last one
//if the last one wasnt moved, dont move the direct followers
for(int i=0; i < selectedItems.size() && activeList->row(selectedItems[i]) == activeList->count()-1-i;++i)
--start;
//move bottom first
for (int i=selectedItems.size()-1+start; i >= 0 ; --i)
{
QListWidgetItem* activeItem = activeList->selectedItems()[i];
unsigned selectedRow = activeList->row(activeItem);
slotMovePostProcessor(selectedRow,selectedRow+1);
}
}
void PostProcessorDialog::slotMoveUp()
{
int start = 0;
QList<QListWidgetItem*> selectedItems = activeList->selectedItems();
//sort list, so the top is the first element
std::sort(selectedItems.begin(), selectedItems.end(), QListWidgetRowCmp<std::less<int> >(activeList));
//dont move the first one
//if the first one wasnt moved, dont move the direct followers
for(int i=0; i < selectedItems.size() && activeList->row(selectedItems[i]) == i;++i)
++start;
//move top first
for (int i=start; i < selectedItems.size(); ++i)
{
QListWidgetItem* activeItem = selectedItems[i];
unsigned selectedRow = activeList->row(activeItem);
slotMovePostProcessor(selectedRow,selectedRow-1);
}
}
void PostProcessorDialog::slotSaveActive()
{
QStringList activeList("");
for (int i = 0; i < postProcessorManager().numActive(currentExaminer_); ++i)
{
unsigned int id = postProcessorManager().activeId(currentExaminer_, i);
activeList.push_back(postProcessorManager()[id]->name);
}
OpenFlipperSettings().setValue(QString("PostProcessor/Viewer/%1").arg(currentExaminer_),activeList);
}
QStringList PostProcessorDialog::getSavedPostProcessorNames(const unsigned _examiner)
{
return OpenFlipperSettings().value(QString("PostProcessor/Viewer/%1").arg(_examiner),QStringList("")).toStringList();
}
void PostProcessorDialog::loadSavedPostProcessors(const unsigned _examiner)
{
QStringList active = getSavedPostProcessorNames(_examiner);
for (QStringList::iterator iter = active.begin(); iter != active.end(); ++iter)
{
postProcessorManager().append(*iter,_examiner);
}
}
......@@ -41,43 +41,74 @@
\*===========================================================================*/
#include "ui_postProcessorWidget.hh"
#if QT_VERSION >= 0x050000
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include <vector>
#include <OpenFlipper/common/RendererInfo.hh>
#include <QDialog>
#include <QPoint>
#include <QStringList>
class QWidget;
class QFrame;
class PostProcessorInfo;
class PostProcessorDialog : public QDialog, public Ui::PostProcessorWidget
{
Q_OBJECT
signals:
/// request an update for an specified viewer
void updateExaminer(unsigned _viewer);
public:
PostProcessorDialog(QWidget *parent = 0);
PostProcessorDialog(QWidget *_parent = 0);
/// return the names of all saved post processors
static QStringList getSavedPostProcessorNames(const unsigned _examiner);
/// append all saved post processors
static void loadSavedPostProcessors(const unsigned _examiner);
private slots:
/// Show the custom context menu
void slotContextMenu(const QPoint& _point);
/// Show the custom context menu for activation
void slotContextMenuActivate(const QPoint& _point);
/// Show the custom context menu for deactivation
void slotContextMenuDeactivate(const QPoint& _point);
/// Activates the post processor (triggered via the context menu)
void slotActivatePostProcessor();
/// Deactivates the current postProcessor
void slotDeactivatePostProcessor();
/// Move the position/ordering of postprocessor in the postprocessor
void slotMovePostProcessor(unsigned _from, unsigned _to);
/// move the selected active postprocessor 1 up
void slotMoveUp();
/// move the selected active postprocessor 1 down
void slotMoveDown();
/// saves active post processor chain
void slotSaveActive();
protected:
void closeEvent(QCloseEvent *event);
void closeEvent(QCloseEvent *_event);
void showEvent ( QShowEvent * );
private:
/// initiaize the window with the post processors of the current examiner
void initWindow();
QFrame* createFrame(const PostProcessorInfo& _pPI);
void update();
/// holds the examiner id for the window
unsigned currentExaminer_;
std::vector<QLabel*> descriptions_;
QVector< QFrame* > frames_;
/// maps activeRow from activeList (same as chainIdx from RendererInfo) to row from list (same as activeId from RendererInfo) for each viewer
std::vector<unsigned> activeRowToRow_;
};
......@@ -13,8 +13,137 @@
<property name="windowTitle">
<string>post processors</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<widget class="QListWidget" name="activeList">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::NoDragDrop</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Active Post Processors Order</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="activateButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;activate selected post processor/s and put it on the last position of the post processor chain&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>--&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deactivateButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;deactivate selected post processor/s&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>&lt;--</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">