File indexing completed on 2025-04-27 03:58:31

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2005-03-22
0007  * Description : a widget to manage sidebar in GUI - Splitter implementation.
0008  *
0009  * SPDX-FileCopyrightText: 2005-2006 by Joern Ahrens <joern dot ahrens at kdemail dot net>
0010  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2008-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0012  * SPDX-FileCopyrightText: 2001-2003 by Joseph Wenninger <jowenn at kde dot org>
0013  *
0014  * SPDX-License-Identifier: GPL-2.0-or-later
0015  *
0016  * ============================================================ */
0017 
0018 #include "sidebar_p.h"
0019 
0020 namespace Digikam
0021 {
0022 
0023 const QString SidebarSplitter::DEFAULT_CONFIG_KEY = QLatin1String("SplitterState");
0024 
0025 SidebarSplitter::SidebarSplitter(QWidget* const parent)
0026     : QSplitter(parent),
0027       d        (new Private)
0028 {
0029     connect(this, SIGNAL(splitterMoved(int,int)),
0030             this, SLOT(slotSplitterMoved(int,int)));
0031 }
0032 
0033 SidebarSplitter::SidebarSplitter(Qt::Orientation orientation, QWidget* const parent)
0034     : QSplitter(orientation, parent),
0035       d        (new Private)
0036 {
0037     connect(this, SIGNAL(splitterMoved(int,int)),
0038             this, SLOT(slotSplitterMoved(int,int)));
0039 }
0040 
0041 SidebarSplitter::~SidebarSplitter()
0042 {
0043     // retreat cautiously from sidebars that live longer
0044 
0045     Q_FOREACH (Sidebar* const sidebar, d->sidebars)
0046     {
0047         sidebar->d->splitter = nullptr;
0048     }
0049 
0050     delete d;
0051 }
0052 
0053 void SidebarSplitter::restoreState(KConfigGroup& group)
0054 {
0055     restoreState(group, DEFAULT_CONFIG_KEY);
0056 }
0057 
0058 void SidebarSplitter::restoreState(KConfigGroup& group, const QString& key)
0059 {
0060     if (group.hasKey(key))
0061     {
0062         QByteArray state;
0063         state = group.readEntry(key, state);
0064 
0065         if (!state.isEmpty())
0066         {
0067             QSplitter::restoreState(QByteArray::fromBase64(state));
0068         }
0069     }
0070 }
0071 
0072 void SidebarSplitter::saveState(KConfigGroup& group)
0073 {
0074     saveState(group, DEFAULT_CONFIG_KEY);
0075 }
0076 
0077 void SidebarSplitter::saveState(KConfigGroup& group, const QString& key)
0078 {
0079     group.writeEntry(key, QSplitter::saveState().toBase64());
0080 }
0081 
0082 int SidebarSplitter::size(Sidebar* const bar) const
0083 {
0084     return size(bar->d->stack);
0085 }
0086 
0087 int SidebarSplitter::size(QWidget* const widget) const
0088 {
0089     int index = indexOf(widget);
0090 
0091     if (index == -1)
0092     {
0093         return -1;
0094     }
0095 
0096     return sizes().at(index);
0097 }
0098 
0099 void SidebarSplitter::setSize(Sidebar* const bar, int size)
0100 {
0101     setSize(bar->d->stack, size);
0102 }
0103 
0104 void SidebarSplitter::setSize(QWidget* const widget, int size)
0105 {
0106     int index = indexOf(widget);
0107 
0108     if (index == -1)
0109     {
0110         return;
0111     }
0112 
0113     // special case: Use minimum size hint
0114 
0115     if (size == -1)
0116     {
0117         if (orientation() == Qt::Horizontal)
0118         {
0119             size = widget->minimumSizeHint().width();
0120         }
0121 
0122         if (orientation() == Qt::Vertical)
0123         {
0124             size = widget->minimumSizeHint().height();
0125         }
0126     }
0127 
0128     QList<int> sizeList = sizes();
0129     sizeList[index]     = size;
0130     setSizes(sizeList);
0131 }
0132 
0133 void SidebarSplitter::slotSplitterMoved(int pos, int index)
0134 {
0135     Q_UNUSED(pos);
0136 
0137     // When the user moves the splitter so that size is 0 (collapsed),
0138     // it may be difficult to restore the sidebar as clicking the buttons
0139     // has no effect (only hides/shows the splitter handle)
0140     // So we want to transform this size-0-sidebar
0141     // to a sidebar that is shrunk (d->stack hidden)
0142     // and can be restored by clicking a tab bar button
0143 
0144     // We need to look at the widget between index-1 and index
0145     // and the one between index and index+1
0146 
0147     QList<int> sizeList = sizes();
0148 
0149     // Is there a sidebar with size 0 before index ?
0150 
0151     if ((index > 0) && (sizeList.at(index-1) == 0))
0152     {
0153         QWidget* const w = widget(index-1);
0154 
0155         Q_FOREACH (Sidebar* const sidebar, d->sidebars)
0156         {
0157             if (w == sidebar->d->stack)
0158             {    // cppcheck-suppress useStlAlgorithm
0159                 if (!sidebar->d->minimized)
0160                 {
0161                     sidebar->setTab(sidebar->d->activeTab, false);
0162                     sidebar->shrink();
0163                 }
0164 
0165                 break;
0166             }
0167         }
0168     }
0169 
0170     // Is there a sidebar with size 0 after index ?
0171 
0172     if (sizeList.at(index) == 0)
0173     {
0174         QWidget* const w = widget(index);
0175 
0176         Q_FOREACH (Sidebar* const sidebar, d->sidebars)
0177         {
0178             if (w == sidebar->d->stack)
0179             {   // cppcheck-suppress useStlAlgorithm
0180                 if (!sidebar->d->minimized)
0181                 {
0182                     sidebar->setTab(sidebar->d->activeTab, false);
0183                     sidebar->shrink();
0184                 }
0185 
0186                 break;
0187             }
0188         }
0189     }
0190 }
0191 
0192 } // namespace Digikam