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 };