File indexing completed on 2025-01-19 03:53:21

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-03-25
0007  * Description : Tree View for album models
0008  *
0009  * SPDX-FileCopyrightText: 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2010-2011 by Andi Clemens <andi dot clemens at gmail dot com>
0011  * SPDX-FileCopyrightText: 2014      by Mohamed_Anwer <m_dot_anwer at gmx dot com>
0012  * SPDX-FileCopyrightText: 2014      by Michael G. Hansen <mike at mghansen dot de>
0013  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0014  *
0015  * SPDX-License-Identifier: GPL-2.0-or-later
0016  *
0017  * ============================================================ */
0018 
0019 #include "abstractcheckablealbumtreeview.h"
0020 
0021 // KDE includes
0022 
0023 #include <kconfiggroup.h>
0024 
0025 // Local includes
0026 
0027 #include "abstractalbumtreeview_p.h"
0028 
0029 namespace Digikam
0030 {
0031 
0032 class Q_DECL_HIDDEN AbstractCheckableAlbumTreeView::Private
0033 {
0034 public:
0035 
0036     explicit Private()
0037     {
0038     }
0039 
0040     static const QString configCheckedAlbumsEntry;
0041     static const QString configPartiallyCheckedAlbumsEntry;
0042     static const QString configRestoreCheckedEntry;
0043 
0044     QList<int>           checkedAlbumIds;
0045     QList<int>           partiallyCheckedAlbumIds;
0046 };
0047 
0048 const QString AbstractCheckableAlbumTreeView::Private::configCheckedAlbumsEntry(QLatin1String("Checked"));
0049 const QString AbstractCheckableAlbumTreeView::Private::configPartiallyCheckedAlbumsEntry(QLatin1String("PartiallyChecked"));
0050 const QString AbstractCheckableAlbumTreeView::Private::configRestoreCheckedEntry(QLatin1String("RestoreChecked"));
0051 
0052 // --------------------------------------------------------
0053 
0054 AbstractCheckableAlbumTreeView::AbstractCheckableAlbumTreeView(QWidget* const parent, Flags flags)
0055     : AbstractCountingAlbumTreeView(parent, flags & ~CreateDefaultFilterModel),
0056       d                            (new Private)
0057 {
0058     m_checkOnMiddleClick = true;
0059     m_restoreCheckState  = false;
0060 
0061     if (flags & CreateDefaultFilterModel)
0062     {
0063         setAlbumFilterModel(new CheckableAlbumFilterModel(this));
0064     }
0065 }
0066 
0067 AbstractCheckableAlbumTreeView::~AbstractCheckableAlbumTreeView()
0068 {
0069     delete d;
0070 }
0071 
0072 AbstractCheckableAlbumModel* AbstractCheckableAlbumTreeView::albumModel() const
0073 {
0074     return dynamic_cast<AbstractCheckableAlbumModel*>(m_albumModel);
0075 }
0076 
0077 CheckableAlbumFilterModel* AbstractCheckableAlbumTreeView::albumFilterModel() const
0078 {
0079     return dynamic_cast<CheckableAlbumFilterModel*> (m_albumFilterModel);
0080 }
0081 
0082 void AbstractCheckableAlbumTreeView::setCheckOnMiddleClick(bool doThat)
0083 {
0084     m_checkOnMiddleClick = doThat;
0085 }
0086 
0087 void AbstractCheckableAlbumTreeView::middleButtonPressed(Album* a)
0088 {
0089     AbstractCheckableAlbumModel* const model = static_cast<AbstractCheckableAlbumModel*>(m_albumModel);
0090 
0091     if (!model)
0092     {
0093         return;
0094     }
0095 
0096     if (model->isCheckable())
0097     {
0098         if (model->isTristate())
0099         {
0100             switch (model->checkState(a))
0101             {
0102                 case Qt::Unchecked:
0103                     model->setCheckState(a, Qt::PartiallyChecked);
0104                     break;
0105                 case Qt::PartiallyChecked:
0106                     model->setCheckState(a, Qt::Checked);
0107                     break;
0108                 case Qt::Checked:
0109                     model->setCheckState(a, Qt::Unchecked);
0110                     break;
0111             }
0112         }
0113         else
0114         {
0115             model->toggleChecked(a);
0116         }
0117     }
0118 }
0119 
0120 bool AbstractCheckableAlbumTreeView::isRestoreCheckState() const
0121 {
0122     return m_restoreCheckState;
0123 }
0124 
0125 void AbstractCheckableAlbumTreeView::setRestoreCheckState(bool restore)
0126 {
0127     m_restoreCheckState = restore;
0128 }
0129 
0130 void AbstractCheckableAlbumTreeView::doLoadState()
0131 {
0132     AbstractCountingAlbumTreeView::doLoadState();
0133 
0134     KConfigGroup group = getConfigGroup();
0135 
0136     if (!m_restoreCheckState)
0137     {
0138         m_restoreCheckState = group.readEntry(entryName(d->configRestoreCheckedEntry), false);
0139     }
0140 
0141     if (!m_restoreCheckState || !checkableModel()->isCheckable())
0142     {
0143         return;
0144     }
0145 
0146     const QStringList checkedAlbums = group.readEntry(entryName(d->configCheckedAlbumsEntry), QStringList());
0147 
0148     d->checkedAlbumIds.clear();
0149 
0150     Q_FOREACH (const QString& albumId, checkedAlbums)
0151     {
0152         bool ok;
0153         const int id = albumId.toInt(&ok);
0154 
0155         if (ok)
0156         {
0157             d->checkedAlbumIds << id;
0158         }
0159     }
0160 
0161     const QStringList partiallyCheckedAlbums = group.readEntry(entryName(d->configPartiallyCheckedAlbumsEntry), QStringList());
0162     d->partiallyCheckedAlbumIds.clear();
0163 
0164     Q_FOREACH (const QString& albumId, partiallyCheckedAlbums)
0165     {
0166         bool ok;
0167         const int id = albumId.toInt(&ok);
0168 
0169         if (ok)
0170         {
0171             d->partiallyCheckedAlbumIds << id;
0172         }
0173     }
0174 
0175     // initially sync with the albums that are already in the model
0176 
0177     restoreCheckStateForHierarchy(QModelIndex());
0178     horizontalScrollBar()->setValue(0);
0179 }
0180 
0181 void AbstractCheckableAlbumTreeView::rowsInserted(const QModelIndex& parent, int start, int end)
0182 {
0183     AbstractCountingAlbumTreeView::rowsInserted(parent, start, end);
0184 
0185     if (!d->checkedAlbumIds.isEmpty())
0186     {
0187         for (int i = start ; i <= end ; ++i)
0188         {
0189             const QModelIndex child = checkableModel()->index(i, 0, parent);
0190             restoreCheckState(child);
0191         }
0192     }
0193 }
0194 
0195 void AbstractCheckableAlbumTreeView::restoreCheckStateForHierarchy(const QModelIndex& index)
0196 {
0197     // recurse children
0198 
0199     for (int i = 0 ; i < checkableModel()->rowCount(index) ; ++i)
0200     {
0201         const QModelIndex child = checkableModel()->index(i, 0, index);
0202         restoreCheckState(child);
0203         restoreCheckStateForHierarchy(child);
0204     }
0205 }
0206 
0207 void AbstractCheckableAlbumTreeView::restoreCheckState(const QModelIndex& index)
0208 {
0209     Album* const album = checkableModel()->albumForIndex(index);
0210 
0211     if (!album || !(album->id()))
0212     {
0213         return;
0214     }
0215 
0216     if (d->checkedAlbumIds.contains(album->id()))
0217     {
0218         checkableModel()->setCheckState(album, Qt::Checked);
0219         d->checkedAlbumIds.removeOne(album->id());
0220     }
0221 
0222     if (d->partiallyCheckedAlbumIds.contains(album->id()))
0223     {
0224         checkableModel()->setCheckState(album, Qt::PartiallyChecked);
0225         d->partiallyCheckedAlbumIds.removeOne(album->id());
0226     }
0227 }
0228 
0229 void AbstractCheckableAlbumTreeView::doSaveState()
0230 {
0231     AbstractCountingAlbumTreeView::doSaveState();
0232 
0233     KConfigGroup group = getConfigGroup();
0234 
0235     group.writeEntry(entryName(d->configRestoreCheckedEntry), m_restoreCheckState);
0236 
0237     if (!m_restoreCheckState || !checkableModel()->isCheckable())
0238     {
0239         return;
0240     }
0241 
0242     const QList<Album*> checkedAlbums = checkableModel()->checkedAlbums();
0243     QStringList checkedIds;
0244 
0245     Q_FOREACH (Album* const album, checkedAlbums)
0246     {
0247         checkedIds << QString::number(album->id());
0248     }
0249 
0250     group.writeEntry(entryName(d->configCheckedAlbumsEntry), checkedIds);
0251 
0252     if (!checkableModel()->isTristate())
0253     {
0254         return;
0255     }
0256 
0257     const QList<Album*> partiallyCheckedAlbums = checkableModel()->partiallyCheckedAlbums();
0258     QStringList partiallyCheckedIds;
0259 
0260     Q_FOREACH (Album* const album, partiallyCheckedAlbums)
0261     {
0262         partiallyCheckedIds << QString::number(album->id());
0263     }
0264 
0265     group.writeEntry(entryName(d->configPartiallyCheckedAlbumsEntry), partiallyCheckedIds);
0266 }
0267 
0268 } // namespace Digikam
0269 
0270 #include "moc_abstractcheckablealbumtreeview.cpp"