1
Hacking on Amarok
2
-----------------
3
4
Please respect these guidelines when coding for Amarok, thanks!
5
6
* Where this document isn't clear, refer to Amarok code.
7
8
9
This C++ FAQ is a life saver in many situations, so you want to keep it handy:
10
11
  http://www.parashift.com/c++-faq-lite/
12
13
14
Formatting
15
----------
16
* Spaces, not tabs
17
* Indentation is 4 spaces
18
* Lines should be limited to 90 characters
19
* Spaces between brackets and argument functions
20
* For pointer and reference variable declarations put a space between the type
21
  and the * or & and no space before the variable name.
22
* For if, else, while and similar statements put the brackets on the next line,
23
  although brackets are not needed for single statements.
24
* Function and class definitions have their brackets on separate lines
25
* A function implementation's return type is on its own line.
26
* CamelCase.{cpp,h} style file names.
27
* Qt 4 includes a foreach keyword which makes it very easy to iterate over all
28
  elements of a container.
29
30
Example:
31
32
 | bool
33
 | MyClass::myMethod( QStringList list, const QString &name )
34
 | {
35
 |     if( list.isEmpty() )
36
 |         return false;
37
 |
38
 |     /*
39
 |       Define the temporary variable like this to restrict its scope
40
 |       when you do not need it outside the loop. Let the compiler
41
 |       optimise it.
42
 |      */
43
 |     foreach( const QString &string, list )
44
 |         debug() << "Current string is " << string << endl;
45
 | }
46
47
48
Using "astyle" for auto formatting
49
----------------------------------
50
The program astyle can be used to automatically format source code, which can
51
be useful for badly formatted 3rd party patches.
52
53
Use it like this to get (approximately) Amarok formatting style:
54
55
    "astyle -s4 -b -p -U -D -o source.cpp"
56
57
58
Class, Function & Variable Naming
59
---------------------------------
60
*Use CamelCase for everything.
61
*Local variables should start out with a lowercase letter.
62
*Class names are captialized
63
*Prefix class member variables with m_, ex. m_trackList.
64
*Prefix static member variables with s_, ex s_instance
65
*Functions are named in the Qt style. It's like Java's, without the "get" 
66
 prefix.
67
  *A getter is variable()
68
  *If it's a getter for a boolean, prefix with 'is', so isCondition()
69
  *A setter is setVariable( arg ).
70
71
72
Includes
73
--------
74
Header includes should be listed in the following order:
75
    - Own Header
76
    - Amarok includes
77
    - KDE includes
78
    - Qt includes
79
80
They should also be sorted alphabetically, for ease of locating them.  A small comment
81
if applicable is also helpful.
82
83
Includes in a header file should be kept to the absolute minimum, as to keep compile times
84
low. This can be achieved by using "forward declarations" instead of includes, like
85
"class QListView;" Forward declarations work for pointers and const references.
86
87
TIP:
88
Kate/KDevelop users can sort the headers automatically. Select the lines you want to sort,
89
then Tools -> Filter Selection Through Command -> "sort".
90
91
In vim the same can be achieved by marking the block, and then doing ":sort".
92
93
Example:
94
95
 | #include "MySuperWidget.h"
96
 |
97
 | #include "Amarok.h"
98
 | #include "Debug.h"
99
 | #include "Playlist.h"
100
 |
101
 | #include <KDialogBase>    //baseclass
102
 | #include <KPushButton>    //see function...
103
 |
104
 | #include <QGraphicsView>
105
 | #include <QWidget>
106
107
108
Comments
109
--------
110
Comment your code. Don't comment what the code does, comment on the purpose of the code. It's
111
good for others reading your code, and ultimately it's good for you too.
112
113
Comments are essential when adding a strange hack, like the following example:
114
115
 | /** Due to xine-lib, we have to make K3Process close all fds, otherwise we get "device is busy" messages
116
 |   * Used by AmarokProcIO and AmarokProcess, exploiting commSetupDoneC(), a virtual method that
117
 |   * happens to be called in the forked process
118
 |   * See bug #103750 for more information.
119
 |   */
120
 | class AmarokProcIO : public K3ProcIO 
121
 | {
122
 |     public:
123
 |     virtual int commSetupDoneC() {
124
 |         const int i = K3ProcIO::commSetupDoneC();
125
 |         Amarok::closeOpenFiles(K3ProcIO::out[0],K3ProcIO::in[0],K3ProcIO::err[0]);
126
 |         return i;
127
 |     }
128
 | };
129
130
131
For headers, use the Doxygen syntax. See: http://www.stack.nl/~dimitri/doxygen/
132
133
Example:
134
135
 | /**
136
 |  * Start playback.
137
 |  * @param offset Start playing at @p msec position.
138
 |  * @return True for success.
139
 |  */
140
 | virtual bool play( uint offset = 0 ) = 0;
141
142
143
Header Formatting
144
-----------------
145
General rules apply here.  Please keep header function definitions aligned nicely,
146
if possible.  It helps greatly when looking through the code.  Sorted methods,
147
either by name or by their function (ie, group all related methods together) is
148
great too. Access levels should be sorted in this order: public, protected, private.
149
150
151
 | #ifndef AMAROK_QUEUEMANAGER_H
152
 | #define AMAROK_QUEUEMANAGER_H
153
154
 | class QueueList : public K3ListView
155
 | {
156
 |         Q_OBJECT
157
 |
158
 |     public:
159
 |         Queuelist( QWidget *parent, const char *name = 0 );
160
 |         ~QueueList() {};
161
 |
162
 |     public slots:
163
 |         void    moveSelectedUp();
164
 |         void    moveSelectedDown();
165
 | };
166
167
#endif /* AMAROK_QUEUEMANAGER_H */
168
169
170
0 vs NULL
171
---------
172
The use of 0 to express a null pointer is preferred over the use of NULL.
173
0 is not a magic value, it's the defined value of the null pointer in C++.
174
NULL, on the other hand, is a preprocessor directive (#define) and not only is
175
it more typing than '0' but preprocessor directives are less elegant.
176
177
 |     SomeClass *instance = 0;
178
179
180
Const Correctness
181
-----------------
182
Try to keep your code const correct. Declare methods const if they don't mutate the object,
183
and use const variables. It improves safety, and also makes it easier to understand the code.
184
185
See: http://www.parashift.com/c++-faq-lite/const-correctness.html
186
187
188
Example:
189
190
 | bool
191
 | MyClass::isValidFile( const QString& path ) const
192
 | {
193
 |     const bool valid = QFile::exist( path );
194
 |
195
 |     return valid;
196
 | }
197
198
199
Debugging
200
---------
201
debug.h contains some handy functions for our debug console output.
202
Please use them instead of kDebug().
203
204
Usage:
205
206
 | #include "debug.h"
207
 |
208
 | debug()   << "Something is happening" << endl;
209
 | warning() << "Something bad may happen" << endl;
210
 | error()   << "Something bad did happen!" << endl;
211
212
Additionally, there are some macros for debugging functions:
213
214
DEBUG_BLOCK
215
DEBUG_FUNC_INFO
216
DEBUG_LINE_INFO
217
DEBUG_INDENT
218
DEBUG_UNINDENT
219
220
AMAROK_NOTIMPLEMENTED
221
AMAROK_DEPRECATED
222
223
threadweaver.h has two additional macros:
224
DEBUG_THREAD_FUNC_INFO outputs the memory address of the current QThread or 'none'
225
    if its the original GUI thread.
226
SHOULD_BE_GUI outputs a warning message if it occurs in a thread that isn't in
227
    the original "GUI Thread", otherwise it is silent. Useful for documenting
228
    functions and to prevent problems in the future.
229
230
231
Errors & Asserts
232
----------------
233
*Never use assert() or fatal(). There must be a better option than crashing a user's
234
application (its not uncommon for end-users to have debugging enabled).
235
236
*KMessageBox is fine to use to prompt the user, but do not use it to display errors
237
or informational messages. Instead, KDE::StatusBar has a few handy methods. Refer to
238
amarok/src/statusbar/statusBarBase.h
239
240
241
Commenting Out Code
242
-------------------
243
Don't keep commented out code. It just causes confusion and makes the source
244
harder to read. Remember, the last revision before your change is always
245
availabe in SVN. Hence no need for leaving cruft in the source.
246
247
Wrong:
248
 | myWidget->show();
249
 | //myWidget->rise(); //what is this good for?
250
251
Correct:
252
 | myWidget->show();
253
254
255
Tips & Tricks
256
-------------
257
A useful service is http://lxr.kde.org. Lxr is a cross reference of the entire
258
KDE SVN repository. You can for instance use it to search for example code
259
from other applications for a given KDElibs method.
260
261
Markey's .vimrc
262
---------------
263
264
let ruby_no_expensive = 1
265
syntax on
266
267
set shiftwidth=4
268
set tabstop=4
269
set expandtab
270
set hlsearch
271
set ruler
272
set smartindent
273
set nowrap
274
275
set ignorecase
276
set smartcase
277
278
set title
279
set showtabline=2  "Makes the status bar always show, also for just one tab
280
281
autocmd FileType ruby set shiftwidth=2 tabstop=2
282
283
Git and SVN aware prompt
284
----------------
285
The following prompt shows the current git branch if sitting in a git repository.
286
Random crap courtesy of shell colours.
287
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;33m\]`git branch 2>/dev/null|cut -f2 -d\* -s`\[\033[00m\]\$ '
288
289
This is an even more colorful configuration for .bashrc that displays the
290
current git branch if sitting in a git repository and the current SVN revision
291
if sitting in an SVN checkout.
292
svn_prompt() {
293
	SVNBRANCH=`svn info 2>/dev/null | grep Revision: | cut -f 2 -d " "`
294
	if [ -n "$SVNBRANCH" ]; then
295
		BRANCH=" (r$SVNBRANCH)";
296
	else
297
		BRANCH="";
298
	fi
299
    echo "$BRANCH"
300
}
301
export PS1='\[\e[0;32m\]\u@\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\]\[\033[01;33m\]`__git_ps1`\[\e[m\]\[\e[01;35m\]`svn_prompt`\[\e[m\]\[\033[00m\]  \[\e[1;32m\]\$ \[\e[m\]\[\e[1;37m\] '
302
303
Copyright
304
---------
305
To comply with the GPL, add your name, email address & the year to the top of any file
306
that you edit. If you bring in code or files from elsewhere, make sure its
307
GPL-compatible and to put the authors name, email & copyright year to the top of
308
those files.
309
310
Please note that it is not sufficient to write a pointer to the license (like a URL).
311
The complete license header needs to be written everytime.
312
313
314
Thanks, now have fun!
315
  -- the Amarok developers