UI: Add copying/pasting of sources/filters
Closes jp9000/obs-studio#860
This commit is contained in:
parent
1ef7a48e9c
commit
bcd491a3d6
@ -61,6 +61,14 @@ Deprecated="Deprecated"
|
||||
ReplayBuffer="Replay Buffer"
|
||||
Import="Import"
|
||||
Export="Export"
|
||||
Copy="Copy"
|
||||
Paste="Paste"
|
||||
PasteReference="Paste (Reference)"
|
||||
PasteDuplicate="Paste (Duplicate)"
|
||||
|
||||
# copy filters
|
||||
Copy.Filters="Copy Filters"
|
||||
Paste.Filters="Paste Filters"
|
||||
|
||||
# updater
|
||||
Updater.Title="New update available"
|
||||
|
@ -892,6 +892,51 @@
|
||||
<addaction name="actionScaleCanvas"/>
|
||||
<addaction name="actionScaleOutput"/>
|
||||
</widget>
|
||||
<action name="actionCopySource">
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPasteRef">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PasteReference</string>
|
||||
</property>
|
||||
<property name="iconText">
|
||||
<string>PasteReference</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>PasteReference</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+V</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCopyFilters">
|
||||
<property name="text">
|
||||
<string>Copy.Filters</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPasteFilters">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Paste.Filters</string>
|
||||
</property>
|
||||
</action>
|
||||
<addaction name="actionCopySource"/>
|
||||
<addaction name="actionPasteRef"/>
|
||||
<addaction name="actionPasteDup"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCopyFilters"/>
|
||||
<addaction name="actionPasteFilters"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="transformMenu"/>
|
||||
<addaction name="orderMenu"/>
|
||||
<addaction name="scalingMenu"/>
|
||||
@ -1409,6 +1454,11 @@
|
||||
<string>Basic.MainMenu.Edit.Scale.Output</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPasteDup">
|
||||
<property name="text">
|
||||
<string>PasteDuplicate</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -225,6 +225,8 @@ void OBSBasic::RefreshSceneCollections()
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
main->OpenSavedProjectors();
|
||||
main->ui->actionPasteRef->setEnabled(false);
|
||||
main->ui->actionPasteDup->setEnabled(false);
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionNewSceneCollection_triggered()
|
||||
|
@ -3347,6 +3347,19 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
|
||||
if (addSourceMenu)
|
||||
popup.addMenu(addSourceMenu);
|
||||
|
||||
ui->actionCopyFilters->setEnabled(false);
|
||||
|
||||
popup.addSeparator();
|
||||
popup.addAction(ui->actionCopySource);
|
||||
popup.addAction(ui->actionPasteRef);
|
||||
popup.addAction(ui->actionPasteDup);
|
||||
popup.addSeparator();
|
||||
|
||||
popup.addSeparator();
|
||||
popup.addAction(ui->actionCopyFilters);
|
||||
popup.addAction(ui->actionPasteFilters);
|
||||
popup.addSeparator();
|
||||
|
||||
if (item) {
|
||||
if (addSourceMenu)
|
||||
popup.addSeparator();
|
||||
@ -3393,6 +3406,8 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
|
||||
SLOT(OpenFilters()));
|
||||
popup.addAction(QTStr("Properties"), this,
|
||||
SLOT(on_actionSourceProperties_triggered()));
|
||||
|
||||
ui->actionCopyFilters->setEnabled(true);
|
||||
}
|
||||
|
||||
popup.exec(QCursor::pos());
|
||||
@ -5270,3 +5285,60 @@ bool OBSBasic::sysTrayMinimizeToTray()
|
||||
return config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "SysTrayMinimizeToTray");
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionCopySource_triggered()
|
||||
{
|
||||
on_actionCopyTransform_triggered();
|
||||
|
||||
OBSSceneItem item = GetCurrentSceneItem();
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
OBSSource source = obs_sceneitem_get_source(item);
|
||||
|
||||
copyString = obs_source_get_name(source);
|
||||
copyVisible = obs_sceneitem_visible(item);
|
||||
|
||||
ui->actionPasteRef->setEnabled(true);
|
||||
ui->actionPasteDup->setEnabled(true);
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionPasteRef_triggered()
|
||||
{
|
||||
OBSBasicSourceSelect::SourcePaste(copyString, copyVisible, false);
|
||||
on_actionPasteTransform_triggered();
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionPasteDup_triggered()
|
||||
{
|
||||
OBSBasicSourceSelect::SourcePaste(copyString, copyVisible, true);
|
||||
on_actionPasteTransform_triggered();
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionCopyFilters_triggered()
|
||||
{
|
||||
OBSSceneItem item = GetCurrentSceneItem();
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
OBSSource source = obs_sceneitem_get_source(item);
|
||||
|
||||
copyFiltersString = obs_source_get_name(source);
|
||||
|
||||
ui->actionPasteFilters->setEnabled(true);
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionPasteFilters_triggered()
|
||||
{
|
||||
OBSSource source = obs_get_source_by_name(copyFiltersString);
|
||||
OBSSceneItem sceneItem = GetCurrentSceneItem();
|
||||
|
||||
OBSSource dstSource = obs_sceneitem_get_source(sceneItem);
|
||||
|
||||
if (source == dstSource)
|
||||
return;
|
||||
|
||||
obs_source_copy_filters(dstSource, source);
|
||||
}
|
||||
|
@ -119,6 +119,10 @@ private:
|
||||
bool projectChanged = false;
|
||||
bool previewEnabled = true;
|
||||
|
||||
const char *copyString;
|
||||
const char *copyFiltersString;
|
||||
bool copyVisible = true;
|
||||
|
||||
QPointer<QThread> updateCheckThread;
|
||||
QPointer<QThread> logUploadThread;
|
||||
|
||||
@ -413,6 +417,13 @@ private slots:
|
||||
|
||||
void ToggleShowHide();
|
||||
|
||||
void on_actionCopySource_triggered();
|
||||
void on_actionPasteRef_triggered();
|
||||
void on_actionPasteDup_triggered();
|
||||
|
||||
void on_actionCopyFilters_triggered();
|
||||
void on_actionPasteFilters_triggered();
|
||||
|
||||
private:
|
||||
/* OBS Callbacks */
|
||||
static void SceneReordered(void *data, calldata_t *params);
|
||||
|
@ -93,7 +93,28 @@ static void AddSource(void *_data, obs_scene_t *scene)
|
||||
obs_sceneitem_set_visible(sceneitem, data->visible);
|
||||
}
|
||||
|
||||
static void AddExisting(const char *name, const bool visible)
|
||||
static char *get_new_source_name(const char *name)
|
||||
{
|
||||
struct dstr new_name = {0};
|
||||
int inc = 0;
|
||||
|
||||
dstr_copy(&new_name, name);
|
||||
|
||||
for (;;) {
|
||||
obs_source_t *existing_source = obs_get_source_by_name(
|
||||
new_name.array);
|
||||
if (!existing_source)
|
||||
break;
|
||||
|
||||
obs_source_release(existing_source);
|
||||
|
||||
dstr_printf(&new_name, "%s %d", name, ++inc + 1);
|
||||
}
|
||||
|
||||
return new_name.array;
|
||||
}
|
||||
|
||||
static void AddExisting(const char *name, bool visible, bool duplicate)
|
||||
{
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
OBSScene scene = main->GetCurrentScene();
|
||||
@ -102,6 +123,17 @@ static void AddExisting(const char *name, const bool visible)
|
||||
|
||||
obs_source_t *source = obs_get_source_by_name(name);
|
||||
if (source) {
|
||||
if (duplicate) {
|
||||
obs_source_t *from = source;
|
||||
char *new_name = get_new_source_name(name);
|
||||
source = obs_source_duplicate(from, new_name, false);
|
||||
bfree(new_name);
|
||||
obs_source_release(from);
|
||||
|
||||
if (!source)
|
||||
return;
|
||||
}
|
||||
|
||||
AddSourceData data;
|
||||
data.source = source;
|
||||
data.visible = visible;
|
||||
@ -155,7 +187,7 @@ void OBSBasicSourceSelect::on_buttonBox_accepted()
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
AddExisting(QT_TO_UTF8(item->text()), visible);
|
||||
AddExisting(QT_TO_UTF8(item->text()), visible, false);
|
||||
} else {
|
||||
if (ui->sourceName->text().isEmpty()) {
|
||||
QMessageBox::information(this,
|
||||
@ -243,3 +275,8 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
|
||||
obs_enum_sources(EnumSources, this);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasicSourceSelect::SourcePaste(const char *name, bool visible, bool dup)
|
||||
{
|
||||
AddExisting(name, visible, dup);
|
||||
}
|
||||
|
@ -47,4 +47,6 @@ public:
|
||||
OBSBasicSourceSelect(OBSBasic *parent, const char *id);
|
||||
|
||||
OBSSource newSource;
|
||||
|
||||
static void SourcePaste(const char *name, bool visible, bool duplicate);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user