Skip to content

Commit

Permalink
Highlight the active LibraryTreeItem (#7112)
Browse files Browse the repository at this point in the history
* Highlight the active LibraryTreeItem

Fixes #7104

* Added an option to synchronize the with the ModelWidget

* Show hide the scroll to button based on setting

* Make the active item bold and modified item italic

* Don't change the color of the items as this might lead to problems in different styles/themes

* Add documentation
  • Loading branch information
adeas31 committed Feb 1, 2021
1 parent 263a0e5 commit 141624b
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 38 deletions.
41 changes: 14 additions & 27 deletions OMEdit/OMEditLIB/Modeling/ItemDelegate.cpp
Expand Up @@ -32,6 +32,7 @@
*/

#include "ItemDelegate.h"
#include "Modeling/ModelWidgetContainer.h"
#include "Modeling/LibraryTreeWidget.h"
#include "Plotting/VariablesWidget.h"
#include "Simulation/SimulationOutputWidget.h"
Expand Down Expand Up @@ -98,18 +99,18 @@ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
if (value.isValid()) {
if (value.type() == QVariant::Icon) {
icon = qvariant_cast<QIcon>(value);
decorationRect = QRect(QPoint(0, 0), icon.actualSize(option.decorationSize, iconMode, iconState));
decorationRect = QRect(QPoint(0, 0), icon.actualSize(opt.decorationSize, iconMode, iconState));
} else {
pixmap = decoration(opt, value);
decorationRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
decorationRect = QRect(QPoint(0, 0), opt.decorationSize).intersected(pixmap.rect());
}
}
QString text;
QRect displayRect;
value = index.data(Qt::DisplayRole);
if (value.isValid()) {
text = formatDisplayText(value);
displayRect = textRectangle(painter, option.rect, opt.font, text);
displayRect = textRectangle(painter, opt.rect, opt.font, text);
}
QRect checkRect;
Qt::CheckState checkState = Qt::Unchecked;
Expand All @@ -124,20 +125,6 @@ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
}
// do the layout
doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
/* We check if item belongs to QTreeView and QTreeView model is LibraryTreeProxyModel.
* If LibraryTreeItem is unsaved then draw its background as Qt::darkRed.
*/
if (parent() && qobject_cast<QTreeView*>(parent())) {
QTreeView *pTreeView = qobject_cast<QTreeView*>(parent());
LibraryTreeProxyModel *pLibraryTreeProxyModel = qobject_cast<LibraryTreeProxyModel*>(pTreeView->model());
if (pLibraryTreeProxyModel) {
QModelIndex sourceIndex = pLibraryTreeProxyModel->mapToSource(index);
LibraryTreeItem *pLibraryTreeItem = static_cast<LibraryTreeItem*>(sourceIndex.internalPointer());
if (pLibraryTreeItem && !pLibraryTreeItem->isSaved()) {
opt.palette.setBrush(QPalette::Highlight, Qt::darkRed);
}
}
}
// draw background
drawBackground(painter, opt, index);
// hover
Expand All @@ -148,16 +135,16 @@ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
if (mDrawGrid) {
QPen pen;
if (!mGridColor.isValid()) {
int gridHint = qApp->style()->styleHint(QStyle::SH_Table_GridLineColor, &option);
int gridHint = qApp->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt);
const QColor gridColor = static_cast<QRgb>(gridHint);
pen.setColor(gridColor);
} else {
pen.setColor(mGridColor);
}
painter->save();
painter->setPen(pen);
painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
painter->drawLine(opt.rect.topRight(), opt.rect.bottomRight());
painter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight());
painter->restore();
}
/* ticket:5050 Use Qt::ElideRight for value column only if the value is a double in non-scientific notation.
Expand All @@ -176,20 +163,20 @@ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
if (mDrawRichText) {
QAbstractTextDocumentLayout::PaintContext ctx;
QTextDocument textDocument;
initTextDocument(&textDocument, opt.font, option.rect.width());
initTextDocument(&textDocument, opt.font, opt.rect.width());

QVariant variant = index.data(Qt::ForegroundRole);
if (variant.isValid()) {
if (option.state & ~QStyle::State_Selected) {
if (opt.state & ~QStyle::State_Selected) {
ctx.palette.setColor(QPalette::Text, variant.value<QColor>());
}
}
QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) {
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
cg = QPalette::Inactive;
}
if (option.state & QStyle::State_Selected) {
ctx.palette.setColor(QPalette::Text, option.palette.color(cg, QPalette::HighlightedText));
if (opt.state & QStyle::State_Selected) {
ctx.palette.setColor(QPalette::Text, opt.palette.color(cg, QPalette::HighlightedText));
}

textDocument.setHtml(text);
Expand All @@ -207,7 +194,7 @@ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
if (mDrawRichText) {
decorationRect = QRect(decorationRect.left(), displayRect.top() + 4, decorationRect.width(), decorationRect.height());
}
icon.paint(painter, decorationRect, option.decorationAlignment, QIcon::Normal, QIcon::Off);
icon.paint(painter, decorationRect, opt.decorationAlignment, QIcon::Normal, QIcon::Off);
} else {
drawDecoration(painter, opt, decorationRect, pixmap);
}
Expand Down
33 changes: 30 additions & 3 deletions OMEdit/OMEditLIB/Modeling/LibraryTreeWidget.cpp
Expand Up @@ -763,8 +763,19 @@ QVariant LibraryTreeItem::data(int column, int role) const
}
case Qt::ToolTipRole:
return getTooltip();
case Qt::ForegroundRole:
return mIsSaved ? QVariant() : QColor(Qt::darkRed);
case Qt::FontRole:
if (!mIsSaved || (mpModelWidget && mpModelWidget == MainWindow::instance()->getModelWidgetContainer()->getCurrentModelWidget())) {
QFont font;
if (mpModelWidget && mpModelWidget == MainWindow::instance()->getModelWidgetContainer()->getCurrentModelWidget()) {
font.setBold(true);
}
if (!mIsSaved) {
font.setItalic(true);
}
return font;
} else {
return QVariant();
}
default:
return QVariant();
}
Expand Down Expand Up @@ -4034,6 +4045,8 @@ LibraryWidget::LibraryWidget(QWidget *pParent)
connect(mpTreeSearchFilters->getSyntaxComboBox(), SIGNAL(currentIndexChanged(int)), SLOT(searchClasses()));
mpTreeSearchFilters->getExpandAllButton()->hide();
mpTreeSearchFilters->getCollapseAllButton()->hide();
mpTreeSearchFilters->getScrollToActiveButton()->setVisible(!OptionsDialog::instance()->getGeneralSettingsPage()->getSynchronizeWithModelWidgetCheckBox()->isChecked());
connect(mpTreeSearchFilters->getScrollToActiveButton(), SIGNAL(clicked()), SLOT(scrollToActiveLibraryTreeItem()));
// create tree view
mpLibraryTreeModel = new LibraryTreeModel(this);
mpLibraryTreeProxyModel = new LibraryTreeProxyModel(this, false);
Expand All @@ -4050,7 +4063,7 @@ LibraryWidget::LibraryWidget(QWidget *pParent)
pMainLayout->setContentsMargins(0, 0, 0, 0);
pMainLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
pMainLayout->addWidget(mpTreeSearchFilters, 0, 0);
pMainLayout->addWidget(mpLibraryTreeView, 1, 0);
pMainLayout->addWidget(mpLibraryTreeView, 2, 0);
setLayout(pMainLayout);
}

Expand Down Expand Up @@ -5196,6 +5209,20 @@ bool LibraryWidget::saveTotalLibraryTreeItemHelper(LibraryTreeItem *pLibraryTree
return result;
}

/*!
* \brief LibraryWidget::scrollToActiveLibraryTreeItem
* Makes sure that active LibraryTreeItem is visible. Scrolls to active LibraryTreeItem.
*/
void LibraryWidget::scrollToActiveLibraryTreeItem()
{
ModelWidget *pModelWidget = MainWindow::instance()->getModelWidgetContainer()->getCurrentModelWidget();
if (pModelWidget && pModelWidget->getLibraryTreeItem()) {
QModelIndex modelIndex = mpLibraryTreeModel->libraryTreeItemIndex(pModelWidget->getLibraryTreeItem());
QModelIndex proxyIndex = mpLibraryTreeProxyModel->mapFromSource(modelIndex);
mpLibraryTreeView->scrollTo(proxyIndex);
}
}

/*!
* \brief LibraryWidget::searchClasses
* Searches the classes in the Libraries Browser.
Expand Down
1 change: 1 addition & 0 deletions OMEdit/OMEditLIB/Modeling/LibraryTreeWidget.h
Expand Up @@ -509,6 +509,7 @@ class LibraryWidget : public QWidget
bool saveCompositeModelLibraryTreeItem(LibraryTreeItem *pLibraryTreeItem, QString fileName);
bool saveTotalLibraryTreeItemHelper(LibraryTreeItem *pLibraryTreeItem);
public slots:
void scrollToActiveLibraryTreeItem();
void searchClasses();
};

Expand Down
11 changes: 8 additions & 3 deletions OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp
Expand Up @@ -8263,16 +8263,21 @@ void ModelWidgetContainer::currentModelWidgetChanged(QMdiSubWindow *pSubWindow)
MainWindow::instance()->getUndoAction()->setEnabled(false);
MainWindow::instance()->getRedoAction()->setEnabled(false);
}
/* ticket:4983 Update the documentation browser when a new ModelWidget is selected.
* Provided that the Documentation Browser is already visible.
*/
if (!pSubWindow || mpLastActiveSubWindow == pSubWindow) {
return;
}
mpLastActiveSubWindow = pSubWindow;
/* ticket:4983 Update the documentation browser when a new ModelWidget is selected.
* Provided that the Documentation Browser is already visible.
*/
if (pModelWidget && pModelWidget->getLibraryTreeItem() && MainWindow::instance()->getDocumentationDockWidget()->isVisible()) {
MainWindow::instance()->getDocumentationWidget()->showDocumentation(pModelWidget->getLibraryTreeItem());
}
// Update the LibraryTreeView to mark the active model
MainWindow::instance()->getLibraryWidget()->getLibraryTreeView()->viewport()->update();
if (OptionsDialog::instance()->getGeneralSettingsPage()->getSynchronizeWithModelWidgetCheckBox()->isChecked()) {
MainWindow::instance()->getLibraryWidget()->scrollToActiveLibraryTreeItem();
}
}

/*!
Expand Down
11 changes: 11 additions & 0 deletions OMEdit/OMEditLIB/Options/OptionsDialog.cpp
Expand Up @@ -231,6 +231,10 @@ void OptionsDialog::readGeneralSettings()
if (mpSettings->contains("showHiddenClasses")) {
mpGeneralSettingsPage->setShowHiddenClasses(mpSettings->value("showHiddenClasses").toBool());
}
// read synchronize with ModelWidget
if (mpSettings->contains("synchronizeWithModelWidget")) {
mpGeneralSettingsPage->getSynchronizeWithModelWidgetCheckBox()->setChecked(mpSettings->value("synchronizeWithModelWidget").toBool());
}
// read auto save
if (mpSettings->contains("autoSave/enable")) {
mpGeneralSettingsPage->getEnableAutoSaveGroupBox()->setChecked(mpSettings->value("autoSave/enable").toBool());
Expand Down Expand Up @@ -1044,6 +1048,9 @@ void OptionsDialog::saveGeneralSettings()
mpSettings->setValue("showHiddenClasses", mpGeneralSettingsPage->getShowHiddenClasses());
// show/hide the protected classes
MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->showHideProtectedClasses();
// save synchronize with ModelWidget
mpSettings->setValue("synchronizeWithModelWidget", mpGeneralSettingsPage->getSynchronizeWithModelWidgetCheckBox()->isChecked());
MainWindow::instance()->getLibraryWidget()->getTreeSearchFilters()->getScrollToActiveButton()->setVisible(!mpGeneralSettingsPage->getSynchronizeWithModelWidgetCheckBox()->isChecked());
// save auto save
mpSettings->setValue("autoSave/enable", mpGeneralSettingsPage->getEnableAutoSaveGroupBox()->isChecked());
mpSettings->setValue("autoSave/interval", mpGeneralSettingsPage->getAutoSaveIntervalSpinBox()->value());
Expand Down Expand Up @@ -1956,6 +1963,9 @@ GeneralSettingsPage::GeneralSettingsPage(OptionsDialog *pOptionsDialog)
mpShowProtectedClasses = new QCheckBox(tr("Show Protected Classes"));
// show hidden classes
mpShowHiddenClasses = new QCheckBox(tr("Show Hidden Classes (Ignores the annotation(Protection(access = Access.hide)))"));
// synchronize Libraries Browser with ModelWidget
mpSynchronizeWithModelWidgetCheckBox = new QCheckBox(tr("Synchronize with Model Widget"));
mpSynchronizeWithModelWidgetCheckBox->setChecked(true);
// Libraries Browser group box layout
QGridLayout *pLibrariesBrowserLayout = new QGridLayout;
pLibrariesBrowserLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Expand All @@ -1966,6 +1976,7 @@ GeneralSettingsPage::GeneralSettingsPage(OptionsDialog *pOptionsDialog)
pLibrariesBrowserLayout->addWidget(mpLibraryIconTextLengthSpinBox, 1, 1);
pLibrariesBrowserLayout->addWidget(mpShowProtectedClasses, 2, 0, 1, 2);
pLibrariesBrowserLayout->addWidget(mpShowHiddenClasses, 3, 0, 1, 2);
pLibrariesBrowserLayout->addWidget(mpSynchronizeWithModelWidgetCheckBox, 4, 0, 1, 2);
mpLibrariesBrowserGroupBox->setLayout(pLibrariesBrowserLayout);
// Auto Save
mpEnableAutoSaveGroupBox = new QGroupBox(tr("Enable Auto Save"));
Expand Down
2 changes: 2 additions & 0 deletions OMEdit/OMEditLIB/Options/OptionsDialog.h
Expand Up @@ -241,6 +241,7 @@ class GeneralSettingsPage : public QWidget
bool getShowProtectedClasses() {return mpShowProtectedClasses->isChecked();}
void setShowHiddenClasses(bool value) {mpShowHiddenClasses->setChecked(value);}
bool getShowHiddenClasses() {return mpShowHiddenClasses->isChecked();}
QCheckBox* getSynchronizeWithModelWidgetCheckBox() {return mpSynchronizeWithModelWidgetCheckBox;}
QGroupBox* getEnableAutoSaveGroupBox() {return mpEnableAutoSaveGroupBox;}
QSpinBox* getAutoSaveIntervalSpinBox() {return mpAutoSaveIntervalSpinBox;}
int getWelcomePageView();
Expand Down Expand Up @@ -276,6 +277,7 @@ class GeneralSettingsPage : public QWidget
QSpinBox *mpLibraryIconTextLengthSpinBox;
QCheckBox *mpShowProtectedClasses;
QCheckBox *mpShowHiddenClasses;
QCheckBox *mpSynchronizeWithModelWidgetCheckBox;
QGroupBox *mpEnableAutoSaveGroupBox;
Label *mpAutoSaveIntervalLabel;
QSpinBox *mpAutoSaveIntervalSpinBox;
Expand Down
18 changes: 13 additions & 5 deletions OMEdit/OMEditLIB/Util/Utilities.cpp
Expand Up @@ -69,12 +69,19 @@ TreeSearchFilters::TreeSearchFilters(QWidget *pParent)
// filter timer
mpFilterTimer = new QTimer;
mpFilterTimer->setSingleShot(true);
mpScrollToActiveButton = new QToolButton;
QString scrollToActiveButtonText = tr("Scroll to Active");
mpScrollToActiveButton->setText(scrollToActiveButtonText);
mpScrollToActiveButton->setIcon(QIcon(":/Resources/icons/step-into.svg"));
mpScrollToActiveButton->setToolTip(scrollToActiveButtonText);
mpScrollToActiveButton->setAutoRaise(true);
mpScrollToActiveButton->hide();
// show hide button
mpShowHideButton = new QToolButton;
QString text = tr("Show/hide filters");
mpShowHideButton->setText(text);
QString showHideButtonText = tr("Show/hide filters");
mpShowHideButton->setText(showHideButtonText);
mpShowHideButton->setIcon(QIcon(":/Resources/icons/down.svg"));
mpShowHideButton->setToolTip(text);
mpShowHideButton->setToolTip(showHideButtonText);
mpShowHideButton->setAutoRaise(true);
mpShowHideButton->setCheckable(true);
connect(mpShowHideButton, SIGNAL(toggled(bool)), SLOT(showHideFilters(bool)));
Expand Down Expand Up @@ -111,8 +118,9 @@ TreeSearchFilters::TreeSearchFilters(QWidget *pParent)
pMainLayout->setContentsMargins(0, 0, 0, 0);
pMainLayout->setAlignment(Qt::AlignTop);
pMainLayout->addWidget(mpFilterTextBox, 0, 0);
pMainLayout->addWidget(mpShowHideButton, 0, 1);
pMainLayout->addWidget(mpFiltersWidget, 1, 0, 1, 2);
pMainLayout->addWidget(mpScrollToActiveButton, 0, 1);
pMainLayout->addWidget(mpShowHideButton, 0, 2);
pMainLayout->addWidget(mpFiltersWidget, 1, 0, 1, 3);
setLayout(pMainLayout);
}

Expand Down
2 changes: 2 additions & 0 deletions OMEdit/OMEditLIB/Util/Utilities.h
Expand Up @@ -124,6 +124,7 @@ class TreeSearchFilters : public QWidget
TreeSearchFilters(QWidget *pParent = 0);
QLineEdit* getFilterTextBox() {return mpFilterTextBox;}
QTimer* getFilterTimer() {return mpFilterTimer;}
QToolButton* getScrollToActiveButton() {return mpScrollToActiveButton;}
QComboBox* getSyntaxComboBox() {return mpSyntaxComboBox;}
QCheckBox* getCaseSensitiveCheckBox() {return mpCaseSensitiveCheckBox;}
QPushButton* getExpandAllButton() {return mpExpandAllButton;}
Expand All @@ -133,6 +134,7 @@ class TreeSearchFilters : public QWidget
private:
QLineEdit *mpFilterTextBox;
QTimer *mpFilterTimer;
QToolButton *mpScrollToActiveButton;
QToolButton *mpShowHideButton;
QWidget *mpFiltersWidget;
QComboBox *mpSyntaxComboBox;
Expand Down
3 changes: 3 additions & 0 deletions doc/UsersGuide/source/omedit.rst
Expand Up @@ -1048,6 +1048,9 @@ General
- *Show Hidden Classes* – If enabled then Libraries Browser will also list the hidden classes.
Ignores the annotation(Protection(access = Access.hide))

- *Synchronize with Model Widget* – If enabled then Libraries Browser will scroll automatically
to the active Model Widget i.e., the current model.

- Enable Auto Save - Enables/disables the auto save feature.

- *Auto Save interval* – Sets the auto save interval value. The minimum
Expand Down

0 comments on commit 141624b

Please sign in to comment.