11#include <config-libkleo.h> 
   13#include "treewidget.h" 
   15#include <models/keylist.h> 
   17#include <KConfigGroup> 
   18#include <KLocalizedString> 
   19#include <KSharedConfig> 
   22#include <QContextMenuEvent> 
   23#include <QGuiApplication> 
   29static const int MAX_AUTOMATIC_COLUMN_WIDTH = 400;
 
   31class TreeWidget::Private
 
   36    QMenu *mHeaderPopup = 
nullptr;
 
   37    QList<QAction *> mColumnActions;
 
   38    QString mStateGroupName;
 
   39    std::vector<bool> mColumnForcedHidden;
 
   41    Private(TreeWidget *qq)
 
   50    void saveColumnLayout();
 
   53TreeWidget::TreeWidget(
QWidget *parent)
 
   55    , d{new Private(this)}
 
   60TreeWidget::~TreeWidget() = 
default;
 
   68    d->mColumnForcedHidden.resize(
columnCount(), 
false);
 
   69    d->mColumnForcedHidden[column] = 
true;
 
 
   72void TreeWidget::Private::saveColumnLayout()
 
   74    if (mStateGroupName.isEmpty()) {
 
   78    auto header = q->header();
 
   80    QVariantList columnVisibility;
 
   81    QVariantList columnOrder;
 
   82    QVariantList columnWidths;
 
   83    const int headerCount = header->count();
 
   84    columnVisibility.reserve(headerCount);
 
   85    columnWidths.reserve(headerCount);
 
   86    columnOrder.reserve(headerCount);
 
   87    for (
int i = 0; i < headerCount; ++i) {
 
   88        columnVisibility << 
QVariant(!q->isColumnHidden(i));
 
   89        columnWidths << 
QVariant(header->sectionSize(i));
 
   90        columnOrder << 
QVariant(header->visualIndex(i));
 
   93    config.writeEntry(
"ColumnVisibility", columnVisibility);
 
   94    config.writeEntry(
"ColumnOrder", columnOrder);
 
   95    config.writeEntry(
"ColumnWidths", columnWidths);
 
   97    config.writeEntry(
"SortAscending", (
int)header->sortIndicatorOrder());
 
   98    if (header->isSortIndicatorShown()) {
 
   99        config.writeEntry(
"SortColumn", header->sortIndicatorSection());
 
  101        config.writeEntry(
"SortColumn", -1);
 
  108    if (stateGroupName.
isEmpty()) {
 
  112    d->mColumnForcedHidden.resize(
columnCount(), 
false);
 
  114    d->mStateGroupName = stateGroupName;
 
  118    QVariantList columnVisibility = config.readEntry(
"ColumnVisibility", QVariantList());
 
  119    QVariantList columnOrder = config.readEntry(
"ColumnOrder", QVariantList());
 
  120    QVariantList columnWidths = config.readEntry(
"ColumnWidths", QVariantList());
 
  122    if (!columnVisibility.isEmpty() && !columnOrder.isEmpty() && !columnWidths.isEmpty()) {
 
  123        for (
int i = 0; i < 
header->count(); ++i) {
 
  124            if (d->mColumnForcedHidden[i] || i >= columnOrder.size() || i >= columnWidths.size() || i >= columnVisibility.size()) {
 
  129            bool visible = columnVisibility[i].toBool();
 
  130            int width = columnWidths[i].toInt();
 
  131            int order = columnOrder[i].toInt();
 
  141        for (
int i = 0; i < 
header->count(); ++i) {
 
  142            if (d->mColumnForcedHidden[i]) {
 
  154        d->saveColumnLayout();
 
  157        d->saveColumnLayout();
 
  160        d->saveColumnLayout();
 
  162    return !columnVisibility.isEmpty() && !columnOrder.isEmpty() && !columnWidths.isEmpty();
 
 
  170        if (!d->mHeaderPopup) {
 
  171            d->mHeaderPopup = 
new QMenu(
this);
 
  172            d->mHeaderPopup->setTitle(
i18nc(
"@title:menu", 
"View Columns"));
 
  173            for (
int i = 0; i < model()->columnCount(); ++i) {
 
  177                d->mColumnActions << tmp;
 
  181                const int col = action->data().toInt();
 
  182                if (action->isChecked()) {
 
  184                    if (columnWidth(col) == 0 || columnWidth(col) == header()->defaultSectionSize()) {
 
  185                        resizeColumnToContents(col);
 
  186                        setColumnWidth(col, std::min(columnWidth(col), MAX_AUTOMATIC_COLUMN_WIDTH));
 
  193                    Q_EMIT columnEnabled(col);
 
  195                    Q_EMIT columnDisabled(col);
 
  197                d->saveColumnLayout();
 
  201        for (QAction *action : std::as_const(d->mColumnActions)) {
 
  202            const int column = action->data().toInt();
 
  203            action->setChecked(!isColumnHidden(column));
 
  206        auto numVisibleColumns = std::count_if(d->mColumnActions.cbegin(), d->mColumnActions.cend(), [](
const auto &action) {
 
  207            return action->isChecked();
 
  210        for (
auto action : std::as_const(d->mColumnActions)) {
 
  211            action->setEnabled(numVisibleColumns != 1 || !action->isChecked());
 
  214        d->mHeaderPopup->popup(mapToGlobal(e->pos()));
 
  221void TreeWidget::focusInEvent(QFocusEvent *event)
 
  228    auto forceAccessibleFocusEventForCurrentItem = [
this]() {
 
  232        const QModelIndex index = currentIndex();
 
  234            currentChanged(index, QModelIndex{});
 
  241void TreeWidget::keyPressEvent(QKeyEvent *event)
 
  244        const QModelIndex index = currentIndex();
 
  245        if (index.
isValid() && model()) {
 
  246            QVariant variant = model()->data(index, Kleo::ClipboardRole);
 
  268    if ((cursorAction != MoveLeft) && (cursorAction != MoveRight)) {
 
  272    const auto savedSelectionBehavior = selectionBehavior();
 
  273    setSelectionBehavior(SelectItems);
 
  274    const auto savedItemsExpandable = itemsExpandable();
 
  275    setItemsExpandable(
false);
 
  279    setItemsExpandable(savedItemsExpandable);
 
  280    setSelectionBehavior(savedSelectionBehavior);
 
  285void TreeWidget::resizeToContentsLimited()
 
  287    for (
int i = 0; i < model()->columnCount(); i++) {
 
  288        resizeColumnToContents(i);
 
  289        setColumnWidth(i, std::min(columnWidth(i), MAX_AUTOMATIC_COLUMN_WIDTH));
 
  293#include "moc_treewidget.cpp" 
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
 
QString i18nc(const char *context, const char *text, const TYPE &arg...)
 
virtual bool eventFilter(QObject *object, QEvent *event) override
 
virtual void focusInEvent(QFocusEvent *event) override
 
virtual void keyPressEvent(QKeyEvent *event) override
 
virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)=0
 
bool isChecked() const const
 
void setData(const QVariant &data)
 
void setText(const QString &text, Mode mode)
 
bool isValid() const const
 
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
void installEventFilter(QObject *filterObj)
 
bool isEmpty() const const
 
typedef KeyboardModifiers
 
void hideColumn(int column)
 
void sortByColumn(int column, Qt::SortOrder order)
 
bool isSortingEnabled() const const
 
bool canConvert() const const
 
bool isValid() const const
 
QString toString() const const