File indexing completed on 2024-05-12 04:38:23

0001 /*
0002     SPDX-FileCopyrightText: David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_WORKINGSET_H
0008 #define KDEVPLATFORM_WORKINGSET_H
0009 
0010 #include <QObject>
0011 #include <QIcon>
0012 #include <KConfigGroup>
0013 #include <QPointer>
0014 #include <QSet>
0015 
0016 namespace Sublime {
0017 class Area;
0018 class AreaIndex;
0019 class View;
0020 }
0021 
0022 namespace KDevelop {
0023 
0024 /// Contains all significant parameters which control the appearance of a working set icon
0025 struct WorkingSetIconParameters {
0026     explicit WorkingSetIconParameters(const QString& id)
0027         : setId(qHash(id) % 268435459)
0028         , coloredCount((setId % 15 < 4) ? 1 : (setId % 15 < 10) ? 2 : (setId % 15 == 14) ? 4 : 3)
0029         , hue((setId % 273 * 83) % 360)
0030         , swapDiagonal(setId % 31 < 16)
0031     { };
0032     // calculate layout and colors depending on the working set ID
0033     // modulo it so it's around 2^28, leaving some space before uint overflows
0034     const uint setId;
0035     // amount of colored squares in this icon (the rest is grey or whatever you set as default color)
0036     // use 4-6-4-1 weighting for 1, 2, 3, 4 squares, because that's the number of arrangements for each
0037     const uint coloredCount;
0038     const uint hue;
0039     bool swapDiagonal;
0040     // between 0 and 100, 100 = very similar, 0 = very different
0041     // 20 points should make a significantly different icon.
0042     uint similarity(const WorkingSetIconParameters& other) const {
0043         int sim = 100;
0044         uint hueDiff = qAbs<int>(hue - other.hue);
0045         hueDiff = hueDiff > 180 ? 360 - hueDiff : hueDiff;
0046         sim -= hueDiff > 35 ? 50 : (hueDiff * 50) / 180;
0047         if ( coloredCount != other.coloredCount ) {
0048             sim -= 50;
0049         }
0050         else if ( coloredCount == 2 && swapDiagonal != other.swapDiagonal ) {
0051             sim -= 35;
0052         }
0053         return sim;
0054     };
0055 };
0056 
0057 
0058 class WorkingSet : public QObject {
0059     Q_OBJECT
0060 
0061 public:
0062     explicit WorkingSet(const QString& id);
0063 
0064     bool isConnected(Sublime::Area* area);
0065 
0066     QIcon icon() const;
0067 
0068     bool isPersistent() const;
0069 
0070     void setPersistent(bool persistent);
0071 
0072     QString id() const;
0073 
0074     QStringList fileList() const;
0075 
0076     QSet<QString> fileSet() const;
0077 
0078     bool isEmpty() const;
0079 
0080     ///Updates this working-set from the given area
0081     void saveFromArea(Sublime::Area* area);
0082 
0083     ///Loads this working-set directly from the configuration file, and stores it in the given area
0084     ///Does not ask the user, this should be done beforehand.
0085     void loadToArea(Sublime::Area* area);
0086 
0087     bool hasConnectedAreas() const;
0088 
0089     bool hasConnectedArea(Sublime::Area *area) const;
0090 
0091     void connectArea(Sublime::Area* area);
0092 
0093     void disconnectArea(Sublime::Area* area);
0094 
0095     void deleteSet(bool force, bool silent = false);
0096 
0097 private Q_SLOTS:
0098     void areaViewAdded(Sublime::AreaIndex* /*index*/, Sublime::View* /*view*/);
0099     void areaViewRemoved(Sublime::AreaIndex* /*index*/, Sublime::View* /*view*/);
0100 
0101 Q_SIGNALS:
0102     void setChangedSignificantly();
0103     void aboutToRemove(WorkingSet*);
0104 
0105 private:
0106     void changed(Sublime::Area* area);
0107 
0108     const QString m_id;
0109     const QIcon m_icon;
0110     QVector<QPointer<Sublime::Area>> m_areas;
0111     static bool m_loading;
0112 };
0113 
0114 }
0115 
0116 #endif // KDEVPLATFORM_WORKINGSET_H