File indexing completed on 2023-12-03 09:01:45

0001 /*
0002  *   SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
0003  *   SPDX-FileCopyrightText: 2001-2002 Raffaele Sandrini <sandrini@kde.org>
0004  *   SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
0005  *   SPDX-FileCopyrightText: 2008 Laurent Montel <montel@kde.org>
0006  *
0007  *   SPDX-License-Identifier: GPL-2.0-or-later
0008  *
0009  */
0010 
0011 #ifndef treeview_h
0012 #define treeview_h
0013 
0014 #include <QMimeData>
0015 #include <QTreeWidget>
0016 
0017 #include <KService>
0018 #include <KServiceGroup>
0019 
0020 class QMenu;
0021 class QDropEvent;
0022 
0023 class KActionCollection;
0024 class KDesktopFile;
0025 class MenuFile;
0026 class MenuFolderInfo;
0027 class MenuEntryInfo;
0028 class MenuSeparatorInfo;
0029 class QKeySequence;
0030 
0031 static const QString SAVE_ACTION_NAME = QStringLiteral("file_save");
0032 static const QString NEW_ITEM_ACTION_NAME = QStringLiteral("new_item");
0033 static const QString NEW_SUBMENU_ACTION_NAME = QStringLiteral("new_submenu");
0034 static const QString NEW_SEPARATOR_ACTION_NAME = QStringLiteral("new_separator");
0035 static const QString CUT_ACTION_NAME = QStringLiteral("edit_cut");
0036 static const QString COPY_ACTION_NAME = QStringLiteral("edit_copy");
0037 static const QString PASTE_ACTION_NAME = QStringLiteral("edit_paste");
0038 static const QString DELETE_ACTION_NAME = QStringLiteral("delete");
0039 static const QString SORT_ACTION_NAME = QStringLiteral("sort");
0040 static const QString SORT_BY_NAME_ACTION_NAME = QStringLiteral("sort_by_name");
0041 static const QString SORT_BY_DESCRIPTION_ACTION_NAME = QStringLiteral("sort_by_description");
0042 static const QString SORT_ALL_BY_NAME_ACTION_NAME = QStringLiteral("sort_all_by_name");
0043 static const QString SORT_ALL_BY_DESCRIPTION_ACTION_NAME = QStringLiteral("sort_all_by_description");
0044 static const QString MOVE_UP_ACTION_NAME = QStringLiteral("move_up");
0045 static const QString MOVE_DOWN_ACTION_NAME = QStringLiteral("move_down");
0046 
0047 class TreeItem : public QTreeWidgetItem
0048 {
0049 public:
0050     TreeItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, const QString &menuId, bool __init = false);
0051     TreeItem(QTreeWidget *parent, QTreeWidgetItem *after, const QString &menuId, bool __init = false);
0052     ~TreeItem() override;
0053     static bool itemNameLessThan(QTreeWidgetItem *item1, QTreeWidgetItem *item2);
0054     static bool itemDescriptionLessThan(QTreeWidgetItem *item1, QTreeWidgetItem *item2);
0055 
0056     QString menuId() const
0057     {
0058         return m_menuId;
0059     }
0060 
0061     QString directory() const
0062     {
0063         return m_directoryPath;
0064     }
0065 
0066     void setDirectoryPath(const QString &path)
0067     {
0068         m_directoryPath = path;
0069     }
0070 
0071     MenuFolderInfo *folderInfo()
0072     {
0073         return m_folderInfo;
0074     }
0075 
0076     void setMenuFolderInfo(MenuFolderInfo *folderInfo)
0077     {
0078         m_folderInfo = folderInfo;
0079     }
0080 
0081     MenuEntryInfo *entryInfo() const
0082     {
0083         return m_entryInfo;
0084     }
0085 
0086     void setMenuEntryInfo(MenuEntryInfo *entryInfo)
0087     {
0088         m_entryInfo = entryInfo;
0089     }
0090 
0091     QString name() const
0092     {
0093         return m_name;
0094     }
0095 
0096     void setName(const QString &name);
0097 
0098     QString description() const;
0099 
0100     bool isDirectory() const
0101     {
0102         return m_folderInfo;
0103     }
0104 
0105     bool isEntry() const
0106     {
0107         return m_entryInfo;
0108     }
0109 
0110     bool isSeparator() const
0111     {
0112         return !isDirectory() && !isEntry();
0113     }
0114 
0115     bool isHiddenInMenu() const
0116     {
0117         return m_hidden;
0118     }
0119 
0120     void setHiddenInMenu(bool b);
0121 
0122     bool isLayoutDirty() const;
0123     void setLayoutDirty()
0124     {
0125         m_layoutDirty = true;
0126     }
0127 
0128     void saveLayout(MenuFile *menuFile);
0129 
0130     void load();
0131 
0132     // virtual void paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align);
0133 
0134 private:
0135     void update();
0136 
0137     bool m_hidden : 1;
0138     bool m_init : 1;
0139     bool m_layoutDirty : 1;
0140     QString m_menuId;
0141     QString m_name;
0142     QString m_directoryPath;
0143     MenuFolderInfo *m_folderInfo;
0144     MenuEntryInfo *m_entryInfo;
0145 };
0146 
0147 class TreeView : public QTreeWidget
0148 {
0149     friend class TreeItem;
0150     Q_OBJECT
0151 public:
0152     explicit TreeView(KActionCollection *ac, QWidget *parent = nullptr);
0153     ~TreeView() override;
0154 
0155     void readMenuFolderInfo(MenuFolderInfo *folderInfo = 0, KServiceGroup::Ptr folder = KServiceGroup::Ptr(), const QString &prefix = QString());
0156     void setViewMode(bool showHidden);
0157     bool save();
0158 
0159     bool dirty();
0160 
0161     void selectMenu(const QString &menu);
0162     void selectMenuEntry(const QString &menuEntry);
0163 
0164     void restoreMenuSystem();
0165 
0166     void updateTreeView(bool showHidden);
0167 
0168 public Q_SLOTS:
0169     void currentDataChanged(MenuFolderInfo *folderInfo);
0170     void currentDataChanged(MenuEntryInfo *entryInfo);
0171     void findServiceShortcut(const QKeySequence &, KService::Ptr &);
0172     void searchUpdated(const QString &searchString);
0173 
0174 Q_SIGNALS:
0175     void entrySelected(MenuFolderInfo *folderInfo);
0176     void entrySelected(MenuEntryInfo *entryInfo);
0177     void disableAction();
0178 
0179 protected Q_SLOTS:
0180     void itemSelected(QTreeWidgetItem *);
0181     bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override;
0182 
0183     void newsubmenu();
0184     void newitem();
0185     void newsep();
0186 
0187     void cut();
0188     void copy();
0189     void paste();
0190     void del();
0191     void sort(const int sortCmd);
0192     void moveUpItem();
0193     void moveDownItem();
0194 
0195 protected:
0196     enum SortType {
0197         SortByName = 0,
0198         SortByDescription,
0199         SortAllByName,
0200         SortAllByDescription,
0201     };
0202 
0203     void contextMenuEvent(QContextMenuEvent *event) override;
0204     void dropEvent(QDropEvent *event) override;
0205     void startDrag(Qt::DropActions supportedActions) override;
0206     QTreeWidgetItem *selectedItem();
0207     TreeItem *createTreeItem(TreeItem *parent, QTreeWidgetItem *after, MenuFolderInfo *folderInfo, bool _init = false);
0208     TreeItem *createTreeItem(TreeItem *parent, QTreeWidgetItem *after, MenuEntryInfo *entryInfo, bool _init = false);
0209     TreeItem *createTreeItem(TreeItem *parent, QTreeWidgetItem *after, MenuSeparatorInfo *sepInfo, bool _init = false);
0210 
0211     void del(TreeItem *, bool deleteInfo);
0212     void fill();
0213     void fillBranch(MenuFolderInfo *folderInfo, TreeItem *parent);
0214     QString findName(KDesktopFile *df, bool deleted);
0215     void sortItem(TreeItem *item, SortType sortType);
0216     void sortItemChildren(const QList<QTreeWidgetItem *>::iterator &begin, const QList<QTreeWidgetItem *>::iterator &end, SortType sortType);
0217     TreeItem *getParentItem(QTreeWidgetItem *item) const;
0218     void moveUpOrDownItem(bool isMovingUpAction);
0219 
0220     TreeItem *expandPath(TreeItem *item, const QString &path);
0221 
0222     // moving = src will be removed later
0223     void copy(bool moving);
0224 
0225     void cleanupClipboard();
0226 
0227     bool isLayoutDirty();
0228     void setLayoutDirty(TreeItem *);
0229     void saveLayout();
0230 
0231     QStringList mimeTypes() const override;
0232 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0233     QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
0234 #else
0235     QMimeData *mimeData(const QList<QTreeWidgetItem *> &items) const override;
0236 #endif
0237     Qt::DropActions supportedDropActions() const override;
0238 
0239     void sendReloadMenu();
0240 
0241 private:
0242     KActionCollection *m_ac = nullptr;
0243     QMenu *m_popupMenu = nullptr;
0244     int m_clipboard;
0245     MenuFolderInfo *m_clipboardFolderInfo = nullptr;
0246     MenuEntryInfo *m_clipboardEntryInfo = nullptr;
0247     bool m_showHidden;
0248     MenuFile *m_menuFile = nullptr;
0249     MenuFolderInfo *m_rootFolder = nullptr;
0250     MenuSeparatorInfo *m_separator = nullptr;
0251     QStringList m_newMenuIds;
0252     QStringList m_newDirectoryList;
0253     bool m_layoutDirty;
0254     bool m_detailedMenuEntries;
0255     bool m_detailedEntriesNamesFirst;
0256     QStringList m_dropMimeTypes;
0257 };
0258 
0259 class MenuItemMimeData : public QMimeData
0260 {
0261     Q_OBJECT
0262 public:
0263     explicit MenuItemMimeData(TreeItem *item);
0264     QStringList formats() const override;
0265     bool hasFormat(const QString &mimeType) const override;
0266     TreeItem *item() const;
0267 
0268 protected:
0269 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
0270     QVariant retrieveData(const QString &mimeType, QVariant::Type type) const override;
0271 #else
0272     QVariant retrieveData(const QString &mimeType, QMetaType type) const override;
0273 #endif
0274 private:
0275     TreeItem *m_item = nullptr;
0276 };
0277 
0278 Q_DECLARE_METATYPE(TreeItem *)
0279 
0280 #endif