| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 | 
							- /*=========================================================================
 
-   Library:   CTK
 
-   Copyright (c) Kitware Inc.
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-       http://www.commontk.org/LICENSE
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
- =========================================================================*/
 
- // Qt includes
 
- #include <QAction>
 
- #include <QDebug>
 
- #include <QPainter>
 
- #include <QSortFilterProxyModel>
 
- #include <QStandardItem>
 
- #include <QStandardItemModel>
 
- #include <QTextDocument>
 
- #include <QTreeView>
 
- #include <QVBoxLayout>
 
- // CTK includes
 
- #include "ctkActionsWidget.h"
 
- //-----------------------------------------------------------------------------
 
- class ctkActionsWidgetPrivate
 
- {
 
-   Q_DECLARE_PUBLIC(ctkActionsWidget);
 
- protected:
 
-   ctkActionsWidget* const q_ptr;
 
- public:
 
-   ctkActionsWidgetPrivate(ctkActionsWidget& object);
 
-   void setupUI();
 
-   void setupHeaders();
 
-   void updateItems(QList<QStandardItem*>& items, QAction* action);
 
-   QStandardItemModel*    ActionsModel;
 
-   ctkSortFilterActionsProxyModel* SortFilterActionsProxyModel;
 
-   QTreeView*             ActionsTreeView;
 
- };
 
- //-----------------------------------------------------------------------------
 
- ctkActionsWidgetPrivate::ctkActionsWidgetPrivate(ctkActionsWidget& object)
 
-   :q_ptr(&object)
 
- {
 
-   this->ActionsModel = 0;
 
-   this->SortFilterActionsProxyModel = 0;
 
-   this->ActionsTreeView = 0;
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidgetPrivate::setupUI()
 
- {
 
-   Q_Q(ctkActionsWidget);
 
-   this->ActionsModel = new QStandardItemModel(q);
 
-   this->setupHeaders();
 
-   this->SortFilterActionsProxyModel = new ctkSortFilterActionsProxyModel(q);
 
-   this->SortFilterActionsProxyModel->setSourceModel(this->ActionsModel);
 
-   this->ActionsTreeView = new QTreeView(q);
 
-   QVBoxLayout* layout = new QVBoxLayout(q);
 
-   layout->addWidget(this->ActionsTreeView);
 
-   q->setLayout(layout);
 
-   this->ActionsTreeView->setModel(this->SortFilterActionsProxyModel);
 
-   this->ActionsTreeView->setAlternatingRowColors(true);
 
-   //this->ActionsTreeView->setItemDelegate(new ctkRichTextItemDelegate);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidgetPrivate::setupHeaders()
 
- {
 
-   this->ActionsModel->setColumnCount(4);
 
-   QStringList headers;
 
-   headers << "Action" << "Shortcut" << "Context" << "Details";
 
-   this->ActionsModel->setHorizontalHeaderLabels(headers);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidgetPrivate
 
- ::updateItems(QList<QStandardItem*>& items, QAction* action)
 
- {
 
-   Q_ASSERT(items.size() == 4);
 
-   // Name
 
-   QString actionText = action->text();
 
-   if (actionText.indexOf('&') != -1)
 
-     {
 
-     actionText = actionText.remove(actionText.indexOf('&'),1);  // remove mnemonic
 
-     }
 
-   items[ctkActionsWidget::NameColumn]->setText(actionText);
 
-   items[ctkActionsWidget::NameColumn]->setIcon(action->icon());
 
-   // Shortcut
 
-   items[ctkActionsWidget::ShortcutColumn]->setText(
 
-     action->shortcut().toString(QKeySequence::NativeText));
 
-   // Context
 
-   QString shortcutContext;
 
-   switch (action->shortcutContext())
 
-     {
 
-     case Qt::WidgetShortcut:
 
-     case Qt::WidgetWithChildrenShortcut:
 
-       shortcutContext = "Widget";
 
-       break;
 
-     case Qt::WindowShortcut:
 
-     case Qt::ApplicationShortcut:
 
-     default:
 
-       shortcutContext = "Application";
 
-     }
 
-   items[ctkActionsWidget::ContextColumn]->setText(shortcutContext);
 
-   items[ctkActionsWidget::DetailsColumn]->setText(action->toolTip() != actionText
 
-     ? action->toolTip() : QString(""));
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkActionsWidget::ctkActionsWidget(QWidget* parentWidget)
 
-   :QWidget(parentWidget)
 
-   , d_ptr(new ctkActionsWidgetPrivate(*this))
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   d->setupUI();
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkActionsWidget::~ctkActionsWidget()
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::addAction(QAction* action, const QString& group)
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   QStandardItem* actionGroupItem = this->groupItem(group);
 
-   Q_ASSERT(actionGroupItem);
 
-   QList<QStandardItem*> actionItems;
 
-   for (int i = 0; i < 4; ++i)
 
-     {
 
-     QStandardItem* item = new QStandardItem;
 
-     item->setData(qVariantFromValue(qobject_cast<QObject*>(action)));
 
-     item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 
-     actionItems << item;
 
-     }
 
-   d->updateItems(actionItems, action);
 
-   
 
-   bool expandGroupItem = (actionGroupItem->rowCount() == 0);
 
-   actionGroupItem->appendRow(actionItems);
 
-   // if the group didn't exist yet or was empty, then open/expand it
 
-   // automatcally to show its contents. If the group was not empty, then let
 
-   // it as is (maybe the user closed/collapsed it for a good reason...
 
-   if (expandGroupItem)
 
-     {
 
-     d->ActionsTreeView->expand(
 
-       d->SortFilterActionsProxyModel->mapFromSource(d->ActionsModel->indexFromItem(actionGroupItem)));
 
-     }
 
-   d->ActionsTreeView->resizeColumnToContents(0);
 
-   connect(action, SIGNAL(changed()), this, SLOT(updateAction()));
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::addActions(QList<QAction*> actions, const QString& group)
 
- {
 
-   foreach(QAction* action, actions)
 
-     {
 
-     this->addAction(action, group);
 
-     }
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::clear()
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   d->ActionsModel->clear();
 
-   d->setupHeaders();
 
- }
 
- //-----------------------------------------------------------------------------
 
- QStandardItem* ctkActionsWidget::groupItem(const QString& group)
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   if (group.isEmpty())
 
-     {
 
-     return d->ActionsModel->invisibleRootItem();
 
-     }
 
-   // check if the group already exists
 
-   QList<QStandardItem *> foundGroup =
 
-     d->ActionsModel->findItems(group);
 
-   if (foundGroup.size() > 0)
 
-     {
 
-     return foundGroup[0];
 
-     }
 
-   QStandardItem* groupItem = new QStandardItem(group);
 
-   groupItem->setFlags(Qt::ItemIsEnabled);
 
-   d->ActionsModel->appendRow(groupItem);
 
-   return groupItem;
 
- }
 
- //-----------------------------------------------------------------------------
 
- QStandardItemModel* ctkActionsWidget::model()const
 
- {
 
-   Q_D(const ctkActionsWidget);
 
-   return d->ActionsModel;
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::setActionsWithNoShortcutVisible(bool show)
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   d->SortFilterActionsProxyModel->setActionsWithNoShortcutVisible(show);
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkActionsWidget::areActionsWithNoShortcutVisible()const
 
- {
 
-   Q_D(const ctkActionsWidget);
 
-   return d->SortFilterActionsProxyModel->areActionsWithNoShortcutVisible();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::setMenuActionsVisible(bool show)
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   d->SortFilterActionsProxyModel->setMenuActionsVisible(show);
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkActionsWidget::areMenuActionsVisible()const
 
- {
 
-   Q_D(const ctkActionsWidget);
 
-   return d->SortFilterActionsProxyModel->areMenuActionsVisible();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkActionsWidget::updateAction()
 
- {
 
-   Q_D(ctkActionsWidget);
 
-   QAction* action = qobject_cast<QAction*>(this->sender());
 
-   Q_ASSERT(action);
 
-   QModelIndexList foundActions =
 
-     d->ActionsModel->match(d->ActionsModel->index(0,0),
 
-     Qt::UserRole + 1, qVariantFromValue(qobject_cast<QObject*>(action)),
 
-     -1, Qt::MatchExactly | Qt::MatchRecursive);
 
-   Q_ASSERT(foundActions.size());
 
-   foreach (QModelIndex actionIndex, foundActions)
 
-     {
 
-     QModelIndex parentIndex = actionIndex.parent();
 
-     QStandardItem* parent = parentIndex.isValid()
 
-       ? d->ActionsModel->itemFromIndex(parentIndex)
 
-       : d->ActionsModel->invisibleRootItem();
 
-     int actionRow = actionIndex.row();
 
-     Q_ASSERT(actionRow >= 0);
 
-     QList<QStandardItem*> actionItems;
 
-     for(int i = 0; i < 4; ++i)
 
-       {
 
-       actionItems << parent->child(actionRow, i);
 
-       }
 
-     d->updateItems(actionItems, action);
 
-     }
 
- }
 
- //-----------------------------------------------------------------------------
 
- QTreeView* ctkActionsWidget::view()const
 
- {
 
-   Q_D(const ctkActionsWidget);
 
-   return d->ActionsTreeView;
 
- }
 
- //-----------------------------------------------------------------------------
 
- class ctkSortFilterActionsProxyModelPrivate
 
- {
 
- protected:
 
-   ctkSortFilterActionsProxyModel* const q_ptr;
 
- public:
 
-   ctkSortFilterActionsProxyModelPrivate(ctkSortFilterActionsProxyModel& object);
 
-   bool                   ActionsWithNoShortcutVisible;
 
-   bool                   MenuActionsVisible;
 
- };
 
- //-----------------------------------------------------------------------------
 
- ctkSortFilterActionsProxyModelPrivate::ctkSortFilterActionsProxyModelPrivate(ctkSortFilterActionsProxyModel& object)
 
-   :q_ptr(&object)
 
- {
 
-   this->ActionsWithNoShortcutVisible = true;
 
-   this->MenuActionsVisible = true;
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkSortFilterActionsProxyModel::~ctkSortFilterActionsProxyModel()
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkSortFilterActionsProxyModel::ctkSortFilterActionsProxyModel(QObject* parentObject)
 
-  :QSortFilterProxyModel(parentObject)
 
-   , d_ptr(new ctkSortFilterActionsProxyModelPrivate(*this))
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkSortFilterActionsProxyModel::setActionsWithNoShortcutVisible(bool visible)
 
- {
 
-   Q_D(ctkSortFilterActionsProxyModel);
 
-   d->ActionsWithNoShortcutVisible = visible;
 
-   this->invalidateFilter();
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkSortFilterActionsProxyModel::areActionsWithNoShortcutVisible()const
 
- {
 
-   Q_D(const ctkSortFilterActionsProxyModel);
 
-   return d->ActionsWithNoShortcutVisible;
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkSortFilterActionsProxyModel::setMenuActionsVisible(bool visible)
 
- {
 
-   Q_D(ctkSortFilterActionsProxyModel);
 
-   d->MenuActionsVisible = visible;
 
-   this->invalidateFilter();
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkSortFilterActionsProxyModel::areMenuActionsVisible()const
 
- {
 
-   Q_D(const ctkSortFilterActionsProxyModel);
 
-   return d->MenuActionsVisible;
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkSortFilterActionsProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
 
- {
 
-   Q_D(const ctkSortFilterActionsProxyModel);
 
-   QModelIndex shortcutIndex = this->sourceModel()->index(source_row, ctkActionsWidget::ShortcutColumn, source_parent);
 
-   QStandardItem* shortcutItem = qobject_cast<QStandardItemModel*>(
 
-     this->sourceModel())->itemFromIndex(shortcutIndex);
 
-   QAction* action = shortcutItem ?
 
-     qobject_cast<QAction*>(shortcutItem->data().value<QObject*>()) : 0;
 
-   if (!action)
 
-     {
 
-     return true;
 
-     }
 
-   if (action->isSeparator())
 
-     {
 
-     return false;
 
-     }
 
-   if (action->text().isEmpty())
 
-     {// not sure what the empty text actions are
 
-     return false;
 
-     }
 
-   if (!d->ActionsWithNoShortcutVisible && shortcutItem->text().isEmpty())
 
-     {
 
-     return false;
 
-     }
 
-   if (!d->MenuActionsVisible && action->menu())
 
-     {
 
-     return false;
 
-     }
 
-   return true;
 
- }
 
- //---------------------------------------------------------------------------
 
- void ctkRichTextItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option,
 
-                                     const QModelIndex &index) const
 
- {
 
-   QStyleOptionViewItemV4 options = option;
 
-   initStyleOption(&options, index);
 
-   if (! Qt::mightBeRichText(options.text))
 
-     {
 
-     this->QStyledItemDelegate::paint(painter, option, index);
 
-     return;
 
-     }
 
-   painter->save();
 
-   QTextDocument doc;
 
-   doc.setHtml(options.text);
 
-   /* Call this to get the focus rect and selection background. */
 
-   options.text = "";
 
-   options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);
 
-   /* Draw using our rich text document. */
 
-   painter->translate(options.rect.left(), options.rect.top());
 
-   QRect clip(0, 0, options.rect.width(), options.rect.height());
 
-   doc.drawContents(painter, clip);
 
-   painter->restore();
 
- }
 
- //---------------------------------------------------------------------------
 
- QSize ctkRichTextItemDelegate::sizeHint(const QStyleOptionViewItem & option,
 
-                                         const QModelIndex & index)const
 
- {
 
-   QStyleOptionViewItemV4 options = option;
 
-   initStyleOption(&options, index);
 
-   if (! Qt::mightBeRichText(options.text))
 
-     {
 
-     return this->QStyledItemDelegate::sizeHint(option, index);;
 
-     }
 
-   QTextDocument doc;
 
-   doc.setHtml(options.text);
 
-   doc.setTextWidth(options.rect.width());
 
-   return QSize(doc.idealWidth(), doc.size().height());
 
- }
 
 
  |