README.CodingStyle.md
1## SubtitleComposer Coding Style ##
2
3### Indentation
4
51 tab is used for indentation
6
7Tab, not spaces!
8
9
10### Declaring variables
11
12Declare each variable on a separate line
13
14Avoid short or meaningless names (e.g. "a", "rbarr", "nughdeget")
15
16Single character variable names are only okay for counters and temporaries, where the purpose of the variable is obvious
17
18Wait when declaring a variable until it is needed
19
20```C++
21 // Wrong
22 int a, b;
23 char *c, *d;
24
25 // Correct
26 int height;
27 int width;
28 char *nameOfThis;
29 char *nameOfThat;
30```
31
32Variables and functions start with a lower-case letter. Each consecutive word in a variable’s name starts with an upper-case letter
33
34Avoid abbreviations
35
36```C++
37 // Wrong
38 short Cntr;
39 char ITEM_DELIM = '\t';
40
41 // Correct
42 short counter;
43 char itemDelimiter = '\t';
44```
45
46Classes always start with an upper-case letter. Public classes start with a ‘Q’ (QRgb) followed by an upper case letter. Public functions most often start with a ‘q’ (qRgb).
47Acronyms are camel-cased (e.g. QXmlStreamReader, not QXMLStreamReader).
48
49
50### Whitespace
51
52Use blank lines to group statements together where suited
53Always use only one blank line
54Do not use space after a keyword
55Always use one single space before a curly brace:
56
57```C++
58 // Wrong
59 if (foo){
60 }
61
62 // Correct
63 if(foo) {
64 }
65```
66
67For pointers or references, always use a single space between the type and ‘*’ or ‘&’, but no space between the ‘*’ or ‘&’ and the variable name:
68
69```C++
70 // Correct
71 char *x;
72 const QString &myString;
73 const char * const y = "hello";
74```
75
76Surround binary operators with spaces
77No space after a cast
78Avoid C-style casts when possible
79
80```C++
81 // Wrong
82 char* blockOfMemory = (char*)malloc(data.size());
83
84 // Correct
85 char *blockOfMemory = reinterpret_cast<char *>(malloc(data.size()));
86```
87
88Do not put multiple statements on one line
89By extension, use a new line for the body of a control flow statement:
90
91```C++
92 // Wrong
93 if(foo) bar();
94
95 // Correct
96 if(foo)
97 bar();
98```
99
100
101### Braces
102
103Use attached braces: The opening brace goes on the same line as the start of the statement. If the closing brace is followed by another keyword, it goes into the same line as well:
104
105```C++
106 // Wrong
107 if(codec)
108 {
109 }
110 else
111 {
112 }
113
114 // Correct
115 if(codec) {
116 } else {
117 }
118```
119
120Exception: Function implementations and class declarations always have the left brace on the start of a line:
121
122```C++
123 // Correct
124 static void
125 foo(int g)
126 {
127 qDebug("foo: %i", g);
128 }
129
130 class Moo
131 {
132 };
133```
134
135Use curly braces only when the body of a conditional statement contains more than one line:
136
137```C++
138 // Wrong
139 if(address.isEmpty()) {
140 return false;
141 }
142
143 for(int i = 0; i < 10; ++i) {
144 qDebug("%i", i);
145 }
146
147 // Correct
148 if(address.isEmpty())
149 return false;
150
151 for(int i = 0; i < 10; ++i)
152 qDebug("%i", i);
153```
154
155Exception 1: Use braces also if the parent statement covers several lines / wraps:
156
157```C++
158 // Correct
159 if(address.isEmpty() || !isValid()
160 || !codec) {
161 return false;
162 }
163```
164
165Exception 2: Brace symmetry: Use braces also in if-then-else blocks where either the if-code or the else-code covers several lines:
166
167```C++
168 // Wrong
169 if(address.isEmpty())
170 return false;
171 else {
172 qDebug("%s", qPrintable(address));
173 ++it;
174 }
175
176 // Correct
177 if(address.isEmpty()) {
178 return false;
179 } else {
180 qDebug("%s", qPrintable(address));
181 ++it;
182 }
183
184 // Wrong
185 if(a)
186 if(b)
187 ...
188 else
189 ...
190 // Correct
191 if(a) {
192 if(b)
193 ...
194 else
195 ...
196 }
197```
198
199Use curly braces when the body of a conditional statement is empty
200
201```C++
202 // Wrong
203 while(a);
204
205 // Correct
206 while(a) {}
207```
208
209
210### Parentheses
211
212Use parentheses to group expressions:
213
214```C++
215 // Wrong
216 if(a && b || c)
217
218 // Correct
219 if((a && b) || c)
220
221 // Wrong
222 a + b & c
223
224 // Correct
225 (a + b) & c
226```
227
228
229### Switch statements
230
231The case labels are in the same column as the switch
232Every case must have a break (or return) statement at the end or a comment to indicate that there’s intentionally no break, unless another case follows immediately.
233
234```C++
235 // Correct
236 switch(myEnum) {
237 case Value1:
238 doSomething();
239 break;
240 case Value2:
241 case Value3:
242 doSomethingElse();
243 // fall through
244 default:
245 defaultHandling();
246 break;
247 }
248```
249
250Jump statements (break, continue, return, and goto)
251
252Do not put ‘else’ after jump statements:
253
254```C++
255 // Wrong
256 if(thisOrThat)
257 return;
258 else
259 somethingElse();
260
261 // Correct
262 if(thisOrThat)
263 return;
264 somethingElse();
265```
266
267Exception: If the code is inherently symmetrical, use of ‘else’ is allowed to visualize that symmetry
268
269
270### Line breaks
271
272Keep lines shorter than 100 characters; wrap if necessary
273Commas go at the end of wrapped lines; operators start at the beginning of the new lines. An operator at the end of the line is easy to miss if the editor is too narrow.
274
275```C++
276 // Wrong
277 if(longExpression +
278 otherLongExpression +
279 otherOtherLongExpression) {
280 }
281
282 // Correct
283 if(longExpression
284 + otherLongExpression
285 + otherOtherLongExpression) {
286 }
287```
288
289
290### Inheritance and the `virtual` keyword
291
292When reimplementing a virtual method, do not put the `virtual` keyword in the header file.
293On Qt5, annotate them with the [Q_DECL_OVERRIDE](http://qt-project.org/doc/qt-5.0/qtcore/qtglobal.html#Q_DECL_OVERRIDE) macro after the function declaration, just before the ‘;’ (or the ‘{’ ).
294
295
296### Qt Includes
297
298Do not use both the module and class name for Qt includes.
299
300```C++
301 // Correct
302 #include <QString>
303
304 // Wrong
305 #include <QtCore/QString>
306```
307
308
309### C++11 Lambdas
310
311You can use lambdas with the following restrictions:
312
313* You have to explicitly specify the return type (unless it's void), if the lambda contains more than a single expression.
314
315```C++
316 // Correct
317 []() -> QString {
318 Foo *foo = activeFoo();
319 return foo ? foo->displayName() : QString();
320 });
321
322 // Wrong
323 []() {
324 Foo *foo = activeFoo();
325 return foo ? foo->displayName() : QString();
326 });
327```
328
329* If you use static functions from the class that the lambda is located in, you have to explicitly capture this. Otherwise it does not compile with g++ 4.7 and earlier.
330```C++
331 // Correct
332 void
333 Foo::something()
334 {
335 ...
336 [this]() { Foo::someStaticFunction(); }
337 ...
338 }
339
340 // Wrong
341 void
342 Foo::something()
343 {
344 ...
345 []() { Foo::someStaticFunction(); }
346 ...
347 }
348```
349
350Format the lambda according to the following rules:
351
352* Always write parentheses for the parameter list, even if the function does not take parameters.
353
354```C++
355 // Correct
356 []() { doSomething(); }
357
358 // Wrong
359 [] { doSomething(); }
360```
361
362* Place the capture-list, parameter list, return type, and opening brace on the first line, the body indented on the following lines, and the closing brace on a new line.
363```C++
364 // Correct
365 []() -> bool {
366 something();
367 return isSomethingElse();
368 }
369
370 // Wrong
371 []() -> bool { something();
372 somethingElse(); }
373```
374
375* Place a closing parenthesis and semicolon of an enclosing function call on the same line as the closing brace of the lambda.
376```C++
377 // Correct
378 foo([]() {
379 something();
380 });
381```
382
383* If you are using a lambda in an 'if' statement, start the lambda on a new line, to avoid confusion between the opening brace for the lambda and the opening brace for the 'if' statement.
384```C++
385 // Correct
386 if(anyOf(fooList,
387 [](Foo foo) {
388 return foo.isGreat();
389 }) {
390 return;
391 }
392
393 // Correct - place the lambda completely on one line if it fits
394 if(foo([]() { return true; })) {
395 ...
396 }
397
398 // Wrong
399 if(anyOf(fooList, [](Foo foo) {
400 return foo.isGreat();
401 }) {
402 return;
403 }
404```
405
406
407### C++11 auto keyword
408
409You can use the auto keyword in the following cases. If in doubt (e.g. using auto could make the code less readable) do not use auto. Keep in mind that code is read much more often than written.
410
411* When it avoids repetition of a type in the same statement.
412```C++
413 // Correct
414 auto something = new MyCustomType;
415 auto keyEvent = static_cast<QKeyEvent *>(event);
416```
417
418* When assigning iterator types.
419```C++
420 // Correct
421 auto it = myList.const_iterator();
422```
423
424### C++11 initializer lists
425
426You should prefer initializer lists over adding the entries at runtime.
427
428```C++
429 // Wrong
430 auto myList = QStringList() << QLatin1String("FooThing") << QLatin1String("BarThing");
431 // Correct
432 QStringList myList{QStringLiteral("FooThing"), QStringLiteral("BarThing")};
433 QStringList myListWithSingleEntry{QStringLiteral("FooThing")};
434```
435
436### General exception
437
438When strictly following a rule makes your code look bad, feel free to break it
439
README.md
1## Subtitle Composer
2[![Linux Build](https://subtitlecomposer.smoothware.net/badge.php?p=job/kf5-qt5&os=suse&t=Linux+Build)](https://build.kde.org/job/Extragear/job/subtitlecomposer/)
3[![FreeBSD Build](https://subtitlecomposer.smoothware.net/badge.php?p=job/kf5-qt5&os=bsd&t=FreeBSD+Build)](https://build.kde.org/job/Extragear/job/subtitlecomposer/)
4[![TravisCI Build](https://img.shields.io/travis/com/maxrd2/subtitlecomposer/master.svg?label=Travis+Builds)](https://travis-ci.com/maxrd2/subtitlecomposer)
5[![Localization](https://d322cqt584bo4o.cloudfront.net/subtitlecomposer/localized.svg)](https://l10n.kde.org/stats/gui/trunk-kf5/po/subtitlecomposer.po/)
6
7An open source text-based subtitle editor that supports basic and advanced editing operations, aiming to become an improved version of Subtitle Workshop for every platform supported by Plasma Frameworks.
8
9[Homepage][homepage] - [Downloads][downloads]
10
11### FEATURES
12 - Open/Save **Text Subtitle Formats**
13 - SubRip/SRT, MicroDVD, SSA/ASS, MPlayer, TMPlayer and YouTube captions
14 - Open/OCR **Graphics Subtitle Formats**
15 - VobSub (.idx/.sub/.rar), BluRay/PGS (*.sup), formats supported by ffmpeg (DVD/Vob, DVB, XSUB, HDMV-PGS)
16 - **Demux Graphics/Text Subtitle Stream** from video file
17 - SRT, SSA/ASS, MOV text, MicroDVD, Graphic formats supported by ffmpeg (DVD/Vob, DVB, XSUB, HDMV-PGS)
18 - **Speech Recognition** from audio/video file using PocketSphinx
19 - Smart **language/text encoding** detection
20 - Live preview of subtitles in **integrated video player** (FFmpeg) w/ audio stream selection
21 - Preview/editing of subtitles on **audio waveform** w/ audio stream selection
22 - Quick and **easy subtitle sync**:
23 - Dragging several anchors/graftpoints and stretching timeline
24 - Time shifting and scaling, lines duration re-calculation, framerate conversion, etc.
25 - Joining and splitting of subtitle files
26 - Side by side subtitle **translations**
27 - Text **styles** (italic, bold, underline, stroke, color)
28 - **Spell** checking
29 - Detection of timing errors in subtitles
30 - **Scripting** (JavaScript, Python, Ruby and other languages supported by [Kross](http://techbase.kde.org/Development/Tutorials/Kross-Tutorial)).
31
32![Main Window](https://cdn.kde.org/screenshots/subtitlecomposer/mainwindow.png)
33
34### INSTALL
35Linux and Windows binaries downloadable from [downloads page][downloads]
36
37### BUILD
38Instructions for building from sources can be found on [wiki page][build instructions]
39
40### CONTRIBUTING
41Join friendly Matrix chat room [#subtitlecomposer][matrix-chat] and say hello or ask for help.
42
43Feedback and ideas on how to make Subtitle Composer better are welcome and appreciated!
44Let us know in [#subtitlecomposer chat][matrix-chat].
45
46Submit bug reports or feature requests to the [official issue tracker][bugs].
47
48Pull requests and patches are welcome. Please follow the [coding style][coding style].
49
50### LICENSE
51
52Subtitle Composer is released under [GNU General Public License v2.0](LICENSE)
53
54[homepage]: https://subtitlecomposer.kde.org/
55[matrix-chat]: https://webchat.kde.org/#/room/#subtitlecomposer:kde.org
56[bugs]: https://invent.kde.org/kde/subtitlecomposer/issues "Issue Tracker"
57[milestones]: https://invent.kde.org/kde/subtitlecomposer/-/milestones "Milestones"
58[coding style]: https://invent.kde.org/kde/subtitlecomposer/blob/master/README.CodingStyle.md "Coding Style"
59[build instructions]: https://invent.kde.org/kde/subtitlecomposer/wikis/Building-from-sources "Build Instructions"
60[downloads]: https://subtitlecomposer.kde.org/download.html