MissingFilesPathItemDelegate.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /******************************************************************************
  2. Copyright (C) 2019 by Dillon Pentz <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include "MissingFilesPathItemDelegate.hpp"
  15. #include <OBSApp.hpp>
  16. #include <QFileDialog>
  17. #include <QHBoxLayout>
  18. #include <QLineEdit>
  19. #include <QToolButton>
  20. #include "moc_MissingFilesPathItemDelegate.cpp"
  21. enum MissingFilesRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole };
  22. MissingFilesPathItemDelegate::MissingFilesPathItemDelegate() : QStyledItemDelegate() {}
  23. QWidget *MissingFilesPathItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & /* option */,
  24. const QModelIndex &) const
  25. {
  26. QSizePolicy buttonSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding,
  27. QSizePolicy::ControlType::PushButton);
  28. QWidget *container = new QWidget(parent);
  29. auto browseCallback = [this, container]() {
  30. const_cast<MissingFilesPathItemDelegate *>(this)->handleBrowse(container);
  31. };
  32. auto clearCallback = [this, container]() {
  33. const_cast<MissingFilesPathItemDelegate *>(this)->handleClear(container);
  34. };
  35. QHBoxLayout *layout = new QHBoxLayout();
  36. layout->setContentsMargins(0, 0, 0, 0);
  37. layout->setSpacing(0);
  38. QLineEdit *text = new QLineEdit();
  39. text->setObjectName(QStringLiteral("text"));
  40. text->setSizePolicy(QSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding,
  41. QSizePolicy::ControlType::LineEdit));
  42. layout->addWidget(text);
  43. QToolButton *browseButton = new QToolButton();
  44. browseButton->setText("...");
  45. browseButton->setSizePolicy(buttonSizePolicy);
  46. layout->addWidget(browseButton);
  47. container->connect(browseButton, &QToolButton::clicked, browseCallback);
  48. QToolButton *clearButton = new QToolButton();
  49. QIcon icon;
  50. icon.addFile(QString::fromUtf8(":/res/images/close.svg"), QSize(), QIcon::Mode::Normal, QIcon::State::Off);
  51. clearButton->setIcon(icon);
  52. clearButton->setProperty("class", "icon-close");
  53. clearButton->setSizePolicy(buttonSizePolicy);
  54. layout->addWidget(clearButton);
  55. container->connect(clearButton, &QToolButton::clicked, clearCallback);
  56. container->setLayout(layout);
  57. container->setFocusProxy(text);
  58. return container;
  59. }
  60. void MissingFilesPathItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
  61. {
  62. QLineEdit *text = editor->findChild<QLineEdit *>();
  63. text->setText(index.data().toString());
  64. editor->setProperty(PATH_LIST_PROP, QVariant());
  65. }
  66. void MissingFilesPathItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
  67. const QModelIndex &index) const
  68. {
  69. // We use the PATH_LIST_PROP property to pass a list of
  70. // path strings from the editor widget into the model's
  71. // NewPathsToProcessRole. This is only used when paths
  72. // are selected through the "browse" or "delete" buttons
  73. // in the editor. If the user enters new text in the
  74. // text box, we simply pass that text on to the model
  75. // as normal text data in the default role.
  76. QVariant pathListProp = editor->property(PATH_LIST_PROP);
  77. if (pathListProp.isValid()) {
  78. QStringList list = editor->property(PATH_LIST_PROP).toStringList();
  79. model->setData(index, list);
  80. } else {
  81. QLineEdit *lineEdit = editor->findChild<QLineEdit *>();
  82. model->setData(index, lineEdit->text(), 0);
  83. }
  84. }
  85. void MissingFilesPathItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
  86. const QModelIndex &index) const
  87. {
  88. QStyleOptionViewItem localOption = option;
  89. initStyleOption(&localOption, index);
  90. QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &localOption, painter);
  91. }
  92. void MissingFilesPathItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
  93. {
  94. QStyledItemDelegate::initStyleOption(option, index);
  95. option->textElideMode = Qt::ElideMiddle;
  96. }
  97. void MissingFilesPathItemDelegate::handleBrowse(QWidget *container)
  98. {
  99. QLineEdit *text = container->findChild<QLineEdit *>();
  100. QString currentPath = text->text();
  101. if (currentPath.isEmpty() || currentPath.compare(QTStr("MissingFiles.Clear")) == 0)
  102. currentPath = "";
  103. bool isSet = false;
  104. QString newPath =
  105. QFileDialog::getOpenFileName(container, QTStr("MissingFiles.SelectFile"), currentPath, nullptr);
  106. #ifdef __APPLE__
  107. // TODO: Revisit when QTBUG-42661 is fixed
  108. container->window()->raise();
  109. #endif
  110. if (!newPath.isEmpty()) {
  111. container->setProperty(PATH_LIST_PROP, QStringList() << newPath);
  112. isSet = true;
  113. }
  114. if (isSet)
  115. emit commitData(container);
  116. }
  117. void MissingFilesPathItemDelegate::handleClear(QWidget *container)
  118. {
  119. // An empty string list will indicate that the entry is being
  120. // blanked and should be deleted.
  121. container->setProperty(PATH_LIST_PROP, QStringList() << QTStr("MissingFiles.Clear"));
  122. container->findChild<QLineEdit *>()->clearFocus();
  123. ((QWidget *)container->parent())->setFocus();
  124. emit commitData(container);
  125. }