void OBSBasicStatusBar::UpdateDelayMsg()
{
	QString msg;

	if (delaySecTotal) {
		if (delaySecStarting && !delaySecStopping) {
			msg = QTStr("Basic.StatusBar.DelayStartingIn");
			msg = msg.arg(QString::number(delaySecStarting));

		} else if (!delaySecStarting && delaySecStopping) {
			msg = QTStr("Basic.StatusBar.DelayStoppingIn");
			msg = msg.arg(QString::number(delaySecStopping));

		} else if (delaySecStarting && delaySecStopping) {
			msg = QTStr("Basic.StatusBar.DelayStartingStoppingIn");
			msg = msg.arg(QString::number(delaySecStopping),
					QString::number(delaySecStarting));
		} else {
			msg = QTStr("Basic.StatusBar.Delay");
			msg = msg.arg(QString::number(delaySecTotal));
		}
	}

	delayInfo->setText(msg);
}
void OBSBasicSourceSelect::on_buttonBox_accepted()
{
	bool useExisting = ui->selectExisting->isChecked();
	bool visible = ui->sourceVisible->isChecked();

	if (useExisting) {
		QListWidgetItem *item = ui->sourceList->currentItem();
		if (!item)
			return;

		AddExisting(QT_TO_UTF8(item->text()), visible, false);
	} else {
		if (ui->sourceName->text().isEmpty()) {
			OBSMessageBox::warning(this,
					QTStr("NoNameEntered.Title"),
					QTStr("NoNameEntered.Text"));
			return;
		}

		if (!AddNew(this, id, QT_TO_UTF8(ui->sourceName->text()),
					visible, newSource))
			return;
	}

	done(DialogCode::Accepted);
}
void AutoConfigStreamPage::on_disconnectAccount_clicked()
{
	QMessageBox::StandardButton button;

	button = OBSMessageBox::question(this,
			QTStr(DISCONNECT_COMFIRM_TITLE),
			QTStr(DISCONNECT_COMFIRM_TEXT));

	if (button == QMessageBox::No) {
		return;
	}

	OBSBasic *main = OBSBasic::Get();

	main->auth.reset();
	auth.reset();

	std::string service = QT_TO_UTF8(ui->service->currentText());

#ifdef BROWSER_AVAILABLE
	OAuth::DeleteCookies(service);
#endif

	ui->streamKeyWidget->setVisible(true);
	ui->streamKeyLabel->setVisible(true);
	ui->connectAccount2->setVisible(true);
	ui->disconnectAccount->setVisible(false);
	ui->key->setText("");
}
void OBSBasicStatusBar::UpdateSessionTime()
{
	totalSeconds++;

	int seconds      = totalSeconds % 60;
	int totalMinutes = totalSeconds / 60;
	int minutes      = totalMinutes % 60;
	int hours        = totalMinutes / 60;

	QString text;
	text.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
	sessionTime->setText(text);
	sessionTime->setMinimumWidth(sessionTime->width());

	if (reconnectTimeout > 0) {
		QString msg = QTStr("Basic.StatusBar.Reconnecting");
		showMessage(msg.arg(QString::number(retries),
					QString::number(reconnectTimeout)));
		reconnectTimeout--;

	} else if (retries > 0) {
		QString msg = QTStr("Basic.StatusBar.AttemptingReconnect");
		showMessage(msg.arg(QString::number(retries)));
	}
}
void OBSBasic::on_actionRemoveSceneCollection_triggered()
{
	std::string newName;
	std::string newPath;

	std::string oldFile = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollectionFile");
	std::string oldName = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollection");

	auto cb = [&](const char *name, const char *filePath)
	{
		if (strcmp(oldName.c_str(), name) != 0) {
			newName = name;
			newPath = filePath;
			return false;
		}

		return true;
	};

	EnumSceneCollections(cb);

	/* this should never be true due to menu item being grayed out */
	if (newPath.empty())
		return;

	QString text = QTStr("ConfirmRemove.Text");
	text.replace("$1", QT_UTF8(oldName.c_str()));

	QMessageBox::StandardButton button = QMessageBox::question(this,
			QTStr("ConfirmRemove.Title"), text);
	if (button == QMessageBox::No)
		return;

	char path[512];
	int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get scene collection config path");
		return;
	}

	oldFile.insert(0, path);
	oldFile += ".json";
	os_unlink(oldFile.c_str());

	Load(newPath.c_str());
	RefreshSceneCollections();

	const char *newFile = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollectionFile");

	blog(LOG_INFO, "Removed scene collection '%s' (%s.json), "
			"switched to '%s' (%s.json)",
			oldName.c_str(), oldFile.c_str(),
			newName.c_str(), newFile);
	blog(LOG_INFO, "------------------------------------------------");

	UpdateTitleBar();
}
bool AddNew(QWidget *parent, const char *id, const char *name)
{
	obs_source_t source  = obs_get_output_source(0);
	obs_scene_t  scene   = obs_scene_from_source(source);
	bool         success = false;
	if (!source)
		return false;

	source = obs_get_source_by_name(name);
	if (source) {
		QMessageBox::information(parent,
				QTStr("NameExists.Title"),
				QTStr("NameExists.Text"));

	} else {
		source = obs_source_create(OBS_SOURCE_TYPE_INPUT,
				id, name, NULL);

		if (source) {
			obs_add_source(source);
			obs_scene_add(scene, source);

			success = true;
		}
	}

	obs_source_release(source);
	obs_scene_release(scene);

	return success;
}
void AutoConfigStreamPage::UpdateKeyLink()
{
	bool custom = IsCustom();
	QString serviceName = ui->service->currentText();
	bool isYoutube = false;

	if (custom)
		serviceName = "";

	QString text = QTStr("Basic.AutoConfig.StreamPage.StreamKey");
	if (serviceName == "Twitch") {
		text += " <a href=\"https://";
		text += "www.twitch.tv/broadcast/dashboard/streamkey";
		text += "\">";
		text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
		text += "</a>";
	} else if (serviceName == "YouTube / YouTube Gaming") {
		text += " <a href=\"https://";
		text += "www.youtube.com/live_dashboard";
		text += "\">";
		text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
		text += "</a>";

		isYoutube = true;
	}

	if (isYoutube) {
		ui->doBandwidthTest->setChecked(false);
		ui->doBandwidthTest->setEnabled(false);
	} else {
		ui->doBandwidthTest->setEnabled(true);
	}

	ui->streamKeyLabel->setText(text);
}
AutoConfigStartPage::AutoConfigStartPage(QWidget *parent)
	: QWizardPage (parent),
	  ui          (new Ui_AutoConfigStartPage)
{
	ui->setupUi(this);
	setTitle(QTStr("Basic.AutoConfig.StartPage"));
	setSubTitle(QTStr("Basic.AutoConfig.StartPage.SubTitle"));
}
void AutoConfigStreamPage::on_show_clicked()
{
	if (ui->key->echoMode() == QLineEdit::Password) {
		ui->key->setEchoMode(QLineEdit::Normal);
		ui->show->setText(QTStr("Hide"));
	} else {
		ui->key->setEchoMode(QLineEdit::Password);
		ui->show->setText(QTStr("Show"));
	}
}
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
	: QWizardPage (parent),
	  ui          (new Ui_AutoConfigStreamPage)
{
	ui->setupUi(this);
	ui->bitrateLabel->setVisible(false);
	ui->bitrate->setVisible(false);
	ui->connectAccount2->setVisible(false);
	ui->disconnectAccount->setVisible(false);

	int vertSpacing = ui->topLayout->verticalSpacing();

	QMargins m = ui->topLayout->contentsMargins();
	m.setBottom(vertSpacing / 2);
	ui->topLayout->setContentsMargins(m);

	m = ui->loginPageLayout->contentsMargins();
	m.setTop(vertSpacing / 2);
	ui->loginPageLayout->setContentsMargins(m);

	m = ui->streamkeyPageLayout->contentsMargins();
	m.setTop(vertSpacing / 2);
	ui->streamkeyPageLayout->setContentsMargins(m);

	setTitle(QTStr("Basic.AutoConfig.StreamPage"));
	setSubTitle(QTStr("Basic.AutoConfig.StreamPage.SubTitle"));

	LoadServices(false);

	connect(ui->service, SIGNAL(currentIndexChanged(int)),
			this, SLOT(ServiceChanged()));
	connect(ui->customServer, SIGNAL(textChanged(const QString &)),
			this, SLOT(ServiceChanged()));
	connect(ui->doBandwidthTest, SIGNAL(toggled(bool)),
			this, SLOT(ServiceChanged()));

	connect(ui->service, SIGNAL(currentIndexChanged(int)),
			this, SLOT(UpdateServerList()));

	connect(ui->service, SIGNAL(currentIndexChanged(int)),
			this, SLOT(UpdateKeyLink()));

	connect(ui->key, SIGNAL(textChanged(const QString &)),
			this, SLOT(UpdateCompleted()));
	connect(ui->regionUS, SIGNAL(toggled(bool)),
			this, SLOT(UpdateCompleted()));
	connect(ui->regionEU, SIGNAL(toggled(bool)),
			this, SLOT(UpdateCompleted()));
	connect(ui->regionAsia, SIGNAL(toggled(bool)),
			this, SLOT(UpdateCompleted()));
	connect(ui->regionOther, SIGNAL(toggled(bool)),
			this, SLOT(UpdateCompleted()));
}
示例#11
0
void OBSBasic::TBLiveNeedUpdate(std::string ver, std::string msg, std::string download_url)
{
	QString     str = QTStr("TBLiveUpdateAvailable.Text");
	QMessageBox messageBox(this);

	str = str.arg(QT_UTF8(ver.c_str()),	QT_UTF8(download_url.c_str()));

	messageBox.setWindowTitle(QTStr("TBLiveUpdateAvailable"));
	messageBox.setTextFormat(Qt::RichText);
	messageBox.setText(str);
	messageBox.setInformativeText(QT_UTF8(msg.c_str()));
	messageBox.exec();
}
static bool GetProfileName(QWidget *parent, std::string &name,
		std::string &file, const char *title, const char *text,
		const char *oldName = nullptr)
{
	char path[512];
	int ret;

	for (;;) {
		bool success = NameDialog::AskForName(parent, title, text,
				name, QT_UTF8(oldName));
		if (!success) {
			return false;
		}
		if (name.empty()) {
			QMessageBox::information(parent,
					QTStr("NoNameEntered.Title"),
					QTStr("NoNameEntered.Text"));
			continue;
		}
		if (ProfileExists(name.c_str())) {
			QMessageBox::information(parent,
					QTStr("NameExists.Title"),
					QTStr("NameExists.Text"));
			continue;
		}
		break;
	}

	if (!GetFileSafeName(name.c_str(), file)) {
		blog(LOG_WARNING, "Failed to create safe file name for '%s'",
				name.c_str());
		return false;
	}

	ret = GetConfigPath(path, sizeof(path), "obs-studio/basic/profiles/");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get profiles config path");
		return false;
	}

	file.insert(0, path);

	if (!GetClosestUnusedFileName(file, nullptr)) {
		blog(LOG_WARNING, "Failed to get closest file name for %s",
				file.c_str());
		return false;
	}

	file.erase(0, ret);
	return true;
}
示例#13
0
void OBSBasic::on_selectWindow_clicked()
{
	if (!IsAeroEnabled())
	{
		QMessageBox msgBox(this);
		msgBox.setText(QApplication::translate("OBSBasic", "TBLive.Aero.Disabled", 0));
		msgBox.addButton(QTStr("ok"), QMessageBox::AcceptRole);
		msgBox.setIcon(QMessageBox::Information);
		msgBox.setWindowTitle(QTStr("TBLive.MsgTip"));
		msgBox.exec();
	}

	AddSourceWithProperty("window_capture");
}
void AutoConfigStreamPage::LoadServices(bool showAll)
{
	obs_properties_t *props = obs_get_service_properties("rtmp_common");

	OBSData settings = obs_data_create();
	obs_data_release(settings);

	obs_data_set_bool(settings, "show_all", showAll);

	obs_property_t *prop = obs_properties_get(props, "show_all");
	obs_property_modified(prop, settings);

	ui->service->blockSignals(true);
	ui->service->clear();

	QStringList names;

	obs_property_t *services = obs_properties_get(props, "service");
	size_t services_count = obs_property_list_item_count(services);
	for (size_t i = 0; i < services_count; i++) {
		const char *name = obs_property_list_item_string(services, i);
		names.push_back(name);
	}

	if (showAll)
		names.sort();

	for (QString &name : names)
		ui->service->addItem(name);

	if (!showAll) {
		ui->service->addItem(
			QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
			QVariant((int)ListOpt::ShowAll));
	}

	ui->service->insertItem(0,
			QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
			QVariant((int)ListOpt::Custom));

	if (!lastService.isEmpty()) {
		int idx = ui->service->findText(lastService);
		if (idx != -1)
			ui->service->setCurrentIndex(idx);
	}

	obs_properties_destroy(props);

	ui->service->blockSignals(false);
}
示例#15
0
void OBSBasic::on_stopStreamBtn_clicked()
{
	tbliveLog.Log(lss_info, L"on_stopStreamBtn_clicked");

	if (outputHandler->StreamingActive()) {
		QMessageBox::StandardButton button =
			QMessageBox::question(this,
			QTStr("ConfirmStop.Title"),
			QTStr("ConfirmStop.Text"));

		if (button == QMessageBox::No)
			return;

		StopStreaming();
	}
}
void OBSBasicStatusBar::Reconnect()
{
	retries++;

	QString reconnectMsg = QTStr("Basic.StatusBar.Reconnecting");
	showMessage(reconnectMsg.arg(QString::number(retries)));
}
示例#17
0
QMessageBox::StandardButton OBSMessageBox::question(
		QWidget *parent,
		const QString &title,
		const QString &text,
		QMessageBox::StandardButtons buttons,
		QMessageBox::StandardButton defaultButton)
{
	QMessageBox mb(QMessageBox::Question,
			title, text, buttons,
			parent);
	mb.setDefaultButton(defaultButton);
	if (buttons & QMessageBox::Ok) \
		mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
#define translate_button(x) \
	if (buttons & QMessageBox::x) \
		mb.setButtonText(QMessageBox::x, QTStr(#x));
	translate_button(Open);
	translate_button(Save);
	translate_button(Cancel);
	translate_button(Close);
	translate_button(Discard);
	translate_button(Apply);
	translate_button(Reset);
	translate_button(Yes);
	translate_button(No);
	translate_button(No);
	translate_button(Abort);
	translate_button(Retry);
	translate_button(Ignore);
#undef translate_button
	return (QMessageBox::StandardButton)mb.exec();
}
示例#18
0
void OBSProjector::mousePressEvent(QMouseEvent *event)
{
	OBSQTDisplay::mousePressEvent(event);

	if (event->button() == Qt::RightButton) {
		QMenu popup(this);
		popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
		popup.exec(QCursor::pos());
	}

	if (!mouseSwitching)
		return;

	if (event->button() == Qt::LeftButton) {
		int pos = getSourceByPosition(event->x(), event->y(), ratio);
		if (pos < 0 || pos >= (int)numSrcs)
			return;
		OBSSource src = OBSGetStrongRef(multiviewScenes[pos]);
		if (!src)
			return;

		OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window();
		if (main->GetCurrentSceneSource() != src)
			main->SetCurrentScene(src, false);
	}
}
void OBSBasicStatusBar::ReconnectSuccess()
{
	showMessage(QTStr("Basic.StatusBar.ReconnectSuccessful"), 4000);
	retries              = 0;
	bitrateUpdateSeconds = -1;
	lastBytesSent        = 0;
	lastBytesSentTime    = os_gettime_ns();
}
示例#20
0
void DialogResetPassword::sms(){
	QRegExp telReg("(\\d{11})");
	if (!telReg.exactMatch(ui->lineEditUser->text())){
		QMessageBox::information(this,
			QTStr("Prompt"),
			QTStr("Error.UserName"));
	}
	else{
		MBOService* mbo = new MBOService(this);
		connect(mbo, SIGNAL(callbackSignal(int, QString, QJsonValue)), SLOT(smsResult(int, QString, QJsonValue)));

		progressDialog = new WaitDialog(this);
		progressDialog->show();

		mbo->sms(ui->lineEditUser->text(), 2, "");
	}
}
示例#21
0
void DialogResetPassword::smsResult(int code, QString message, QJsonValue data)
{
	progressDialog->close();

	QMessageBox::information(this,
		QTStr("Prompt"),
		message);
}
void OBSBasic::on_actionImportProfile_triggered()
{
	char path[512];

	QString home = QDir::homePath();

	int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get profile config path");
		return;
	}

	QString dir = QFileDialog::getExistingDirectory(
			this,
			QTStr("Basic.MainMenu.Profile.Import"),
			home,
			QFileDialog::ShowDirsOnly |
			QFileDialog::DontResolveSymlinks);

	if (!dir.isEmpty() && !dir.isNull()) {
		QString inputPath = QString::fromUtf8(path);
		QFileInfo finfo(dir);
		QString directory = finfo.fileName();
		QString profileDir = inputPath + directory;
		QDir folder(profileDir);

		if (!folder.exists()) {
			folder.mkpath(profileDir);
			QFile::copy(dir + "/basic.ini",
					profileDir + "/basic.ini");
			QFile::copy(dir + "/service.json",
					profileDir + "/service.json");
			QFile::copy(dir + "/streamEncoder.json",
					profileDir + "/streamEncoder.json");
			QFile::copy(dir + "/recordEncoder.json",
					profileDir + "/recordEncoder.json");
			RefreshProfiles();
		} else {
			QMessageBox::information(this,
					QTStr("Basic.MainMenu.Profile.Import"),
					QTStr("Basic.MainMenu.Profile.Exists"));
		}
	}
}
示例#23
0
void OBSProjector::UpdateProjectorTitle(QString name)
{
	projectorTitle = name;

	QString title = nullptr;
	switch (type) {
	case ProjectorType::Scene:
		title = QTStr("SceneWindow") + " - " + name;
		break;
	case ProjectorType::Source:
		title = QTStr("SourceWindow") + " - " + name;
		break;
	default:
		title = name;
		break;
	}

	setWindowTitle(title);
}
示例#24
0
void OBSBasic::on_pauseStreamBtn_clicked()
{
	tbliveLog.Log(lss_info, L"on_pauseStreamBtn_clicked");

	if (outputHandler->StreamingActive()) {
		// Already streaming
		QMessageBox::StandardButton button =
			QMessageBox::question(this,
			QTStr("ConfirmPause.Title"),
			QTStr("ConfirmPause.Text"));

		if (button == QMessageBox::No)
			return;

		m_bPauseClicked = true;
		ui->pauseStreamBtn->setEnabled(false);
		StopStreaming();
	}
}
示例#25
0
void OBSProjector::mousePressEvent(QMouseEvent *event)
{
	OBSQTDisplay::mousePressEvent(event);

	if (event->button() == Qt::RightButton) {
		QMenu popup(this);
		popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
		popup.exec(QCursor::pos());
	}
}
示例#26
0
void OBSMessageBox::warning(
	QWidget *parent,
	const QString &title,
	const QString &text)
{
	QMessageBox mb(QMessageBox::Warning,
		title, text, QMessageBox::Ok,
		parent);
	mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
	mb.exec();
}
示例#27
0
void OBSMessageBox::information(
		QWidget *parent,
		const QString &title,
		const QString &text)
{
	QMessageBox mb(QMessageBox::Information,
			title, text, QMessageBox::Ok,
			parent);
	mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
	mb.exec();
}
示例#28
0
void DialogResetPassword::done(int code){
	if (QDialog::Accepted == code){
		QRegExp telReg("(\\d{11})");
		QRegExp passwordReg(".+");
		if (!telReg.exactMatch(ui->lineEditUser->text())){
			QMessageBox::information(this,
				QTStr("Prompt"),
				QTStr("Error.UserName"));
		}
		else if (!passwordReg.exactMatch(ui->lineEditPassword->text()) || ui->lineEditPassword->text().compare(ui->lineEditPassword_2->text()) != 0){
			QMessageBox::information(this,
				QTStr("Prompt"),
				QTStr("Error.Password"));
		}
		else if (!passwordReg.exactMatch(ui->lineEditCode->text())){
			QMessageBox::information(this,
				QTStr("Prompt"),
				QTStr("Error.Sms"));
		}
		else{
			MBOService* mbo = new MBOService(this);
			connect(mbo, SIGNAL(callbackSignal(int, QString, QJsonValue)), SLOT(sendResult(int, QString, QJsonValue)));

			progressDialog = new WaitDialog(this);
			progressDialog->show();

			mbo->resetPassword(ui->lineEditUser->text(), ui->lineEditPassword->text(), ui->lineEditCode->text());
		}
	}
	else{
		QDialog::done(code);
	}
}
void OBSBasicStatusBar::ReconnectSuccess()
{
	showMessage(QTStr("Basic.StatusBar.ReconnectSuccessful"), 4000);
	retries              = 0;
	reconnectTimeout     = 0;
	bitrateUpdateSeconds = -1;
	lastBytesSent        = 0;
	lastBytesSentTime    = os_gettime_ns();

	if (streamOutput) {
		delaySecTotal = obs_output_get_active_delay(streamOutput);
		UpdateDelayMsg();
	}
}
void OBSBasicSourceSelect::on_buttonBox_accepted()
{
	bool useExisting = ui->selectExisting->isChecked();

	if (useExisting) {
		QListWidgetItem *item = ui->sourceList->currentItem();
		if (!item)
			return;

		AddExisting(QT_TO_UTF8(item->text()));
	} else {
		if (ui->sourceName->text().isEmpty()) {
			QMessageBox::information(this,
					QTStr("NoNameEntered"),
					QTStr("NoNameEntered"));
			return;
		}

		if (!AddNew(this, id, QT_TO_UTF8(ui->sourceName->text())))
			return;
	}

	done(DialogCode::Accepted);
}