Sfoglia il codice sorgente

UI: Improve/refactor autoconfig/settings service UI

Makes it so that services can have custom handling on a per-service
basis.  The bottom part of the service pane is now a stacked widget
which can now be customized for different types of services
(particularly OAuth services).
jp9000 6 anni fa
parent
commit
24bcfacea5

+ 1 - 0
UI/CMakeLists.txt

@@ -134,6 +134,7 @@ set(obs_SOURCES
 	window-basic-auto-config.cpp
 	window-basic-main-outputs.cpp
 	window-basic-source-select.cpp
+	window-basic-settings-stream.cpp
 	window-basic-auto-config-test.cpp
 	window-basic-main-scene-collections.cpp
 	window-basic-main-transitions.cpp

+ 1 - 1
UI/data/locale/en-US.ini

@@ -127,7 +127,7 @@ Basic.AutoConfig.StreamPage="Stream Information"
 Basic.AutoConfig.StreamPage.SubTitle="Please enter your stream information"
 Basic.AutoConfig.StreamPage.Service="Service"
 Basic.AutoConfig.StreamPage.Service.ShowAll="Show All..."
-Basic.AutoConfig.StreamPage.Service.Custom="Custom"
+Basic.AutoConfig.StreamPage.Service.Custom="Custom..."
 Basic.AutoConfig.StreamPage.Server="Server"
 Basic.AutoConfig.StreamPage.StreamKey="Stream Key"
 Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)"

+ 269 - 208
UI/forms/AutoConfigStreamPage.ui

@@ -13,232 +13,293 @@
   <property name="windowTitle">
    <string notr="true"/>
   </property>
-  <layout class="QFormLayout" name="formLayout">
-   <property name="fieldGrowthPolicy">
-    <enum>QFormLayout::ExpandingFieldsGrow</enum>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>0</number>
    </property>
-   <property name="labelAlignment">
-    <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
+   <property name="leftMargin">
+    <number>0</number>
    </property>
-   <item row="0" column="0">
-    <widget class="QLabel" name="serviceLabel">
-     <property name="text">
-      <string>Basic.AutoConfig.StreamPage.Service</string>
-     </property>
-     <property name="buddy">
-      <cstring>service</cstring>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="1">
-    <widget class="QComboBox" name="service"/>
-   </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="serverLabel">
-     <property name="text">
-      <string>Basic.AutoConfig.StreamPage.Server</string>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QWidget" name="widget" native="true">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
      </property>
+     <layout class="QFormLayout" name="topLayout">
+      <property name="fieldGrowthPolicy">
+       <enum>QFormLayout::ExpandingFieldsGrow</enum>
+      </property>
+      <property name="labelAlignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+      <item row="0" column="0">
+       <spacer name="horizontalSpacer_6">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeType">
+         <enum>QSizePolicy::Fixed</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>87</width>
+          <height>0</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="serviceLabel">
+        <property name="text">
+         <string>Basic.AutoConfig.StreamPage.Service</string>
+        </property>
+        <property name="buddy">
+         <cstring>service</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="service"/>
+      </item>
+     </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="QStackedWidget" name="serverStackedWidget">
+   <item>
+    <widget class="QStackedWidget" name="stackedWidget">
      <property name="currentIndex">
       <number>0</number>
      </property>
-     <widget class="QWidget" name="servicePage">
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <property name="leftMargin">
-        <number>0</number>
-       </property>
-       <property name="topMargin">
-        <number>0</number>
+     <widget class="QWidget" name="streamkeyPage">
+      <layout class="QFormLayout" name="streamkeyPageLayout">
+       <property name="fieldGrowthPolicy">
+        <enum>QFormLayout::ExpandingFieldsGrow</enum>
        </property>
-       <property name="rightMargin">
-        <number>0</number>
+       <property name="labelAlignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
        </property>
-       <property name="bottomMargin">
-        <number>0</number>
-       </property>
-       <item>
-        <widget class="QComboBox" name="server"/>
+       <item row="0" column="0">
+        <widget class="QLabel" name="serverLabel">
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.Server</string>
+         </property>
+        </widget>
        </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="customPage">
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
-       <property name="leftMargin">
-        <number>0</number>
-       </property>
-       <property name="topMargin">
-        <number>0</number>
-       </property>
-       <property name="rightMargin">
-        <number>0</number>
-       </property>
-       <property name="bottomMargin">
-        <number>0</number>
-       </property>
-       <item>
-        <widget class="QLineEdit" name="customServer"/>
+       <item row="0" column="1">
+        <widget class="QStackedWidget" name="serverStackedWidget">
+         <property name="currentIndex">
+          <number>0</number>
+         </property>
+         <widget class="QWidget" name="servicePage">
+          <layout class="QHBoxLayout" name="horizontalLayout_2">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
+            <number>0</number>
+           </property>
+           <item>
+            <widget class="QComboBox" name="server"/>
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="customPage">
+          <layout class="QHBoxLayout" name="horizontalLayout_3">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
+            <number>0</number>
+           </property>
+           <item>
+            <widget class="QLineEdit" name="customServer"/>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="streamKeyLabel">
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.StreamKey</string>
+         </property>
+         <property name="openExternalLinks">
+          <bool>true</bool>
+         </property>
+         <property name="buddy">
+          <cstring>key</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QWidget" name="streamKeyWidget" native="true">
+         <layout class="QHBoxLayout" name="horizontalLayout_4">
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QLineEdit" name="key">
+            <property name="inputMask">
+             <string notr="true"/>
+            </property>
+            <property name="text">
+             <string notr="true"/>
+            </property>
+            <property name="echoMode">
+             <enum>QLineEdit::Password</enum>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="show">
+            <property name="text">
+             <string>Show</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="bitrateLabel">
+         <property name="text">
+          <string>Basic.Settings.Output.VideoBitrate</string>
+         </property>
+         <property name="buddy">
+          <cstring>bitrate</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QSpinBox" name="bitrate">
+         <property name="suffix">
+          <string notr="true"/>
+         </property>
+         <property name="minimum">
+          <number>500</number>
+         </property>
+         <property name="maximum">
+          <number>10000</number>
+         </property>
+         <property name="value">
+          <number>2500</number>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QCheckBox" name="preferHardware">
+         <property name="toolTip">
+          <string>Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip</string>
+         </property>
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.PreferHardwareEncoding</string>
+         </property>
+         <property name="checked">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="0">
+        <spacer name="horizontalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>87</width>
+           <height>17</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="4" column="1">
+        <widget class="QCheckBox" name="doBandwidthTest">
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.PerformBandwidthTest</string>
+         </property>
+         <property name="checked">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="1">
+        <widget class="QGroupBox" name="region">
+         <property name="title">
+          <string>BandwidthTest.Region</string>
+         </property>
+         <layout class="QGridLayout" name="gridLayout">
+          <item row="2" column="0">
+           <widget class="QCheckBox" name="regionAsia">
+            <property name="text">
+             <string>BandwidthTest.Region.Asia</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0">
+           <widget class="QCheckBox" name="regionUS">
+            <property name="text">
+             <string>BandwidthTest.Region.US</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QCheckBox" name="regionEU">
+            <property name="text">
+             <string>BandwidthTest.Region.EU</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QCheckBox" name="regionOther">
+            <property name="text">
+             <string>BandwidthTest.Region.Other</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
-   <item row="2" column="0">
-    <widget class="QLabel" name="streamKeyLabel">
-     <property name="text">
-      <string>Basic.AutoConfig.StreamPage.StreamKey</string>
-     </property>
-     <property name="openExternalLinks">
-      <bool>true</bool>
-     </property>
-     <property name="buddy">
-      <cstring>key</cstring>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="1">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLineEdit" name="key">
-       <property name="inputMask">
-        <string notr="true"/>
-       </property>
-       <property name="text">
-        <string notr="true"/>
-       </property>
-       <property name="echoMode">
-        <enum>QLineEdit::Password</enum>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="show">
-       <property name="text">
-        <string>Show</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item row="3" column="0">
-    <widget class="QLabel" name="bitrateLabel">
-     <property name="text">
-      <string>Basic.Settings.Output.VideoBitrate</string>
-     </property>
-     <property name="buddy">
-      <cstring>bitrate</cstring>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="1">
-    <widget class="QSpinBox" name="bitrate">
-     <property name="suffix">
-      <string notr="true"/>
-     </property>
-     <property name="minimum">
-      <number>500</number>
-     </property>
-     <property name="maximum">
-      <number>10000</number>
-     </property>
-     <property name="value">
-      <number>2500</number>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="1">
-    <widget class="QCheckBox" name="preferHardware">
-     <property name="toolTip">
-      <string>Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip</string>
-     </property>
-     <property name="text">
-      <string>Basic.AutoConfig.StreamPage.PreferHardwareEncoding</string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item row="5" column="0">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeType">
-      <enum>QSizePolicy::Fixed</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>90</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="5" column="1">
-    <widget class="QCheckBox" name="doBandwidthTest">
-     <property name="text">
-      <string>Basic.AutoConfig.StreamPage.PerformBandwidthTest</string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item row="6" column="1">
-    <widget class="QGroupBox" name="region">
-     <property name="title">
-      <string>BandwidthTest.Region</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="2" column="0">
-       <widget class="QCheckBox" name="regionAsia">
-        <property name="text">
-         <string>BandwidthTest.Region.Asia</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QCheckBox" name="regionUS">
-        <property name="text">
-         <string>BandwidthTest.Region.US</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QCheckBox" name="regionEU">
-        <property name="text">
-         <string>BandwidthTest.Region.EU</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QCheckBox" name="regionOther">
-        <property name="text">
-         <string>BandwidthTest.Region.Other</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
   </layout>
  </widget>
- <tabstops>
-  <tabstop>service</tabstop>
-  <tabstop>server</tabstop>
-  <tabstop>customServer</tabstop>
-  <tabstop>key</tabstop>
-  <tabstop>show</tabstop>
-  <tabstop>preferHardware</tabstop>
-  <tabstop>doBandwidthTest</tabstop>
-  <tabstop>regionUS</tabstop>
-  <tabstop>regionEU</tabstop>
-  <tabstop>regionAsia</tabstop>
-  <tabstop>regionOther</tabstop>
- </tabstops>
  <resources/>
  <connections/>
 </ui>

+ 234 - 134
UI/forms/OBSBasicSettings.ui

@@ -145,8 +145,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>804</width>
-              <height>1072</height>
+              <width>801</width>
+              <height>836</height>
              </rect>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_19">
@@ -686,89 +686,190 @@
           <number>0</number>
          </property>
          <item>
-          <widget class="QWidget" name="streamContainer" native="true">
+          <widget class="QWidget" name="widget_5" native="true">
            <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+            <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
-           <layout class="QVBoxLayout" name="verticalLayout_6">
-            <property name="leftMargin">
-             <number>0</number>
+           <layout class="QFormLayout" name="topStreamLayout">
+            <property name="fieldGrowthPolicy">
+             <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
             </property>
-            <property name="topMargin">
-             <number>0</number>
+            <property name="labelAlignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
             </property>
-            <property name="rightMargin">
-             <number>0</number>
-            </property>
-            <property name="bottomMargin">
-             <number>0</number>
-            </property>
-            <item alignment="Qt::AlignTop">
-             <widget class="QWidget" name="widget_5" native="true">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
+            <item row="2" column="0">
+             <widget class="QLabel" name="serviceLabel">
+              <property name="text">
+               <string>Basic.AutoConfig.StreamPage.Service</string>
               </property>
-              <layout class="QVBoxLayout" name="verticalLayout_7">
-               <property name="leftMargin">
-                <number>0</number>
+              <property name="buddy">
+               <cstring>service</cstring>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="1">
+             <widget class="QComboBox" name="service">
+              <property name="maxVisibleItems">
+               <number>20</number>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="0">
+             <spacer name="horizontalSpacer_17">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>170</width>
+                <height>0</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </widget>
+         </item>
+         <item>
+          <widget class="QStackedWidget" name="streamStackWidget">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="currentIndex">
+            <number>0</number>
+           </property>
+           <widget class="QWidget" name="streamKeyPage">
+            <layout class="QFormLayout" name="streamkeyPageLayout">
+             <property name="fieldGrowthPolicy">
+              <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+             </property>
+             <property name="labelAlignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+             <item row="0" column="0">
+              <widget class="QLabel" name="serverLabel">
+               <property name="text">
+                <string>Basic.AutoConfig.StreamPage.Server</string>
                </property>
-               <property name="topMargin">
+              </widget>
+             </item>
+             <item row="0" column="1">
+              <widget class="QStackedWidget" name="serverStackedWidget">
+               <property name="currentIndex">
                 <number>0</number>
                </property>
-               <property name="rightMargin">
-                <number>0</number>
+               <widget class="QWidget" name="servicePage">
+                <layout class="QHBoxLayout" name="horizontalLayout_21">
+                 <property name="leftMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="rightMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>0</number>
+                 </property>
+                 <item>
+                  <widget class="QComboBox" name="server"/>
+                 </item>
+                </layout>
+               </widget>
+               <widget class="QWidget" name="customPage">
+                <layout class="QHBoxLayout" name="horizontalLayout_22">
+                 <property name="leftMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="rightMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>0</number>
+                 </property>
+                 <item>
+                  <widget class="QLineEdit" name="customServer"/>
+                 </item>
+                </layout>
+               </widget>
+              </widget>
+             </item>
+             <item row="1" column="0">
+              <widget class="QLabel" name="streamKeyLabel">
+               <property name="text">
+                <string>Basic.AutoConfig.StreamPage.StreamKey</string>
                </property>
-               <property name="bottomMargin">
-                <number>0</number>
+               <property name="openExternalLinks">
+                <bool>true</bool>
                </property>
-               <item>
-                <widget class="QWidget" name="widget_6" native="true">
-                 <layout class="QFormLayout" name="formLayout_8">
-                  <property name="fieldGrowthPolicy">
-                   <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+               <property name="buddy">
+                <cstring>key</cstring>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="1">
+              <widget class="QWidget" name="streamKeyWidget" native="true">
+               <layout class="QHBoxLayout" name="horizontalLayout_11">
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QLineEdit" name="key">
+                  <property name="inputMask">
+                   <string notr="true"/>
                   </property>
-                  <item row="0" column="0">
-                   <widget class="QLabel" name="label_21">
-                    <property name="minimumSize">
-                     <size>
-                      <width>170</width>
-                      <height>0</height>
-                     </size>
-                    </property>
-                    <property name="text">
-                     <string>Basic.Settings.Stream.StreamType</string>
-                    </property>
-                    <property name="alignment">
-                     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-                    </property>
-                    <property name="buddy">
-                     <cstring>streamType</cstring>
-                    </property>
-                   </widget>
-                  </item>
-                  <item row="0" column="1">
-                   <widget class="QComboBox" name="streamType"/>
-                  </item>
-                 </layout>
-                </widget>
-               </item>
-               <item>
-                <widget class="Line" name="line">
-                 <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-            </item>
-           </layout>
+                  <property name="text">
+                   <string notr="true"/>
+                  </property>
+                  <property name="echoMode">
+                   <enum>QLineEdit::Password</enum>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="show">
+                  <property name="text">
+                   <string>Show</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item row="2" column="0">
+              <spacer name="horizontalSpacer_18">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>170</width>
+                 <height>8</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+            </layout>
+           </widget>
           </widget>
          </item>
         </layout>
@@ -797,8 +898,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>813</width>
-              <height>770</height>
+              <width>818</width>
+              <height>697</height>
              </rect>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_21">
@@ -3913,7 +4014,7 @@
               <x>0</x>
               <y>0</y>
               <width>594</width>
-              <height>807</height>
+              <height>833</height>
              </rect>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_23">
@@ -4751,7 +4852,6 @@
  </widget>
  <tabstops>
   <tabstop>listWidget</tabstop>
-  <tabstop>streamType</tabstop>
   <tabstop>outputMode</tabstop>
   <tabstop>simpleOutputVBitrate</tabstop>
   <tabstop>simpleOutputABitrate</tabstop>
@@ -4939,8 +5039,8 @@
      <y>16</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>401</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -4951,12 +5051,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -4967,12 +5067,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -4983,12 +5083,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -4999,12 +5099,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -5015,12 +5115,12 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>232</x>
-     <y>41</y>
+     <x>260</x>
+     <y>73</y>
     </hint>
     <hint type="destinationlabel">
-     <x>241</x>
-     <y>30</y>
+     <x>242</x>
+     <y>85</y>
     </hint>
    </hints>
   </connection>
@@ -5031,12 +5131,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>60</y>
+     <x>260</x>
+     <y>85</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>50</y>
+     <x>229</x>
+     <y>85</y>
     </hint>
    </hints>
   </connection>
@@ -5047,12 +5147,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>259</x>
-     <y>39</y>
+     <x>260</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>29</y>
+     <x>229</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -5063,12 +5163,12 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>168</x>
-     <y>56</y>
+     <x>260</x>
+     <y>85</y>
     </hint>
     <hint type="destinationlabel">
-     <x>228</x>
-     <y>50</y>
+     <x>229</x>
+     <y>85</y>
     </hint>
    </hints>
   </connection>
@@ -5079,12 +5179,12 @@
    <slot>setCurrentIndex(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>50</y>
+     <x>260</x>
+     <y>85</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>52</y>
+     <x>260</x>
+     <y>85</y>
     </hint>
    </hints>
   </connection>
@@ -5095,12 +5195,12 @@
    <slot>setVisible(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
     <hint type="destinationlabel">
-     <x>250</x>
-     <y>39</y>
+     <x>251</x>
+     <y>64</y>
     </hint>
    </hints>
   </connection>
@@ -5111,11 +5211,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>579</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>602</y>
     </hint>
    </hints>
@@ -5127,11 +5227,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>579</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>625</y>
     </hint>
    </hints>
@@ -5159,7 +5259,7 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>340</y>
     </hint>
     <hint type="destinationlabel">
@@ -5175,11 +5275,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>340</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>366</y>
     </hint>
    </hints>
@@ -5191,11 +5291,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>340</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>389</y>
     </hint>
    </hints>
@@ -5207,11 +5307,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>340</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>412</y>
     </hint>
    </hints>
@@ -5223,11 +5323,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>340</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>435</y>
     </hint>
    </hints>
@@ -5239,11 +5339,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>222</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>245</y>
     </hint>
    </hints>
@@ -5255,11 +5355,11 @@
    <slot>setEnabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>950</x>
+     <x>933</x>
      <y>268</y>
     </hint>
     <hint type="destinationlabel">
-     <x>950</x>
+     <x>933</x>
      <y>291</y>
     </hint>
    </hints>

+ 22 - 11
UI/window-basic-auto-config.cpp

@@ -223,6 +223,16 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
 	ui->bitrateLabel->setVisible(false);
 	ui->bitrate->setVisible(false);
 
+	int vertSpacing = ui->topLayout->verticalSpacing();
+
+	QMargins m = ui->topLayout->contentsMargins();
+	m.setBottom(vertSpacing / 2);
+	ui->topLayout->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"));
 
@@ -378,11 +388,11 @@ void AutoConfigStreamPage::ServiceChanged()
 	if (service == "Twitch" && wiz->twitchAuto)
 		regionBased = false;
 
-	ui->formLayout->removeWidget(ui->serverLabel);
-	ui->formLayout->removeWidget(ui->serverStackedWidget);
+	ui->streamkeyPageLayout->removeWidget(ui->serverLabel);
+	ui->streamkeyPageLayout->removeWidget(ui->serverStackedWidget);
 
 	if (custom) {
-		ui->formLayout->insertRow(1, ui->serverLabel,
+		ui->streamkeyPageLayout->insertRow(1, ui->serverLabel,
 				ui->serverStackedWidget);
 
 		ui->region->setVisible(false);
@@ -391,7 +401,7 @@ void AutoConfigStreamPage::ServiceChanged()
 		ui->serverLabel->setVisible(true);
 	} else {
 		if (!testBandwidth)
-			ui->formLayout->insertRow(2, ui->serverLabel,
+			ui->streamkeyPageLayout->insertRow(2, ui->serverLabel,
 					ui->serverStackedWidget);
 
 		ui->region->setVisible(regionBased && testBandwidth);
@@ -474,12 +484,6 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
 	for (QString &name : names)
 		ui->service->addItem(name);
 
-	if (!lastService.isEmpty()) {
-		int idx = ui->service->findText(lastService);
-		if (idx != -1)
-			ui->service->setCurrentIndex(idx);
-	}
-
 	if (!showAll) {
 		ui->service->addItem(
 			QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
@@ -490,6 +494,12 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
 			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);
@@ -573,7 +583,7 @@ AutoConfig::AutoConfig(QWidget *parent)
 #ifdef _WIN32
 	setWizardStyle(QWizard::ModernStyle);
 #endif
-	AutoConfigStreamPage *streamPage = new AutoConfigStreamPage();
+	streamPage = new AutoConfigStreamPage();
 
 	setPage(StartPage, new AutoConfigStartPage());
 	setPage(VideoPage, new AutoConfigVideoPage());
@@ -637,6 +647,7 @@ AutoConfig::AutoConfig(QWidget *parent)
 
 	streamPage->UpdateServerList();
 	streamPage->UpdateKeyLink();
+	streamPage->lastService.clear();
 
 	if (!customServer) {
 		QComboBox *serverList = streamPage->ui->server;

+ 8 - 0
UI/window-basic-auto-config.hpp

@@ -17,6 +17,8 @@ class Ui_AutoConfigVideoPage;
 class Ui_AutoConfigStreamPage;
 class Ui_AutoConfigTestPage;
 
+class AutoConfigStreamPage;
+
 class AutoConfig : public QWizard {
 	Q_OBJECT
 
@@ -60,6 +62,8 @@ class AutoConfig : public QWizard {
 
 	static inline const char *GetEncoderId(Encoder enc);
 
+	AutoConfigStreamPage *streamPage = nullptr;
+
 	Service service = Service::Other;
 	Quality recordingQuality = Quality::Stream;
 	Encoder recordingEncoder = Encoder::Stream;
@@ -155,6 +159,10 @@ class AutoConfigStreamPage : public QWizardPage {
 
 	friend class AutoConfig;
 
+	enum class Section : int {
+		StreamKey,
+	};
+
 	Ui_AutoConfigStreamPage *ui;
 	QString lastService;
 	bool ready = false;

+ 300 - 0
UI/window-basic-settings-stream.cpp

@@ -0,0 +1,300 @@
+#include <QMessageBox>
+
+#include "window-basic-settings.hpp"
+#include "obs-app.hpp"
+#include "window-basic-main.hpp"
+#include "qt-wrappers.hpp"
+
+enum class ListOpt : int {
+	ShowAll = 1,
+	Custom,
+};
+
+enum class Section : int {
+	StreamKey,
+};
+
+inline bool OBSBasicSettings::IsCustomService() const
+{
+	return ui->service->currentData().toInt() == (int)ListOpt::Custom;
+}
+
+void OBSBasicSettings::InitStreamPage()
+{
+	int vertSpacing = ui->topStreamLayout->verticalSpacing();
+
+	QMargins m = ui->topStreamLayout->contentsMargins();
+	m.setBottom(vertSpacing / 2);
+	ui->topStreamLayout->setContentsMargins(m);
+
+	m = ui->streamkeyPageLayout->contentsMargins();
+	m.setTop(vertSpacing / 2);
+	ui->streamkeyPageLayout->setContentsMargins(m);
+
+	LoadServices(false);
+
+	connect(ui->service, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(UpdateServerList()));
+	connect(ui->service, SIGNAL(currentIndexChanged(int)),
+			this, SLOT(UpdateKeyLink()));
+}
+
+void OBSBasicSettings::LoadStream1Settings()
+{
+	obs_service_t *service_obj = main->GetService();
+	const char *type = obs_service_get_type(service_obj);
+
+	loading = true;
+
+	obs_data_t *settings = obs_service_get_settings(service_obj);
+
+	const char *service = obs_data_get_string(settings, "service");
+	const char *server = obs_data_get_string(settings, "server");
+	const char *key = obs_data_get_string(settings, "key");
+
+	if (strcmp(type, "rtmp_custom") == 0) {
+		ui->service->setCurrentIndex(0);
+		ui->customServer->setText(server);
+	} else {
+		int idx = ui->service->findText(service);
+		if (idx == -1) {
+			if (service && *service)
+				ui->service->insertItem(1, service);
+			idx = 1;
+		}
+		ui->service->setCurrentIndex(idx);
+	}
+
+	UpdateServerList();
+
+	if (strcmp(type, "rtmp_common") == 0) {
+		int idx = ui->server->findData(server);
+		if (idx == -1) {
+			if (server && *server)
+				ui->server->insertItem(0, server, server);
+			idx = 0;
+		}
+		ui->server->setCurrentIndex(idx);
+	}
+
+	ui->key->setText(key);
+
+	lastService.clear();
+	on_service_currentIndexChanged(0);
+
+	obs_data_release(settings);
+
+	UpdateKeyLink();
+
+	loading = false;
+}
+
+void OBSBasicSettings::SaveStream1Settings()
+{
+	bool customServer = IsCustomService();
+	const char *service_id = customServer
+		? "rtmp_custom"
+		: "rtmp_common";
+
+	obs_service_t *oldService = main->GetService();
+	OBSData hotkeyData = obs_hotkeys_save_service(oldService);
+	obs_data_release(hotkeyData);
+
+	OBSData settings = obs_data_create();
+	obs_data_release(settings);
+
+	if (!customServer) {
+		obs_data_set_string(settings, "service",
+				QT_TO_UTF8(ui->service->currentText()));
+		obs_data_set_string(settings, "server",
+				QT_TO_UTF8(ui->server->currentData().toString()));
+	} else {
+		obs_data_set_string(settings, "server",
+				QT_TO_UTF8(ui->customServer->text()));
+	}
+
+	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
+
+	OBSService newService = obs_service_create(service_id,
+			"default_service", settings, hotkeyData);
+	obs_service_release(newService);
+
+	if (!newService)
+		return;
+
+	main->SetService(newService);
+	main->SaveService();
+}
+
+void OBSBasicSettings::UpdateKeyLink()
+{
+	bool custom = IsCustomService();
+	QString serviceName = ui->service->currentText();
+
+	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>";
+	}
+
+	ui->streamKeyLabel->setText(text);
+}
+
+void OBSBasicSettings::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);
+}
+
+void OBSBasicSettings::on_service_currentIndexChanged(int)
+{
+	bool showMore =
+		ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
+	if (showMore)
+		return;
+
+	std::string service = QT_TO_UTF8(ui->service->currentText());
+	bool custom = IsCustomService();
+
+	if (custom) {
+		ui->streamkeyPageLayout->insertRow(1, ui->serverLabel,
+				ui->serverStackedWidget);
+
+		ui->serverStackedWidget->setCurrentIndex(1);
+		ui->serverStackedWidget->setVisible(true);
+		ui->serverLabel->setVisible(true);
+	} else {
+		ui->serverStackedWidget->setCurrentIndex(0);
+	}
+}
+
+void OBSBasicSettings::UpdateServerList()
+{
+	QString serviceName = ui->service->currentText();
+	bool showMore =
+		ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
+
+	if (showMore) {
+		LoadServices(true);
+		ui->service->showPopup();
+		return;
+	} else {
+		lastService = serviceName;
+	}
+
+	obs_properties_t *props = obs_get_service_properties("rtmp_common");
+	obs_property_t *services = obs_properties_get(props, "service");
+
+	OBSData settings = obs_data_create();
+	obs_data_release(settings);
+
+	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+	obs_property_modified(services, settings);
+
+	obs_property_t *servers = obs_properties_get(props, "server");
+
+	ui->server->clear();
+
+	size_t servers_count = obs_property_list_item_count(servers);
+	for (size_t i = 0; i < servers_count; i++) {
+		const char *name = obs_property_list_item_name(servers, i);
+		const char *server = obs_property_list_item_string(servers, i);
+		ui->server->addItem(name, server);
+	}
+
+	obs_properties_destroy(props);
+}
+
+void OBSBasicSettings::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"));
+	}
+}
+
+OBSService OBSBasicSettings::SpawnTempService()
+{
+	bool custom = IsCustomService();
+	const char *service_id = custom ? "rtmp_custom" : "rtmp_common";
+
+	OBSData settings = obs_data_create();
+	obs_data_release(settings);
+
+	if (!custom) {
+		obs_data_set_string(settings, "service",
+				QT_TO_UTF8(ui->service->currentText()));
+		obs_data_set_string(settings, "server",
+				QT_TO_UTF8(ui->server->currentData().toString()));
+	} else {
+		obs_data_set_string(settings, "server",
+				QT_TO_UTF8(ui->customServer->text()));
+	}
+	obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text()));
+
+	OBSService newService = obs_service_create(service_id,
+			"temp_service", settings, nullptr);
+	obs_service_release(newService);
+
+	return newService;
+}

+ 6 - 99
UI/window-basic-settings.cpp

@@ -322,8 +322,11 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->multiviewDrawNames,   CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->multiviewDrawAreas,   CHECK_CHANGED,  GENERAL_CHANGED);
 	HookWidget(ui->multiviewLayout,      COMBO_CHANGED,  GENERAL_CHANGED);
+	HookWidget(ui->service,              COMBO_CHANGED,  STREAM1_CHANGED);
+	HookWidget(ui->server,               COMBO_CHANGED,  STREAM1_CHANGED);
+	HookWidget(ui->customServer,         EDIT_CHANGED,   STREAM1_CHANGED);
+	HookWidget(ui->key,                  EDIT_CHANGED,   STREAM1_CHANGED);
 	HookWidget(ui->outputMode,           COMBO_CHANGED,  OUTPUTS_CHANGED);
-	HookWidget(ui->streamType,           COMBO_CHANGED,  STREAM1_CHANGED);
 	HookWidget(ui->simpleOutputPath,     EDIT_CHANGED,   OUTPUTS_CHANGED);
 	HookWidget(ui->simpleNoSpace,        CHECK_CHANGED,  OUTPUTS_CHANGED);
 	HookWidget(ui->simpleOutRecFormat,   COMBO_CHANGED,  OUTPUTS_CHANGED);
@@ -560,7 +563,6 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 
 	installEventFilter(CreateShortcutFilter());
 
-	LoadServiceTypes();
 	LoadEncoderTypes();
 	LoadColorRanges();
 	LoadFormats();
@@ -691,6 +693,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 
 	obs_properties_destroy(ppts);
 
+	InitStreamPage();
 	LoadSettings(false);
 
 	// Add warning checks to advanced output recording section controls
@@ -770,23 +773,6 @@ void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section,
 		config_set_int(main->Config(), section, value, widget->value());
 }
 
-void OBSBasicSettings::LoadServiceTypes()
-{
-	const char    *type;
-	size_t        idx = 0;
-
-	while (obs_enum_service_types(idx++, &type)) {
-		const char *name = obs_service_get_display_name(type);
-		QString qName = QT_UTF8(name);
-		QString qType = QT_UTF8(type);
-
-		ui->streamType->addItem(qName, qType);
-	}
-
-	type = obs_service_get_type(main->GetService());
-	SetComboByValue(ui->streamType, type);
-}
-
 #define TEXT_USE_STREAM_ENC \
 	QTStr("Basic.Settings.Output.Adv.Recording.UseStreamEncoder")
 
@@ -1145,37 +1131,6 @@ void OBSBasicSettings::LoadGeneralSettings()
 	loading = false;
 }
 
-void OBSBasicSettings::LoadStream1Settings()
-{
-	QLayout *layout = ui->streamContainer->layout();
-	obs_service_t *service = main->GetService();
-	const char *type = obs_service_get_type(service);
-
-	loading = true;
-
-	obs_data_t *settings = obs_service_get_settings(service);
-
-	delete streamProperties;
-	streamProperties = new OBSPropertiesView(settings, type,
-			(PropertiesReloadCallback)obs_get_service_properties,
-			170);
-
-	streamProperties->setProperty("changed", QVariant(false));
-	layout->addWidget(streamProperties);
-
-	QObject::connect(streamProperties, SIGNAL(Changed()),
-			this, STREAM1_CHANGED);
-
-	obs_data_release(settings);
-
-	loading = false;
-
-	if (main->StreamingActive()) {
-		ui->streamType->setEnabled(false);
-		ui->streamContainer->setEnabled(false);
-	}
-}
-
 void OBSBasicSettings::LoadRendererList()
 {
 #ifdef _WIN32
@@ -2809,26 +2764,6 @@ void OBSBasicSettings::SaveGeneralSettings()
 		OBSProjector::UpdateMultiviewProjectors();
 }
 
-void OBSBasicSettings::SaveStream1Settings()
-{
-	QString streamType = GetComboData(ui->streamType);
-
-	obs_service_t *oldService = main->GetService();
-	obs_data_t *hotkeyData = obs_hotkeys_save_service(oldService);
-
-	obs_service_t *newService = obs_service_create(QT_TO_UTF8(streamType),
-			"default_service", streamProperties->GetSettings(),
-			hotkeyData);
-
-	obs_data_release(hotkeyData);
-	if (!newService)
-		return;
-
-	main->SetService(newService);
-	main->SaveService();
-	obs_service_release(newService);
-}
-
 void OBSBasicSettings::SaveVideoSettings()
 {
 	QString baseResolution   = ui->baseResolution->currentText();
@@ -3445,30 +3380,6 @@ void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button)
 	}
 }
 
-void OBSBasicSettings::on_streamType_currentIndexChanged(int idx)
-{
-	if (loading)
-		return;
-
-	QLayout *layout = ui->streamContainer->layout();
-	QString streamType = ui->streamType->itemData(idx).toString();
-	obs_data_t *settings = obs_service_defaults(QT_TO_UTF8(streamType));
-
-	delete streamProperties;
-	streamProperties = new OBSPropertiesView(settings,
-			QT_TO_UTF8(streamType),
-			(PropertiesReloadCallback)obs_get_service_properties,
-			170);
-
-	streamProperties->setProperty("changed", QVariant(true));
-	layout->addWidget(streamProperties);
-
-	QObject::connect(streamProperties, SIGNAL(Changed()),
-			this, STREAM1_CHANGED);
-
-	obs_data_release(settings);
-}
-
 void OBSBasicSettings::on_simpleOutputBrowse_clicked()
 {
 	QString dir = QFileDialog::getExistingDirectory(this,
@@ -4318,11 +4229,7 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
 	OBSService service;
 
 	if (stream1Changed) {
-		QString streamType = GetComboData(ui->streamType);
-		service = obs_service_create_private(
-				QT_TO_UTF8(streamType), nullptr,
-				streamProperties->GetSettings());
-		obs_service_release(service);
+		service = SpawnTempService();
 	} else {
 		service = main->GetService();
 	}

+ 16 - 3
UI/window-basic-settings.hpp

@@ -20,12 +20,13 @@
 
 #include <util/util.hpp>
 #include <QDialog>
+#include <QPointer>
 #include <memory>
 #include <string>
 
 #include <libff/ff-util.h>
 
-#include <obs.h>
+#include <obs.hpp>
 
 class OBSBasic;
 class QAbstractButton;
@@ -185,7 +186,6 @@ private:
 
 	bool QueryChanges();
 
-	void LoadServiceTypes();
 	void LoadEncoderTypes();
 	void LoadColorRanges();
 	void LoadFormats();
@@ -207,6 +207,17 @@ private:
 	void LoadLanguageList();
 	void LoadThemeList();
 
+	/* stream */
+	void InitStreamPage();
+	inline bool IsCustomService() const;
+	void LoadServices(bool showAll);
+	QString lastService;
+private slots:
+	void UpdateServerList();
+	void UpdateKeyLink();
+	void on_show_clicked();
+private:
+
 	/* output */
 	void LoadSimpleOutputSettings();
 	void LoadAdvOutputStreamingSettings();
@@ -255,7 +266,7 @@ private slots:
 	void on_listWidget_itemSelectionChanged();
 	void on_buttonBox_clicked(QAbstractButton *button);
 
-	void on_streamType_currentIndexChanged(int idx);
+	void on_service_currentIndexChanged(int idx);
 	void on_simpleOutputBrowse_clicked();
 	void on_advOutRecPathBrowse_clicked();
 	void on_advOutFFPathBrowse_clicked();
@@ -306,6 +317,8 @@ private slots:
 
 	void SimpleStreamingEncoderChanged();
 
+	OBSService SpawnTempService();
+
 protected:
 	virtual void closeEvent(QCloseEvent *event);