Переглянути джерело

UI: Add obs-frontend-api functions to create/delete profiles

SCG82 4 роки тому
батько
коміт
88cc691afa

+ 18 - 0
UI/api-interface.cpp

@@ -266,6 +266,24 @@ struct OBSStudioAPI : obs_frontend_callbacks {
 		}
 	}
 
+	void obs_frontend_create_profile(const char *name) override
+	{
+		QMetaObject::invokeMethod(main, "NewProfile",
+					  Q_ARG(QString, name));
+	}
+
+	void obs_frontend_duplicate_profile(const char *name) override
+	{
+		QMetaObject::invokeMethod(main, "DuplicateProfile",
+					  Q_ARG(QString, name));
+	}
+
+	void obs_frontend_delete_profile(const char *profile) override
+	{
+		QMetaObject::invokeMethod(main, "DeleteProfile",
+					  Q_ARG(QString, profile));
+	}
+
 	void obs_frontend_streaming_start(void) override
 	{
 		QMetaObject::invokeMethod(main, "StartStreaming");

+ 18 - 0
UI/obs-frontend-api/obs-frontend-api.cpp

@@ -216,6 +216,24 @@ void obs_frontend_set_current_profile(const char *profile)
 		c->obs_frontend_set_current_profile(profile);
 }
 
+void obs_frontend_create_profile(const char *name)
+{
+	if (callbacks_valid())
+		c->obs_frontend_create_profile(name);
+}
+
+void obs_frontend_duplicate_profile(const char *name)
+{
+	if (callbacks_valid())
+		c->obs_frontend_duplicate_profile(name);
+}
+
+void obs_frontend_delete_profile(const char *profile)
+{
+	if (callbacks_valid())
+		c->obs_frontend_delete_profile(profile);
+}
+
 void obs_frontend_streaming_start(void)
 {
 	if (callbacks_valid())

+ 3 - 0
UI/obs-frontend-api/obs-frontend-api.h

@@ -119,6 +119,9 @@ EXPORT char **obs_frontend_get_profiles(void);
 EXPORT char *obs_frontend_get_current_profile(void);
 EXPORT char *obs_frontend_get_current_profile_path(void);
 EXPORT void obs_frontend_set_current_profile(const char *profile);
+EXPORT void obs_frontend_create_profile(const char *name);
+EXPORT void obs_frontend_duplicate_profile(const char *name);
+EXPORT void obs_frontend_delete_profile(const char *profile);
 
 typedef void (*obs_frontend_cb)(void *private_data);
 

+ 3 - 0
UI/obs-frontend-api/obs-frontend-internal.hpp

@@ -39,6 +39,9 @@ struct obs_frontend_callbacks {
 	virtual char *obs_frontend_get_current_profile(void) = 0;
 	virtual char *obs_frontend_get_current_profile_path(void) = 0;
 	virtual void obs_frontend_set_current_profile(const char *profile) = 0;
+	virtual void obs_frontend_create_profile(const char *name) = 0;
+	virtual void obs_frontend_duplicate_profile(const char *name) = 0;
+	virtual void obs_frontend_delete_profile(const char *profile) = 0;
 
 	virtual void obs_frontend_streaming_start(void) = 0;
 	virtual void obs_frontend_streaming_stop(void) = 0;

+ 96 - 27
UI/window-basic-main-profiles.cpp

@@ -77,12 +77,13 @@ void EnumProfiles(std::function<bool(const char *, const char *)> &&cb)
 	os_globfree(glob);
 }
 
-static bool ProfileExists(const char *findName)
+static bool GetProfileDir(const char *findName, const char *&profileDir)
 {
 	bool found = false;
-	auto func = [&](const char *name, const char *) {
+	auto func = [&](const char *name, const char *path) {
 		if (strcmp(name, findName) == 0) {
 			found = true;
+			profileDir = strrchr(path, '/') + 1;
 			return false;
 		}
 		return true;
@@ -92,14 +93,17 @@ static bool ProfileExists(const char *findName)
 	return found;
 }
 
-static bool GetProfileName(QWidget *parent, std::string &name,
-			   std::string &file, const char *title,
-			   const char *text, const bool showWizard,
-			   bool &wizardChecked, const char *oldName = nullptr)
+static bool ProfileExists(const char *findName)
 {
-	char path[512];
-	int ret;
+	const char *profileDir = nullptr;
+	return GetProfileDir(findName, profileDir);
+}
 
+static bool AskForProfileName(QWidget *parent, std::string &name,
+			      const char *title, const char *text,
+			      const bool showWizard, bool &wizardChecked,
+			      const char *oldName = nullptr)
+{
 	for (;;) {
 		bool success = false;
 
@@ -130,10 +134,23 @@ static bool GetProfileName(QWidget *parent, std::string &name,
 		}
 		break;
 	}
+	return true;
+}
+
+static bool FindSafeProfileDirName(const std::string &profileName,
+				   std::string &dirName)
+{
+	char path[512];
+	int ret;
+
+	if (ProfileExists(profileName.c_str())) {
+		blog(LOG_WARNING, "Profile '%s' exists", profileName.c_str());
+		return false;
+	}
 
-	if (!GetFileSafeName(name.c_str(), file)) {
+	if (!GetFileSafeName(profileName.c_str(), dirName)) {
 		blog(LOG_WARNING, "Failed to create safe file name for '%s'",
-		     name.c_str());
+		     profileName.c_str());
 		return false;
 	}
 
@@ -143,15 +160,15 @@ static bool GetProfileName(QWidget *parent, std::string &name,
 		return false;
 	}
 
-	file.insert(0, path);
+	dirName.insert(0, path);
 
-	if (!GetClosestUnusedFileName(file, nullptr)) {
+	if (!GetClosestUnusedFileName(dirName, nullptr)) {
 		blog(LOG_WARNING, "Failed to get closest file name for %s",
-		     file.c_str());
+		     dirName.c_str());
 		return false;
 	}
 
-	file.erase(0, ret);
+	dirName.erase(0, ret);
 	return true;
 }
 
@@ -200,16 +217,26 @@ static bool CopyProfile(const char *fromPartial, const char *to)
 bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
 			  const char *init_text, bool rename)
 {
-	std::string newName;
-	std::string newDir;
-	std::string newPath;
-	ConfigFile config;
+	std::string name;
 
 	bool showWizardChecked = config_get_bool(App()->GlobalConfig(), "Basic",
 						 "ConfigOnNewProfile");
 
-	if (!GetProfileName(this, newName, newDir, title, text, create_new,
-			    showWizardChecked, init_text))
+	if (!AskForProfileName(this, name, title, text, create_new,
+			       showWizardChecked, init_text))
+		return false;
+
+	return CreateProfile(name, create_new, showWizardChecked, rename);
+}
+
+bool OBSBasic::CreateProfile(const std::string &newName, bool create_new,
+			     bool showWizardChecked, bool rename)
+{
+	std::string newDir;
+	std::string newPath;
+	ConfigFile config;
+
+	if (!FindSafeProfileDirName(newName, newDir))
 		return false;
 
 	if (create_new) {
@@ -295,6 +322,16 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
 	return true;
 }
 
+bool OBSBasic::NewProfile(const QString &name)
+{
+	return CreateProfile(name.toStdString(), true, false, false);
+}
+
+bool OBSBasic::DuplicateProfile(const QString &name)
+{
+	return CreateProfile(name.toStdString(), false, false, false);
+}
+
 void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
 {
 	char profilePath[512];
@@ -345,6 +382,36 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
 	blog(LOG_INFO, "------------------------------------------------");
 }
 
+void OBSBasic::DeleteProfile(const QString &profileName)
+{
+	std::string name = profileName.toStdString();
+	const char *curName =
+		config_get_string(App()->GlobalConfig(), "Basic", "Profile");
+
+	if (strcmp(curName, name.c_str()) == 0) {
+		on_actionRemoveProfile_triggered(true);
+		return;
+	}
+
+	const char *profileDir = nullptr;
+	if (!GetProfileDir(name.c_str(), profileDir)) {
+		blog(LOG_WARNING, "Profile '%s' not found", name.c_str());
+		return;
+	}
+
+	if (!profileDir) {
+		blog(LOG_WARNING, "Failed to get profile dir for profile '%s'",
+		     name.c_str());
+		return;
+	}
+
+	DeleteProfile(name.c_str(), profileDir);
+	RefreshProfiles();
+	config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
+	if (api)
+		api->on_event(OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED);
+}
+
 void OBSBasic::RefreshProfiles()
 {
 	QList<QAction *> menuActions = ui->profileMenu->actions();
@@ -435,7 +502,7 @@ void OBSBasic::on_actionRenameProfile_triggered()
 	}
 }
 
-void OBSBasic::on_actionRemoveProfile_triggered()
+void OBSBasic::on_actionRemoveProfile_triggered(bool skipConfirmation)
 {
 	std::string newName;
 	std::string newPath;
@@ -462,13 +529,15 @@ void OBSBasic::on_actionRemoveProfile_triggered()
 	if (newPath.empty())
 		return;
 
-	QString text = QTStr("ConfirmRemove.Text");
-	text.replace("$1", QT_UTF8(oldName.c_str()));
+	if (!skipConfirmation) {
+		QString text = QTStr("ConfirmRemove.Text");
+		text.replace("$1", QT_UTF8(oldName.c_str()));
 
-	QMessageBox::StandardButton button = OBSMessageBox::question(
-		this, QTStr("ConfirmRemove.Title"), text);
-	if (button == QMessageBox::No)
-		return;
+		QMessageBox::StandardButton button = OBSMessageBox::question(
+			this, QTStr("ConfirmRemove.Title"), text);
+		if (button == QMessageBox::No)
+			return;
+	}
 
 	size_t newPath_len = newPath.size();
 	newPath += "/basic.ini";

+ 7 - 1
UI/window-basic-main.hpp

@@ -380,6 +380,8 @@ private:
 	void ResetProfileData();
 	bool AddProfile(bool create_new, const char *title, const char *text,
 			const char *init_text = nullptr, bool rename = false);
+	bool CreateProfile(const std::string &newName, bool create_new,
+			   bool showWizardChecked, bool rename = false);
 	void DeleteProfile(const char *profile_name, const char *profile_dir);
 	void RefreshProfiles();
 	void ChangeProfile();
@@ -609,6 +611,10 @@ public slots:
 	bool AddSceneCollection(bool create_new,
 				const QString &name = QString());
 
+	bool NewProfile(const QString &name);
+	bool DuplicateProfile(const QString &name);
+	void DeleteProfile(const QString &profileName);
+
 	void UpdatePatronJson(const QString &text, const QString &error);
 
 	void ShowContextBar();
@@ -973,7 +979,7 @@ private slots:
 	void on_actionNewProfile_triggered();
 	void on_actionDupProfile_triggered();
 	void on_actionRenameProfile_triggered();
-	void on_actionRemoveProfile_triggered();
+	void on_actionRemoveProfile_triggered(bool skipConfirmation = false);
 	void on_actionImportProfile_triggered();
 	void on_actionExportProfile_triggered();
 

+ 18 - 0
docs/sphinx/reference-frontend-api.rst

@@ -327,6 +327,24 @@ Functions
 
 ---------------------------------------
 
+.. function:: bool obs_frontend_create_profile(const char *name)
+
+   :param name: Name of the new profile to create (must be unique).
+
+---------------------------------------
+
+.. function:: bool obs_frontend_duplicate_profile(const char *name)
+
+   :param name: Name of the duplicate profile to create (must be unique).
+
+---------------------------------------
+
+.. function:: void obs_frontend_delete_profile(const char *profile)
+
+   :param profile: Name of the profile to delete.
+
+---------------------------------------
+
 .. function:: void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data)
 
    Adds a callback that will be called when a frontend event occurs.