File indexing completed on 2024-04-21 04:51:44

0001 /*
0002     SPDX-FileCopyrightText: 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003     This file is part of Kdenlive. See www.kdenlive.org.
0004 
0005     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #pragma once
0009 
0010 #include "definitions.h"
0011 
0012 #include <QApplication>
0013 #include <QDir>
0014 #include <QMutex>
0015 #include <QPainter>
0016 #include <QStyledItemDelegate>
0017 #include <QTimer>
0018 #include <QTreeWidget>
0019 
0020 #include <KCoreDirLister>
0021 #include <KFileItem>
0022 #include <KIO/ListJob>
0023 #include <KIO/PreviewJob>
0024 #include <KMessageWidget>
0025 
0026 class ProjectManager;
0027 class KJob;
0028 class QProgressBar;
0029 class QToolBar;
0030 
0031 /**
0032  * @class BinItemDelegate
0033  * @brief This class is responsible for drawing items in the QTreeView.
0034  */
0035 class LibraryItemDelegate : public QStyledItemDelegate
0036 {
0037 public:
0038     explicit LibraryItemDelegate(QObject *parent = nullptr)
0039         : QStyledItemDelegate(parent)
0040     {
0041     }
0042 
0043     void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
0044     {
0045         QStyleOptionViewItem opt = option;
0046         initStyleOption(&opt, index);
0047         QRect r1 = option.rect;
0048         QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0049         const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
0050         int decoWidth = int(2 * textMargin + r1.height() * 1.8);
0051         int mid = r1.height() / 2;
0052         r1.adjust(decoWidth, 0, 0, -mid);
0053         QFont ft = option.font;
0054         ft.setBold(true);
0055         QFontMetricsF fm(ft);
0056         QRect r2 = fm.boundingRect(r1, Qt::AlignLeft | Qt::AlignTop, index.data(Qt::DisplayRole).toString()).toRect();
0057         editor->setGeometry(r2);
0058     }
0059 
0060     QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
0061     {
0062         QSize hint = QStyledItemDelegate::sizeHint(option, index);
0063         QString text = index.data(Qt::UserRole + 1).toString();
0064         QRectF r = option.rect;
0065         QFont ft = option.font;
0066         ft.setBold(true);
0067         QFontMetricsF fm(ft);
0068         QStyle *style = option.widget ? option.widget->style() : QApplication::style();
0069         const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
0070         int width = int(fm.boundingRect(r, Qt::AlignLeft | Qt::AlignTop, text).width() + option.decorationSize.width() + 2 * textMargin);
0071         hint.setWidth(width);
0072         return {hint.width(), qMax(option.fontMetrics.lineSpacing() * 2 + 4, qMax(hint.height(), option.decorationSize.height()))};
0073     }
0074 
0075     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
0076     {
0077         if (index.column() == 0) {
0078             QRect r1 = option.rect;
0079             painter->save();
0080             painter->setClipRect(r1);
0081             QStyleOptionViewItem opt(option);
0082             initStyleOption(&opt, index);
0083             QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0084             const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
0085             // QRect r = QStyle::alignedRect(opt.direction, Qt::AlignVCenter | Qt::AlignLeft, opt.decorationSize, r1);
0086 
0087             style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
0088             if (option.state & QStyle::State_Selected) {
0089                 painter->setPen(option.palette.highlightedText().color());
0090             } else {
0091                 painter->setPen(option.palette.text().color());
0092             }
0093             QRect r = r1;
0094             QFont font = painter->font();
0095             font.setBold(true);
0096             painter->setFont(font);
0097             int decoWidth = int(2 * textMargin + r1.height() * 1.8);
0098             r.setWidth(int(r1.height() * 1.8));
0099             // Draw thumbnail
0100             opt.icon.paint(painter, r);
0101             int mid = r1.height() / 2;
0102             r1.adjust(decoWidth, 0, 0, -mid);
0103             QRect r2 = option.rect;
0104             r2.adjust(decoWidth, mid, 0, 0);
0105             QRectF bounding;
0106             painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(Qt::DisplayRole).toString(), &bounding);
0107             font.setBold(false);
0108             painter->setFont(font);
0109             QString subText = index.data(Qt::UserRole + 1).toString();
0110             r2.adjust(0, int(bounding.bottom() - r2.top()), 0, 0);
0111             QColor subTextColor = painter->pen().color();
0112             subTextColor.setAlphaF(.5);
0113             painter->setPen(subTextColor);
0114             painter->drawText(r2, Qt::AlignLeft | Qt::AlignTop, subText, &bounding);
0115             painter->restore();
0116         } else {
0117             QStyledItemDelegate::paint(painter, option, index);
0118         }
0119     }
0120 };
0121 
0122 /** @class LibraryTree
0123     @brief \@todo Describe class LibraryTree
0124     @todo Describe class LibraryTree
0125  */
0126 class LibraryTree : public QTreeWidget
0127 {
0128     Q_OBJECT
0129 public:
0130     explicit LibraryTree(QWidget *parent = nullptr);
0131 
0132 protected:
0133     QStringList mimeTypes() const override;
0134 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0135     QMimeData *mimeData(const QList<QTreeWidgetItem *> list) const override;
0136 #else
0137     QMimeData *mimeData(const QList<QTreeWidgetItem *> &list) const override;
0138 #endif
0139     void dropEvent(QDropEvent *event) override;
0140     void mousePressEvent(QMouseEvent *event) override;
0141 
0142 public Q_SLOTS:
0143     void slotUpdateThumb(const QString &path, const QString &iconPath);
0144     void slotUpdateThumb(const QString &path, const QPixmap &pix);
0145 
0146 Q_SIGNALS:
0147     void moveData(const QList<QUrl> &, const QString &);
0148     void importSequence(const QStringList &, const QString &);
0149 };
0150 
0151 /** @class LibraryWidget
0152     @brief A "library" that contains a list of clips to be used across projects
0153     @author Jean-Baptiste Mardelle
0154  */
0155 class LibraryWidget : public QWidget
0156 {
0157     Q_OBJECT
0158 
0159 public:
0160     explicit LibraryWidget(ProjectManager *m_manager, QWidget *parent = nullptr);
0161     void setupActions();
0162 
0163 public Q_SLOTS:
0164     void slotAddToLibrary();
0165     void slotUpdateLibraryPath();
0166 
0167 private Q_SLOTS:
0168     void slotAddToProject();
0169     void slotDeleteFromLibrary();
0170     void updateActions();
0171     void slotAddFolder();
0172     void slotOpenFolder();
0173     void slotRenameItem();
0174     void slotMoveData(const QList<QUrl> &, QString);
0175     void slotSaveSequence(const QStringList &info, QString dest);
0176     void slotItemEdited(QTreeWidgetItem *item, int column);
0177     void slotDownloadFinished(KJob *);
0178     void slotDownloadProgress(KJob *, int);
0179     void slotGotPreview(const KFileItem &item, const QPixmap &pix);
0180     void slotItemsAdded(const QUrl &url, const KFileItemList &list);
0181     void slotItemsDeleted(const KFileItemList &list);
0182     void slotClearAll();
0183 
0184 private:
0185     LibraryTree *m_libraryTree;
0186     QToolBar *m_toolBar;
0187     QProgressBar *m_progressBar;
0188     QAction *m_addAction;
0189     QAction *m_deleteAction;
0190     QTimer m_timer;
0191     KMessageWidget *m_infoWidget;
0192     ProjectManager *m_manager;
0193     QList<QTreeWidgetItem *> m_folders;
0194     KIO::PreviewJob *m_previewJob;
0195     KCoreDirLister *m_coreLister;
0196     QMutex m_treeMutex;
0197     QDir m_directory;
0198     /** @brief if true, the next file appearing in the library will be selected */
0199     bool m_selectNewFile;
0200     void showMessage(const QString &text, KMessageWidget::MessageType type = KMessageWidget::Warning);
0201 
0202 Q_SIGNALS:
0203     void addProjectClips(const QList<QUrl> &);
0204     void thumbReady(const QString &, const QString &);
0205     void enableAddSelection(bool);
0206     void saveTimelineSelection(QDir);
0207 };