* In C++03 and earlier, the sign of the modulo result is implementation
defined (this was fixed in C++11).
* Setting a negative time is not what we want here, so make sure we use
the proper value.
* The Install() and Update() versions that take a const char* array
now check whether a string looks like a path to a local package file.
If so, they use that file instead of interpreting the string as a
search string.
* Extend the repository hierarchy. There's now a LocalRepository base
class from which InstalledRepository and the new MiscLocalRepository
derive. The latter is instantiated once and collects all package files
specified by path.
* BFatalErrorException: Add commitTransactionResult property and
respective constructor. In case committing the transaction failed,
BPackageManager throws a BFatalErrorException with the result.
* BFatalErrorException::UserInteractionHandler: Pass
BCommitTransactionResult to ProgressTransactionCommitted().
* BDaemonClient: Move inner class BCommitTransactionResult to top level
and make it public.
* BCommitTransactionResult:
- Add a whole bunch of specific error code enum values. Such an error
code is now the primary error, as opposed to before where we would
mix status_t and enum value errors. There's a systemError property
of type status_t which may provide additional information, though
(depending on the primary error type).
- Remove the errorMessage property. Due to mapping all errors to the
specific error codes this is no longer necessary. Mixing such a
message with another error description is also not very helpful when
it comes to localization (still not supported, though).
- Add several properties (paths, strings, error codes) that serve as
arguments to the primary error and are used by FullErrorMessage().
- Add issues property, a list of instances of new class
BTransactionIssue. Those describe non-critical issues (e.g. failed
update of a settings file) that occurred in the process of
committing the transaction. Those issues should be presented to the
user by the package management program.
* Exception: Adjust to transport the BCommitTransactionResult
properties.
* CommitTransactionHandler, FsTransactions, Root, Volume: Adjust to
BCommitTransactionResult/Exception changes.
* CommitTransactionHandler: Now requires a BCommitTransactionResult to
which it adds the issues it encounters. The reply BMessage is no
longer needed, though.
* Volume: Refactor common code from the three methods that use
CommitTransactionHandler into new method _CommitTransaction.
Add GetPathOrName() and PathOrName() methods which try to get some kind
of usable path or at least a file name for the entry. Useful mainly for
debugging and error reporting cases.
We don't need to create a BNode from a BDirectory because BDirectory derives
from BNode! So use the BDirectory we already have as a BNode and get the
node_ref from it so we can pass it into WatchNode().
Sorry for the noise.
The logic was reversed accidentally in hrev47355
Rewrite the method to make more sense. If data is NULL return
B_BAD_VALUE right away. Otherwise set the status based on the first
operation, if that succeeds perform a second one, and return the
result.
Fixes CID 1222666
No functional change intended.
Focused on documented classes only.
* Update copyright information.
* whitespace fixes.
* pointer style
* Rename some variables, msg => message, form => what
* Need consistent variable names to make documentation easier,
allows us to use \copydoc or \copydetails instead of repeating
ourselves over and over again.
* Each BHttpAuthentication object is locked on all field accesses,
* They are owned by the BUrlContext and never deleted, so there is no
need for reference-counting them,
* The BUrlContext itself is now reference counted, and all BUrlRequests
hold a reference to it.
This makes sure using the BHttpAuthentication objects from requests is
thread-safe.
* Change the semantics of the iterators copy constructor and assignment
operator: they now return a new iterator for the same cookie jar (and
same url for the UrlIterator). They don't try to point to the same
position as the copied iterator. The only purpose of these is to write
code such as:
Iterator it = jar.GetIterator();
so having a full copy isn't that useful.
* The per-domain cookie lists are now protected with a read-write lock.
The iterators retain a read lock while they are handling cookies from
that list. They get a write lock when doing Remove. Adding a cookie to
the jar also gets the write lock for the matching list
* Fix a memory leak when adding a new domain-list to the jar failed
* Simplify the declaration of the PrivateHashMap type (it would be
even simpler if HashMap was a public API)
* The domain hashmap is now a SynchronizedHashMap. It is locked as long
as an Iterator or UrlIterator exists, which may be a problem as these
are public APIs. Writing safe iterators for an hashmap with concurrent
accesses is not easy, so the API could be modified to return a list of
domains and a list of cookies for a given domain or URL instead. This
would suit the intended uses just as well.
* The jar now store const cookies, so there is no need to lock them for
access/modification. Updating a cookie is done by replacing it with
another one in the jar (with the same domain and value). There is still
the problem of deleting a cookie while other threads may still access
it, this will be fixed by making cookies BReferenceable.
If you have the Desktop window open when you switch to spatial
mode this will now close the window. You aren't allowed to have
the Desktop open in 2 places symultaneously in spatial mode.
... in a few more cases.
If you are in spatial mode and you double-click on the Desktop folder
it activates the Desktop putting all other Tracker windows in the
background.
If you are in browser mode and you double-click on the Desktop folder
it opens the Desktop folder in the current window.
If you issue 'open ~/Desktop' from Terminal or if you have Expander set
to open the expanded folder and you expand something on the Desktop
it won't open the Desktop folder in its own window in either spatial or
browser mode.
This patch alters Trackers behavior to open the Desktop folder in its own
window in these cases when you are in browser mode.
One might argue (as a few have on IRC) that this behavior should also
happen in spatial mode, but, this patch does not alter the behavior of
spatial mode. In spatial mode opening the Desktop folder with
'open ~/Desktop' or extracting a zip file with Expander on the Desktop
simply activates the Desktop pushing all other Tracker windows into the
background state.
Fixes#10929
* Cookies sometimes come with the UTC timezone, or no tz info at all.
* No other timezone seems to be used
This allows better matching of cookies which would otherwise be kept
only as session cookies.
* An empty "expires" field results in a session cookie, rather than
rejecting the cookie altogether
* A page can set a cookie it is not allowed to access (for example in a
subdirectory of where the page is located). Separate IsValidForUrl and
_CanBeSetFromUrl to perform the appropriate checks in each case.
* Limit cookie path to 4096 characters. As a result of the previous
change, a page would be allowed to set a cookie with an aribrarily long
subpath, wasting disk space and RAM by growing hte cookie jar.
* Don't allow path with . or .. elements. These are a source of
confusion and are not needed.
* Reset the cookie fields when parsing failed. This does not matter when
using the cookie jar, but is useful when working directly with
BNetworkCookie.
strptime can return non-NULL values even if it only parsed part of the
string. This was sometimes making us use the wrong format. Now we try
all formats and checks how much of the string strptime managed to parse.
We stop when it has parsed a big enough part of it.
* BString::CopyInfo() takes length as second
parameter, not the end-offset. This bug didn't
have any effect, since BString clamps the length.
* ',' is a comma, ':' is a colon.
* When parsing "additionalData" in the loop for
name=value pairs, an empty name is not useful,
continue the loop early.
* "value" may have the length 0, accessing it
with value[0] would not lead to an access violation,
since it just reads the terminating zero (I think),
but it's nicer if the code makes it clear that
value being empty is considered.
* _H() was using a static buffer, in a heavily
multi-threaded situation. I don't think this was
healthy.
* Implement the proposed optimization of using
BString::LockBuffer(). Appending one char at a time
is really bad for peformance. The Base64 encoding/decoding
should really be rewritten as well for similar reasons.
These were getting out of sync and causing trouble, and they are easy to
compute from existing information.
Fixes some problems detected by the testsuite where the user/password or
the host would sometime disappear from the URL.
No functional changes intended.
* Updated copyright information.
* Reduced doxygen documentation down to a helpful summary
in a regular comment, the documentation has been moved into
the Haiku Book.
* Some parameter renaming for consistency and clarity.
* A few other style fixes.
With some testing, found that even with the second patch
provided in #10792, the behaviour is still inconsistent, so
reverting for now.
This reverts commit 273109e004.
* Use merge sort, which is a stable sort, instead of the qsort used in
BList::SortItems
* This allows setting two stops with the same offset to create a sharp
color change in a gradient. This trick is used to create stripe patterns
with css gradients in some web pages.
Fixes#10733.
* Nothing ever reads fTargetName in the scrollbar code, so remove the
field.
* Frees one reserved slot, and a little memory, as the target name was
copied with strdup.
* Don't intercept Enter key press in a window when there is default
button and another BControl focused.
* Current behavior was basically breaking every window using default
button. Even if there was a button focused (using Tab key), when Enter
was hit, default button handled the message, therefore instead of
i.e. 'Revert' 'Apply' was pressed.
* Fixes#10792.
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@gmail.com>
* This may be fine in media server where it lands in logs, but certainly
not when the code is run in applications.
* Helps with all media-related webkit tests.
* They crash app_server if you try to use them, which is not a good idea.
* we could clamp them to 0/255, but reporting the error to the user
seems better.
* The DataReceived hook gets a position argument, making it possible for
listeners to handle out-of-order data (from two range requests at
different positions, for example)
* Adjust HaikuDepot (only user of the API in our sources)
* Add a copy constructor to HTTPRequest that copies the relevant
parameters from an existing request. Makes it easy to repeat a request
with a different range. Could be useful for restarting downloads, or
paralellizing them.
* Add SetRangeStart, SetRangeEnd calls to HTTPRequest, no implementation
yet. I'm putting all the API changes in this commit as it needs to be
synced with a matching haikuwebkit release.
* All archs must update to HaikuWebkit 1.3.0. Previous versions are
broken by this.
These were acceptable in media kit log, but are only annoying now that
the AddOnManager is ran in applications. Moreover, these get to stdout
and make some WebKit tests fail.
* WebKit testsuite relies on the MIME types being correct, so when the
file doesn't have one, try to identify it.
* May be useful for other apps using FileRequest, anyway.
Create and use BLayoutUtils::AlignOnRect() to position the button label
in BControlLook::DrawLabel().
AlignOnRect(), unlike AlignInFrame(), provides the possibility to return
a rectangle with dimensions greater than the available size.
Add some comments above the methods in LayoutUtils that indicate such.
Also update copyright headers in LayoutUtils and ControlLook
* These classes were moved from Media Server, making the use of ports
and messages to communicate with the app irrelevant.
* Split in a separate commit to help git keep track of moved files.
Fixes#4893.
The media server tried to use node monitoring to dynamically add and
remove plug-ins, but it isn't that useful:
* When a plug-in is added, applications would have to query the media
server to get an up to date list of available formats. For example
MediaConvert populates its format menus on startup.
* When removing a plugin, if an app already had it loaded, there is not
much that can be done to keep it working.
* The list of plugins was not sorted by directories (user vs system
add-ons), so the directories were re-scanned to make sure user add-ons
were returned first, rendering the node monitoring less interesting.
Now, the format handling is done by each application. The node
monitoring is removed, instead the apps will scan the plugin directory
when first using the media kit classes. Restarting the application is
needed to update the media formats list.
This reverts a portion of hrev46580 concerning placement of a label on a button.
The label was draw too low on the button in some cases, notably in Keymap.
Restoring the old code for the icon-less case fixes the problem.
There still may be a problem drawing labels on buttons with icons, but, the code
should behave the same as it did in hrev46580 for that case, which is when
buttons with icons was introduced.
...when sending the whole view state over the link.
Also inherit the fill rule when pushing states (DrawState
copy constructor). A somewhat sloppy oversight, I must add.
* BView gets SetFillRule/FillRule methods. The fill rule is part of the
view state.
* The B_NONZERO rule is the default. This is what we implemented before.
* The B_EVEN_ODD rule is the other common possibility for this, and
we need to support it to help WebKit to render properly.
... instead of vertically. This actually swaps horizontal and vertical
so if you have a mouse with a fancy 2-axis scroll ball it will swap
the x and y coordinates. (untested)
* Libbe is not available when cross-building the *_bootstrap packages,
so no libnetwork could not be used either, which made building
anything network-related impossible.
* The only code in libnetwork that requires libbe is the notification,
so I moved that over to libbnetapi. Non-C++ applications can't use
the notification calls anyway, as their interface is C++-only.
* Change default spacing to B_BITMAP_SPACING. The BeBook does not document
what the default spacing is, and I have no BeOS install handy to check.
However, I believe that B_BITMAP_SPACING is what should be the default,
since it gives the best visible result for the common use-case.
In terms of implementation, there is no change, since spacing was ignored
until now and the behavior was that of B_BITMAP_SPACING. This change could
however break BeOS apps which assume B_CHAR_SPACING is the default and don't
set it on new when they need it. Sample code in the BeBook however shows
setting B_CHAR_SPACING on a newly created BFont.
* Implement B_STRING_SPACING to do something sensible. The BeBook documentation
is completely vague in what it is actually supposed to do. Given the
possibilities of FreeType, I am implementing it to enable the use of
kerning. Kerning optimizes the spacing between two glyphs, for example, it
would decrease the spacing between "T" and "e" in the string "Test" for
our default font. Untested.
* Unify asterisk style
* switch indentation style of FontList declaration
* Order FontList methods according to declaration
* Use named constants in default BFont constructor for spacing and encoding.
When Settings.ModuleName() returned NULL here we got a segmentation fault
trying to access the pointer.
I ran into this trying to load up a non-screensaver executable in ScreenSaver,
it crashed instead of doing the right thing and refusing to load.
Also, since we go to the trouble of saving this to a variable, we should actually use it.
* BSecureSocket::CertificateVerificationFailed() took a BCertificate
instance by value as parameter.
BCertificate deletes internal data in its destructor. Passing an
object by value creates a copy, so the copy attempted to delete
the internal data again during its destruction.
This caused mail_daemon to crash here when it came across a failed
certificate.
* Fix: pass BCertificate object as reference.
It actually looked better before. It completely depends
on the first and last letter of the text whether there is
a pixel too much on the left or right. On average, it
looks better with the offset, since the string width often
includes the spacing needed before the next glyph on the
right, while the string touches the bounding box on the left.
What should be changed is how tight everything is in general,
the selection box should simply extend more outward. But I
don't really feel like diving into that right now.
Either the offset was a workaround for some BeOS bug or
backwards compatibility (I know of at least a vertical off-by-one
text positioning on BeOS for backwards compatibility reasons), or
the Haiku (FreeType) text rendering simply differs slightly, which
can't be avoided. In any case, relevant here is what looks better.
Should fix#1319.
* The label might be truncated, in which case the entire width needs to be
redrawn when the menu field shrinks or grows.
* Invalidating the border in the parent looked a bit weird. Simplified.
This is useless, chunked support is mandatory in HTTP1.1, and it's not a
content-encoding, but a transfer-encoding, so accept-encoding wouldn't
help anyway.
* Use the ZlibDecompressor to decompress the data
* Advertise support in accept-encoding
This should make web browsing feel even faster on wesites that support
these compresion schemes. It also fixes some websites (www.ru,
rainloop.net, ...) that serve gzipped resources even to browser not
supporting it.
zlib can decompress both gzip and zlib formatted compressed streams. The
compression algorithm is the same, but the headers are different. The
format is autodetected from the data.
* This will be used to implement compressed http streams
* Remove the custom BDataOutput class, and use BDataIO instead, for
easier integration with existing code.
* ... instead of queuing it for the job thread. The advantage is that
the request will be handled immediately and clients won't have to wait
for transactions (which may even require user feedback) to finish. It
complicates Volume a bit, since there are now two threads that may
access it. The shared data have been moved to a State object which is
protected by a lock.
* For commit transaction requests check whether another package request
is already pending/in progress before queuing a job. Fail immediately,
if there is.
Fixes bug #10039.
Everything untested, but compiles, so it must work. The idea is to introduce
BAffineTransform additionally to the existing Origin and Scale properties of
BViews. One may use it in parallel or as an alternative. Painter in app_server
is not yet aware of the additional transformation. It is however already used
to transform drawing coordinates. It probably needs to work differently,
perhaps only in Painter and AGGTextRenderer.
* The transaction_type(.., ..., SOLVER_TRANSACTION_RPM_ONLY)
categorization of the transaction steps is incorrect since rpm
automatically replaces an older package version when a new one is
installed and thus such package removals would be omitted. Use a
simpler check instead.
* Omit the unnecessary explicit check whether a package really has to be
installed.
Thanks to Michael Schroeder @ SUSE for his help figuring this out.
... inside a selection. If you click outside a selection extend the
selection to include the new items as Tracker normally would and
then pop up the dialogs.
Works with control-click as well, same utility function used.
Fixes#10449
Create this utility method in Utilities.cpp and use it elsewhere tell if the
secondary mouse button is pressed or if it is emulated with a control-click.
When BPictures are created on the stack and go out of scope, they send a
AS_DELETE_PICTURE command to the ServerApp thread, and that command may be
processed sooner than the AS_VIEW_CLIP_TO_PICTURE command in the ServerWindow
thread, causing that command to no longer find a ServerPicture for the given
token. Apparently, the Be API leaves you the choice not to sync, in case for
example when you cache your BPictures and they remain valid. The default
value for "sync" is true. The BeBook could explain the situation better when
sync is needed and when not.
Make Cmd+Left and Cmd+Right work the same as Option+Left and
Option+Right, that is, they do word-wise navigation.
Make Option+Up go to beginning of paragraph and Option+Down go to end
of paragraph like Cmd+Left and Cmd+Right used to.
Unfortunately option shortcuts are currently eaten by S&T until #9431
gets fixed.
* Command+Left goes to beginning of line, ignoring softwrap
* Command+Right goes to the end of line, ignoring softwrap
* Home goes to beginning of line, accounting for softwrap
* End goes to end of line, accounting for softwrap
* Option+Left goes to previous word
* Option+Right goes to next word
* Command+Home and Command+Up go to beginning of document
* Command+End and Command+Down go to end of document
Shift with any of the above also selects the text.
This is similar to how the text editor Eddie works.
Instead of 1/10000 we now add 1/128 to the width to compensate for
rounding inaccuracies. Due to the limited float mantissa precision
(23 bit) the previous value would already have no effect for relatively
small widths (>= 128).
Fixes#10455.
Use the new SetIconForType() and SetSupportedTypes() versions and
request the MIME DB not to be updated. This changes the
update_mime_info() and mimeset (without -a/-A) behavior in that they
only modify the (application) file attributes, now. Addresses #10453.
Add SetSupportedTypes() and SetIcon[ForType]() versions with an
additional bool updateMimeDB parameter. If false, the method doesn't
update the MIME DB entries for the type.
When switching AppMetaMimeCreator from BMimeType to Database the
SetIcon[ForType]() calls with a BBitmap* ended up calling the vector
icon version with the icon_size as the data size argument, thus not only
not writing the bitmap icon attributes, but also clobbering the vector
icon attribute.
* BSolver/LibsolvSolver: Add FullSync() method. It uses libsolv's
SOLVER_DISTUPGRADE mode.
* BPackageManager: Add FullSync() using the new solver mode.
* pkgman: Add full-sync command.
The new command is similar to the update command without arguments, just
more aggressive, allowing downgrading or even removal of packages, to
match the state of the repositories. Just like "update" it doesn't work
properly yet.
We don't want this method to be exposed in the global namespace!
Also add a note about removing this signal-based solution when our
close() method can be interrupted in other ways.
thanks axel for watching!
Some websites set cookies expiring in the (not so) far future, after year 2038.
So, using time_t to store the cookie expiration date won't do. Use the
BDateTime class instead.
This makes goodsearch.com login work again (#10460).
Sometimes an HTTP request would get stuck in a call to connect(). While
our read() and write() implementations are interrupted if you close()
the socket, our connect() isn't. It would nonetheless abort the
connection process, and connect would stay blocked for quite a long
time.
When navigating away from a page, WebKit closes all pending connections,
and in our network backend this also means freeing the request object.
But, the destructor can't be called until the thread has stopped
running, to ensure proper cleanup.
Avoid the lockup in connect by sending a signal (SIGUSR1) to the thread
we want to unlock. This interrupts the syscall, and the thread exits
immediately.
Now that DrawingContext makes it possible to draw on a ServerBitmap
without the need for a BView, we can replay pictures on app_server side,
avoiding the cost of creating a BBitmap, offscreen BWindow, and BView
from the application side.
The offscreen drawing context gets the same state as the view it's
rendering the picture for, so font size, drawing mode, etc are used.
The implementation is still the suboptimal one, converting the BBitmap
to a BRegion, and using that for clipping. Changing that comes next.
* We should have the buildbots compile this to make sure it still works
* I had to split two ServerApp methods to a searate C++ file to link
them in libtestappserver.so
* some fixes related to the switch to PM and better hybrid support in
jam rules; moving of MIME stuff from registrar to storage kit, merge of
Locale Kit and ICU in libbe, and a few more.
* Modified the test_app_server hwinterface and rdef file so it is not a
background app, and the window isn't floating. Otherwise, hiding the
window would leave you without a way to recover it.
There seem to be a problem with the architecture, when building for an
x86_gcc2 system things are generated in libbe_test/x86, and then fail
with a lot of undefined references. Help welcome.
Adjust Database{Location} to only attempt to create a mimetype when
actually necessary, and fail otherwise if a writable version doesn't yet
exist. Correspondingly, adjust callers such as
DatabaseLocation::DeleteAttribute(). Fixes a problem where a caller asking
to perform a mimeset could fail early due to SetSupportedTypes() attempting
to update the read-only mime database entry supplied by a package, and
consequently most of the mimeset operations would be skipped.
Cookies date are always in GMT time. Using mktime wrongly converts them
as local time instead. This would lead to cookies expiring too early or
too late.
* Add some tracing, std::nothrow and null checks
* The HashString class doesn't like SetTo being called with a substring
of the current key, so use a copy of it instead.
Fixes#6667.
* Use pthread_once to initialize the SSL context once, in a thread-safe
way.
* Do not delete the BIO immediately when closing a connexion, instead
delay this to the destructor. This makes sure the protocol loop is done
running when we do that.
* Instead of creating a new BIO when we reconnect an already used
connection, create the BIO upfront, and reuse it with the new file
descriptor.
* Fix a memory leak: the SSL struct from OpenSSL was never freed, only
the BIO was.
Fixes#10414.
* Don't crash when opening a symlink, traverse it instead.
* Add a ".." entry to navigate to the parent folder
* Set the encoding to utf-8 in the MIME header, but this doesn't seem to
work.
* Instead of creating an OpenSSL context ofor each socket, use a global
one and initialize it lazily when the first SecureSocket is created
* Load the certificates from our certificate list so SSL certificates
sent by servers can be validated.
* Add a callback for signalling that certificate validation failed, the
default implementation proceeds with the connection anyway (to keep the
old behavior).
* Introduce BCertificate class, that provides some information about a
certificate. Currently it's only used by the callback mentionned above,
but it will be possible to get the leaf certificate for the connection
after it's established.
Review of the API and implementation is welcome, before I start making
use of this in HttpRequest and WebKit to allow the user to accept new
certificates.
Use standard error codes instead.
This allows using error code returned by the underlying functions
directly, and makes it possible to use strerror for debugging. So, we
can also remove StatusString() from the various *Request classes.
Variable length arrays of non-PODs are not part of the C++ standard, but
a GNU extension that never worked correctly. Instead, BStackOrHeap array
is used now, which makes sure that it's not too big for the stack, calls
all constructors and is valid C++.
Use the EPFL (Easily Parsed File Listing) format. This is one of the
formats that WebKit allows for directory listings, and it's easily
parsed and generated.
* Previously PE binaries would trigger the "incorrectly
executable" dialog. Now we get a special message for
B_LEGACY_EXECUTABLE and B_UNKNOWN_EXECUTABLE
* Legacy at the moment is a R3 x86 PE binary. This could
be extended to gcc2 binaries someday far, far, down the
road though
* The check for legacy is based on a PE flag I see
set on every R3 binary (that isn't set on dos ones)
* Unknown is something we know *is* an executable, but
can't do anything with (such as an MSDOS or Windows
application)
* No performance drops as we do the PE scan last
* Tested on x86 and x86_gcc2
Deleting the BIO while it's still waiting on a read() in another thread
will lead to a crash when the socket is eventually closed. Close the
socket first, so the read() is unlocked, then safely delete the BIO.
When calling Stop(), we expect the request thread to exit as soon as
possible. Closing the connection unlocks it from any blocking read() or
write(), avoiding some lockup situations.
* Add behavior constant B_POP_UP_BEHAVIOR which adds a pop-up marker
to the button (similar to that of BMenuField).
* Add methods [Set]PopUpMessage(). To set/get the the message that is
sent to the button's target when the pop-up marker is clicked.
The button frame is 3 pixels wide, but that includes one pixel that
actually belongs to the background, which is accounted for by
GetBackgroundInsets().
Removes the additional one pixel inset accidentally introduced earlier.
* Add methods SetFlat()/IsFlat(). A flat button doesn't draw its frame,
unless the mouse is hovering over it or it is otherwise activated.
* As a side effect this change also activates the hover glow that was
already implemented in BControlLook, but not activated in BButton.
* Fix off-by-one issue in Draw() and GetPreferredSize(). The label was
too close to the knob.
* GetPreferredSize(): Remove empty space to the right, when no label
and no icon was specified. Like with BCheckBox there's still two rows
of empty pixels above and below the knob.
* Draw(), GetPreferredSize(): Add icon support.