|
|
@@ -732,12 +732,18 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
|
|
|
popup.addMenu(addMenu);
|
|
|
|
|
|
if (item) {
|
|
|
+ const char *dulpicateSlot =
|
|
|
+ async ? SLOT(DuplicateAsyncFilter())
|
|
|
+ : SLOT(DuplicateEffectFilter());
|
|
|
+
|
|
|
const char *renameSlot = async ? SLOT(RenameAsyncFilter())
|
|
|
: SLOT(RenameEffectFilter());
|
|
|
const char *removeSlot =
|
|
|
async ? SLOT(on_removeAsyncFilter_clicked())
|
|
|
: SLOT(on_removeEffectFilter_clicked());
|
|
|
|
|
|
+ popup.addSeparator();
|
|
|
+ popup.addAction(QTStr("Duplicate"), this, dulpicateSlot);
|
|
|
popup.addSeparator();
|
|
|
popup.addAction(QTStr("Rename"), this, renameSlot);
|
|
|
popup.addAction(QTStr("Remove"), this, removeSlot);
|
|
|
@@ -781,6 +787,58 @@ void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async)
|
|
|
editActive = true;
|
|
|
}
|
|
|
|
|
|
+void OBSBasicFilters::DuplicateItem(QListWidgetItem *item)
|
|
|
+{
|
|
|
+ OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
|
|
|
+ string name = obs_source_get_name(filter);
|
|
|
+ obs_source_t *existing_filter;
|
|
|
+
|
|
|
+ QString placeholder = QString::fromStdString(name);
|
|
|
+ QString text{placeholder};
|
|
|
+ int i = 2;
|
|
|
+ while ((existing_filter = obs_source_get_filter_by_name(
|
|
|
+ source, QT_TO_UTF8(text)))) {
|
|
|
+ obs_source_release(existing_filter);
|
|
|
+ text = QString("%1 %2").arg(placeholder).arg(i++);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool success = NameDialog::AskForName(
|
|
|
+ this, QTStr("Basic.Filters.AddFilter.Title"),
|
|
|
+ QTStr("Basic.Filters.AddFilter.Text"), name, text);
|
|
|
+ if (!success)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (name.empty()) {
|
|
|
+ OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"),
|
|
|
+ QTStr("NoNameEntered.Text"));
|
|
|
+ DuplicateItem(item);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ existing_filter = obs_source_get_filter_by_name(source, name.c_str());
|
|
|
+ if (existing_filter) {
|
|
|
+ OBSMessageBox::warning(this, QTStr("NameExists.Title"),
|
|
|
+ QTStr("NameExists.Text"));
|
|
|
+ obs_source_release(existing_filter);
|
|
|
+ DuplicateItem(item);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ bool enabled = obs_source_enabled(filter);
|
|
|
+ obs_source_t *new_filter =
|
|
|
+ obs_source_duplicate(filter, name.c_str(), false);
|
|
|
+ if (new_filter) {
|
|
|
+ const char *sourceName = obs_source_get_name(source);
|
|
|
+ const char *id = obs_source_get_id(new_filter);
|
|
|
+ blog(LOG_INFO,
|
|
|
+ "User duplicated filter '%s' (%s) from '%s' "
|
|
|
+ "to source '%s'",
|
|
|
+ name.c_str(), id, name.c_str(), sourceName);
|
|
|
+ obs_source_set_enabled(new_filter, enabled);
|
|
|
+ obs_source_filter_add(source, new_filter);
|
|
|
+ obs_source_release(new_filter);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasicFilters::on_asyncFilters_customContextMenuRequested(
|
|
|
const QPoint &pos)
|
|
|
{
|
|
|
@@ -803,6 +861,16 @@ void OBSBasicFilters::RenameEffectFilter()
|
|
|
EditItem(ui->effectFilters->currentItem(), false);
|
|
|
}
|
|
|
|
|
|
+void OBSBasicFilters::DuplicateAsyncFilter()
|
|
|
+{
|
|
|
+ DuplicateItem(ui->asyncFilters->currentItem());
|
|
|
+}
|
|
|
+
|
|
|
+void OBSBasicFilters::DuplicateEffectFilter()
|
|
|
+{
|
|
|
+ DuplicateItem(ui->effectFilters->currentItem());
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
|
|
|
{
|
|
|
QListWidgetItem *listItem = list->currentItem();
|