1 //=============================================================================
2 //
3 //   File : OptionsWidget_dcc.cpp
4 //   Creation date : Fri Aug 17 22:08:09 2001 GMT by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 //   This program is FREE software. You can redistribute it and/or
10 //   modify it under the terms of the GNU General Public License
11 //   as published by the Free Software Foundation; either version 2
12 //   of the License, or (at your option) any later version.
13 //
14 //   This program is distributed in the HOPE that it will be USEFUL,
15 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 //   See the GNU General Public License for more details.
18 //
19 //   You should have received a copy of the GNU General Public License
20 //   along with this program. If not, write to the Free Software Foundation,
21 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24 
25 #include "OptionsWidget_dcc.h"
26 
27 #include "KviOptions.h"
28 #include "KviLocale.h"
29 
30 #include <QLayout>
31 
OptionsWidget_dcc(QWidget * pParent)32 OptionsWidget_dcc::OptionsWidget_dcc(QWidget * pParent)
33     : KviOptionsWidget(pParent)
34 {
35 }
36 
37 OptionsWidget_dcc::~OptionsWidget_dcc()
38     = default;
39 
OptionsWidget_dccGeneral(QWidget * parent)40 OptionsWidget_dccGeneral::OptionsWidget_dccGeneral(QWidget * parent)
41     : KviOptionsWidget(parent)
42 {
43 	setObjectName("dccgeneral_options_widget");
44 	createLayout();
45 
46 	KviBoolSelector * b = addBoolSelector(0, 0, 0, 0, __tr2qs_ctx("Use workaround for firewall", "options"), KviOption_boolCantAcceptIncomingDccConnections);
47 	mergeTip(b, __tr2qs_ctx("Enable this option if you can't accept incoming connections.<br>"
48 	                        "KVIrc will try to use different methods to send and receive files.<br>"
49 	                        "Please note that these methods may NOT work when communicating with a non-KVIrc client.", "options"));
50 
51 	addRowSpacer(0, 1, 0, 1);
52 }
53 
54 OptionsWidget_dccGeneral::~OptionsWidget_dccGeneral()
55     = default;
56 
OptionsWidget_dccAdvanced(QWidget * parent)57 OptionsWidget_dccAdvanced::OptionsWidget_dccAdvanced(QWidget * parent)
58     : KviOptionsWidget(parent)
59 {
60 	setObjectName("dccgeneral_options_widget");
61 	createLayout();
62 
63 	KviBoolSelector * b;
64 	KviBoolSelector * b2;
65 	KviTalGroupBox * g;
66 	KviStringSelector * s;
67 	KviUIntSelector * u;
68 
69 	g = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("Network Properties", "options"));
70 
71 	b = addBoolSelector(g, __tr2qs_ctx("Use user-defined address or network interface", "options"), KviOption_boolDccListenOnSpecifiedInterfaceByDefault);
72 	mergeTip(b, __tr2qs_ctx("Enable this option if you are on a multihost machine and want "
73 	                        "to force one of the available IP addresses to be used for outgoing DCCs.<br>This is especially useful "
74 	                        "when you use IPv6 and IPv4 addresses. You can force KVIrc to always choose the IPv4 interface.", "options"));
75 
76 	s = addStringSelector(g, __tr2qs_ctx("Listen on address/interface:", "options"), KviOption_stringDccListenDefaultInterface,
77 	    KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault));
78 	mergeTip(s, __tr2qs_ctx("This is the IP address or name of the interface to use by default for outgoing DCC transfers.<br>"
79 	                        "On UNIX systems that support it, you can also specify IPv4 interface names (such as <b>ppp0</b>).<br>"
80 	                        "If you set it to <b>0.0.0.0</b>, KVIrc will try to use the first available IPv4 interface.", "options"));
81 
82 	connect(b, SIGNAL(toggled(bool)), s, SLOT(setEnabled(bool)));
83 
84 	b = addBoolSelector(g, __tr2qs_ctx("Use user-defined port range", "options"), KviOption_boolUserDefinedPortRange);
85 	mergeTip(b, __tr2qs_ctx("Enable this option if you want specify a local port range for DCC.", "options"));
86 
87 	KviTalHBox * hb = new KviTalHBox(g);
88 	hb->setSpacing(4);
89 
90 	u = addUIntSelector(hb, __tr2qs_ctx("Lowest port:", "options"), KviOption_uintDccMinPort, 1, 65535, 5000,
91 	    KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange));
92 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
93 
94 	u = addUIntSelector(hb, __tr2qs_ctx("Highest port:", "options"), KviOption_uintDccMaxPort, 1, 65535, 30000,
95 	    KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange));
96 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
97 
98 	b = addBoolSelector(g, __tr2qs_ctx("Send a fixed address in requests", "options"), KviOption_boolDccSendFakeAddressByDefault);
99 	mergeTip(b, __tr2qs_ctx("Enable this option if you want to always send a fake IP address in your DCC requests.<br>"
100 	                        "This might be useful if you're behind a router with a static address that does network address "
101 	                        "translation (NAT) and forwards all or a range of ports.", "options"));
102 
103 	s = addStringSelector(g, __tr2qs_ctx("Send address/interface:", "options"), KviOption_stringDefaultDccFakeAddress,
104 	    KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault));
105 	connect(b, SIGNAL(toggled(bool)), s, SLOT(setEnabled(bool)));
106 	mergeTip(s, __tr2qs_ctx("This is the fixed address that will be sent with all DCC requests if you enable the option above.", "options"));
107 
108 	b2 = addBoolSelector(g, __tr2qs_ctx("Guess address from IRC server if unroutable", "options"), KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable,
109 	    !KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault));
110 
111 	connect(b, SIGNAL(toggled(bool)), b2, SLOT(setNotEnabled(bool)));
112 
113 	mergeTip(b2, __tr2qs_ctx("You can enable this option if you are behind a router that forwards all or a range of ports.<br>"
114 	                         "KVIrc will try to guess the IP address to use for DCC by looking up the local hostname as seen "
115 	                         "by the IRC server you're connected to.<br>This method is an exclusive alternative to the \"fixed address\" above.<br>"
116 	                         "It might guess the correct address automatically if certain conditions are met (e.g. the IRC server doesn't mask hostnames).", "options"));
117 
118 	b = addBoolSelector(g, __tr2qs_ctx("Use \"broken bouncer hack\" to detect address", "options"), KviOption_boolDccBrokenBouncerHack,
119 	    KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable));
120 	mergeTip(b, __tr2qs_ctx("When you're behind a dialup router and also tunneling through a psyBNC bouncer, "
121 	                        "you can use a bug in the bouncer to force KVIrc to bind the DCC connections to the dialup router's address.<br>"
122 	                        "It's an ugly hack - use it only if nothing else works.", "options"));
123 
124 	connect(b2, SIGNAL(toggled(bool)), b, SLOT(setEnabled(bool)));
125 
126 	b = addBoolSelector(0, 1, 1, 1, __tr2qs_ctx("Notify failed DCC handshakes to the remote end", "options"), KviOption_boolNotifyFailedDccHandshakes);
127 	mergeTip(b, __tr2qs_ctx("If you enable this option, when a DCC request from a remote "
128 	                        "user can't be satisfied KVIrc will notify him by a CTCP ERRMSG. This is "
129 	                        "a nice feature so it is a good idea to leave it on unless for some reason "
130 	                        "you have deactivated the anti-flood system: in this case turning off this option "
131 	                        "might help if you often get attacked by CTCP floods.", "options"));
132 
133 	u = addUIntSelector(0, 2, 1, 2, __tr2qs_ctx("Maximum number of DCC sessions:", "options"), KviOption_uintMaxDccSlots, 0, 1000, 64);
134 	mergeTip(u, __tr2qs_ctx("This is the maximum number of concurrent DCC sessions "
135 	                        "and it includes all the DCC types (send, chat, recv.). "
136 	                        "KVIrc will refuse the requests when this limit is reached.", "options"));
137 
138 	u = addUIntSelector(0, 3, 1, 3, __tr2qs_ctx("DCC socket timeout:", "options"), KviOption_uintDccSocketTimeout, 10, 65536, 180);
139 	u->setSuffix(__tr2qs_ctx(" sec", "options"));
140 	mergeTip(u, __tr2qs_ctx("This is the amount of time that KVIrc will wait for a response before assuming that a DCC has failed "
141 	                        "because the remote client was unable to connect to our listening socket.", "options"));
142 
143 	addRowSpacer(0, 4, 1, 4);
144 }
145 
146 OptionsWidget_dccAdvanced::~OptionsWidget_dccAdvanced()
147     = default;
148 
OptionsWidget_dccSend(QWidget * parent)149 OptionsWidget_dccSend::OptionsWidget_dccSend(QWidget * parent)
150     : KviOptionsWidget(parent)
151 {
152 	setObjectName("dccsend_options_widget");
153 }
154 
155 OptionsWidget_dccSend::~OptionsWidget_dccSend()
156     = default;
157 
OptionsWidget_dccSendGeneral(QWidget * parent)158 OptionsWidget_dccSendGeneral::OptionsWidget_dccSendGeneral(QWidget * parent)
159     : KviOptionsWidget(parent)
160 {
161 	setObjectName("dccsend_options_widget");
162 	createLayout();
163 
164 	KviBoolSelector * b;
165 	KviBoolSelector * b2;
166 	KviBoolSelector * b3;
167 	KviBoolSelector * b4;
168 	KviBoolSelector * b1;
169 	KviTalGroupBox * g;
170 
171 	g = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("On Incoming File", "options"));
172 	b2 = addBoolSelector(g, __tr2qs_ctx("Automatically accept", "options"), KviOption_boolAutoAcceptDccSend);
173 	b3 = addBoolSelector(g, __tr2qs_ctx("Open auto-accepted transfer window without focus", "options"), KviOption_boolCreateMinimizedDccSendWhenAutoAccepted,
174 	    !KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend));
175 	mergeTip(b3, __tr2qs_ctx("This option prevents the transfer window "
176 	                         "from opening and diverting application focus.<br>"
177 	                         "Enable this if you don't like the transfer window "
178 	                         "popping up while you're typing something in a channel.", "options"));
179 
180 	b4 = addBoolSelector(g, __tr2qs_ctx("Automatically resume when auto-accepted", "options"), KviOption_boolAutoResumeDccSendWhenAutoAccepted,
181 	    KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccSend));
182 
183 	g = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("Save Location", "options"));
184 
185 	addDirectorySelector(g, __tr2qs_ctx("Download folder:", "options"), KviOption_stringIncomingPath);
186 	addBoolSelector(g, __tr2qs_ctx("Sort saved files by nicknames (create subfolders)", "options"), KviOption_boolSortReceivedByDccFilesByNicks);
187 	addBoolSelector(g, __tr2qs_ctx("Guess save path from media type", "options"), KviOption_boolUseIncomingDccMediaTypeSavePath);
188 
189 	g = addGroupBox(0, 2, 0, 2, Qt::Horizontal, __tr2qs_ctx("On Download Completion", "options"));
190 
191 	addBoolSelector(g, __tr2qs_ctx("Notify completion in console", "options"), KviOption_boolNotifyDccSendSuccessInConsole);
192 	addBoolSelector(g, __tr2qs_ctx("Notify completion in notifier", "options"), KviOption_boolNotifyDccSendSuccessInNotifier);
193 	b = addBoolSelector(g, __tr2qs_ctx("Automatically clear transfer", "options"), KviOption_boolAutoCloseDccSendOnSuccess);
194 	mergeTip(b, __tr2qs_ctx("This option will cause successfully terminated transfers "
195 	                        "to be automatically removed from the transfer window.", "options"));
196 
197 	b1 = addBoolSelector(0, 3, 0, 3, __tr2qs_ctx("Open transfer window without focus", "options"), KviOption_boolCreateMinimizedDccSend);
198 	mergeTip(b1, __tr2qs_ctx("This option prevents the transfer window "
199 	                         "from opening and diverting application focus.<br>"
200 	                         "Enable this if you don't like the transfer window "
201 	                         "popping up while you're typing something in a channel.", "options"));
202 
203 	connect(b1, SIGNAL(toggled(bool)), b3, SLOT(setNotEnabled(bool)));
204 	connect(b2, SIGNAL(toggled(bool)), b4, SLOT(setEnabled(bool)));
205 
206 	addRowSpacer(0, 4, 0, 4);
207 }
208 
209 OptionsWidget_dccSendGeneral::~OptionsWidget_dccSendGeneral()
210     = default;
211 
OptionsWidget_dccSendAdvanced(QWidget * parent)212 OptionsWidget_dccSendAdvanced::OptionsWidget_dccSendAdvanced(QWidget * parent)
213     : KviOptionsWidget(parent)
214 {
215 	setObjectName("dccsend_advanced_options_widget");
216 	createLayout();
217 
218 	KviBoolSelector * b;
219 	KviTalGroupBox * g;
220 	KviUIntSelector * u;
221 
222 	g = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("Bug Compatibility", "options"));
223 
224 	b = addBoolSelector(g, __tr2qs_ctx("Send ACK for byte 0", "options"), KviOption_boolSendZeroAckInDccRecv);
225 	mergeTip(b, __tr2qs_ctx("This option causes KVIrc to send a zero-byte acknowledge to kick-start "
226 	                        "the DCC transfer with some buggy IRC clients.<br>"
227 	                        "Use it only if your DCC transfers stall just after establishing a connection without sending any data.", "options"));
228 
229 	b = addBoolSelector(g, __tr2qs_ctx("Accept RESUME requests with broken filename (mIRC file.ext)", "options"), KviOption_boolAcceptBrokenFileNameDccResumeRequests);
230 	mergeTip(b, __tr2qs_ctx("This option causes KVIrc to accept RESUME requests with invalid filenames.<br>"
231 	                        "Use it if KVIrc fails to accept RESUME requests from other clients (e.g. some versions of mIRC).", "options"));
232 
233 	b = addBoolSelector(g, __tr2qs_ctx("Accept RESUME requests with mismatched ports", "options"), KviOption_boolAcceptMismatchedPortDccResumeRequests);
234 	mergeTip(b, __tr2qs_ctx("This option causes KVIrc to accept RESUME requests with mismatched ports.<br>"
235 	                        "Use it if some router on the path between you and the receiver remaps the ports in DCC SEND "
236 	                        "but not in DCC RESUME requests.<br>Please note that this option may misbehave in certain usage "
237 	                        "patterns since KVIrc must differentiate between transfers only by looking at the filename. Be careful.", "options"));
238 
239 	b = addBoolSelector(g, __tr2qs_ctx("Replace spaces with underscores in outgoing filenames", "options"), KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores);
240 	mergeTip(b, __tr2qs_ctx("This option causes KVIrc to replace spaces with underscores in filenames "
241 	                        "for all the outgoing file transfers. This will fix filename handling with some buggy clients (e.g. some versions of mIRC).", "options"));
242 
243 	b = addBoolSelector(g, __tr2qs_ctx("Send 64-bit ACKs for files larger than 4GiB", "options"), KviOption_boolSend64BitAckInDccRecv);
244 	mergeTip(b, __tr2qs_ctx("This option causes KVIrc to send ACKs as 64-bit integers instead of 32-bit integers.<br>"
245 	                        "Use this to fix DCC RECEIVE transfers where the other client is using the mIRC ACK standard.", "options"));
246 
247 	g = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("Limits", "options"));
248 
249 	KviTalHBox * hb = new KviTalHBox(g);
250 
251 	b = addBoolSelector(hb, __tr2qs_ctx("Limit upload bandwidth to:", "options"), KviOption_boolLimitDccSendSpeed);
252 	u = addUIntSelector(hb, "", KviOption_uintMaxDccSendSpeed, 0, 0xffffff1, 1024, KVI_OPTION_BOOL(KviOption_boolLimitDccSendSpeed));
253 	u->setSuffix(" " + __tr2qs_ctx("bytes/sec", "options"));
254 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
255 
256 	hb = new KviTalHBox(g);
257 	b = addBoolSelector(hb, __tr2qs_ctx("Limit download bandwidth to:", "options"), KviOption_boolLimitDccRecvSpeed);
258 	u = addUIntSelector(hb, "", KviOption_uintMaxDccRecvSpeed, 0, 0xffffff1, 1024, KVI_OPTION_BOOL(KviOption_boolLimitDccRecvSpeed));
259 	u->setSuffix(" " + __tr2qs_ctx("bytes/sec", "options"));
260 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
261 
262 	u = addUIntSelector(g, __tr2qs_ctx("Maximum number of DCC transfers:", "options"), KviOption_uintMaxDccSendTransfers, 0, 1000, 10);
263 	mergeTip(u, __tr2qs_ctx("This is the maximum number of concurrent DCC transfers. "
264 	                        "KVIrc will refuse the requests when this limit is reached.", "options"));
265 
266 	g = addGroupBox(0, 2, 0, 2, Qt::Horizontal, __tr2qs_ctx("Tweaks", "options"));
267 
268 	b = addBoolSelector(g, __tr2qs_ctx("Use fast send (send ahead)", "options"), KviOption_boolUseFastDccSend);
269 	mergeTip(b, __tr2qs_ctx("The \"send ahead\" DCC method allows data to be sent faster by breaking "
270 	                        "some of the rules of the original DCC SEND protocol specification.<br>"
271 	                        "Most clients can handle this kind of optimisation so disable it only if you have problems.", "options"));
272 
273 	hb = new KviTalHBox(g);
274 
275 	b = addBoolSelector(hb, __tr2qs_ctx("Force idle step:", "options"), KviOption_boolDccSendForceIdleStep);
276 	mergeTip(b, __tr2qs_ctx("Enable this option when the DCC file transfers "
277 	                        "tend to block your computer by consuming too much CPU time. "
278 	                        "When this option is enabled the idle interval below will be "
279 	                        "forcibly inserted between each sent/received data packet.", "options"));
280 
281 	u = addUIntSelector(hb, "", KviOption_uintDccSendIdleStepInMSec, 1, 65536, 30, KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep));
282 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
283 	u->setSuffix(__tr2qs_ctx(" msec", "options"));
284 
285 	mergeTip(u, __tr2qs_ctx("This parameter controls the average delay between two packets sent or received.<br>"
286 	                        "A smaller interval will cause you to send data faster but will also "
287 	                        "add load to your CPU, disk and network interface.<br>"
288 	                        "Reasonable values are from 5 to 50 milliseconds.", "options"));
289 
290 	u = addUIntSelector(g, __tr2qs_ctx("Packet size:", "options"), KviOption_uintDccSendPacketSize, 16, 65536, 1024);
291 	u->setSuffix(__tr2qs_ctx(" bytes", "options"));
292 	mergeTip(u, __tr2qs_ctx("This parameter controls the packet size used for DCC SEND.<br>"
293 	                        "With bigger packets you will be probably send data faster, but "
294 	                        "you will also saturate your bandwidth and in some cases "
295 	                        "cause more disk activity.<br>"
296 	                        "Reasonable values are from 512 to 4096 bytes.", "options"));
297 
298 	addRowSpacer(0, 3, 0, 4);
299 }
300 
301 OptionsWidget_dccSendAdvanced::~OptionsWidget_dccSendAdvanced()
302     = default;
303 
OptionsWidget_dccChat(QWidget * parent)304 OptionsWidget_dccChat::OptionsWidget_dccChat(QWidget * parent)
305     : KviOptionsWidget(parent)
306 {
307 	setObjectName("dccchat_options_widget");
308 	createLayout();
309 
310 	KviBoolSelector * b1;
311 	KviBoolSelector * b2;
312 	KviTalGroupBox * g;
313 
314 	g = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("On Chat Request", "options"));
315 	addBoolSelector(g, __tr2qs_ctx("Automatically accept", "options"), KviOption_boolAutoAcceptDccChat);
316 
317 	b1 = addBoolSelector(g, __tr2qs_ctx("Open auto-accepted DCC chat windows without focus", "options"), KviOption_boolCreateMinimizedDccChatWhenAutoAccepted,
318 	    !KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat));
319 	mergeTip(b1, __tr2qs_ctx("This option prevents incoming "
320 	                         "auto-accepted DCC chat windows from diverting application focus.<br>"
321 	                         "Enable this if you don't like DCC chat windows "
322 	                         "popping up while you're typing something in a channel.", "options"));
323 
324 	b2 = addBoolSelector(0, 1, 0, 1, __tr2qs_ctx("Open DCC chat windows without focus", "options"), KviOption_boolCreateMinimizedDccChat);
325 	mergeTip(b2, __tr2qs_ctx("This option prevents incoming "
326 	                         "DCC chat windows from diverting application focus.<br>"
327 	                         "Enable this if you don't like DCC chat windows "
328 	                         "popping up while you're typing something in a channel.", "options"));
329 
330 	connect(b2, SIGNAL(toggled(bool)), b1, SLOT(setNotEnabled(bool)));
331 
332 #if(defined(COMPILE_ON_WINDOWS) || defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_MINGW))
333 	b2 = addBoolSelector(0, 2, 0, 2, __tr2qs_ctx("Flash system taskbar on new DCC chat message", "options"), KviOption_boolFlashDccChatWindowOnNewMessages);
334 	mergeTip(b2, __tr2qs_ctx("This option causes the system taskbar entry for KVIrc to flash when a new DCC chat message "
335 	                         "is received and the KVIrc window is not the active.", "options"));
336 #endif
337 	b2 = addBoolSelector(0, 3, 0, 3, __tr2qs_ctx("Popup notifier on new DCC chat message", "options"), KviOption_boolPopupNotifierOnNewDccChatMessages);
338 	mergeTip(b2, __tr2qs_ctx("This option causes a small notifier window to pop up "
339 	                         "in the low right corner of the screen when a new message is received "
340 	                         "and the KVIrc window is not active.", "options"));
341 
342 	addRowSpacer(0, 4, 0, 4);
343 }
344 
345 OptionsWidget_dccChat::~OptionsWidget_dccChat()
346     = default;
347 
OptionsWidget_dccVoice(QWidget * p)348 OptionsWidget_dccVoice::OptionsWidget_dccVoice(QWidget * p) : KviOptionsWidget(p)
349 {
350 	createLayout();
351 
352 	KviBoolSelector * b1;
353 	KviBoolSelector * b;
354 	KviTalGroupBox * g;
355 	KviUIntSelector * u;
356 
357 	b1 = addBoolSelector(0, 0, 0, 0, __tr2qs_ctx("Open DCC voice windows without focus", "options"), KviOption_boolCreateMinimizedDccVoice);
358 	mergeTip(b1, __tr2qs_ctx("This option prevents all incoming "
359 	                         "DCC voice windows from diverting application focus.<br>"
360 	                         "Enable this if you don't like DCC voice windows "
361 	                         "popping up while you're typing something in a channel.", "options"));
362 
363 	g = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("On Voice Request", "options"));
364 	b = addBoolSelector(g, __tr2qs_ctx("Automatically accept", "options"), KviOption_boolAutoAcceptDccVoice);
365 	b = addBoolSelector(g, __tr2qs_ctx("Open auto-accepted DCC voice windows without focus", "options"), KviOption_boolCreateMinimizedDccVoiceWhenAutoAccepted,
366 	    !KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoice));
367 	mergeTip(b, __tr2qs_ctx("This option prevents incoming "
368 	                        "auto-accepted DCC voice windows from diverting application focus.<br>"
369 	                        "Enable this if you don't like DCC voice windows "
370 	                        "popping up while you're typing something in a channel.", "options"));
371 
372 	connect(b1, SIGNAL(toggled(bool)), b, SLOT(setNotEnabled(bool)));
373 
374 	addBoolSelector(0, 2, 0, 2, __tr2qs_ctx("Force half-duplex mode on sound device", "options"), KviOption_boolDccVoiceForceHalfDuplex);
375 	addBoolSelector(0, 3, 0, 3, __tr2qs_ctx("Volume slider controls PCM, not Master", "options"), KviOption_boolDccVoiceVolumeSliderControlsPCM);
376 
377 	addStringSelector(0, 4, 0, 4, __tr2qs_ctx("Sound device:", "options"), KviOption_stringDccVoiceSoundDevice)->setMinimumLabelWidth(150);
378 	addStringSelector(0, 5, 0, 5, __tr2qs_ctx("Mixer device:", "options"), KviOption_stringDccVoiceMixerDevice)->setMinimumLabelWidth(150);
379 
380 	u = addUIntSelector(0, 6, 0, 6, __tr2qs_ctx("Pre-buffer size:", "options"), KviOption_uintDccVoicePreBufferSize, 2048, 65536, 32000);
381 	u->setSuffix(" bytes");
382 
383 	addRowSpacer(0, 7, 0, 7);
384 }
385 
386 OptionsWidget_dccVoice::~OptionsWidget_dccVoice()
387     = default;
388