summaryrefslogtreecommitdiffstats
path: root/src/widgets
Commit message (Collapse)AuthorAgeFilesLines
* Merge "Merge remote-tracking branch 'origin/5.3' into 5.4" into refs/staging/5.4Oswald Buddenhagen2014-10-296-4/+14
|\
| * Merge remote-tracking branch 'origin/5.3' into 5.4Oswald Buddenhagen2014-10-286-4/+14
| |\ | | | | | | | | | Change-Id: I224e44a9df314b9a99d33148b6cf400fcbc9de8e
| | * Doc: Don't show a description for omitted SH_ComboBox_UseNativePopup enum itemAlexander Volkov2014-10-282-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | \omitvalue does not allow a description of an enum item, so move the description as a comment to the enum declaration. Change-Id: I4192b16e41b704cbad66c0eeafcb141087d2ba65 Reviewed-by: Martin Smith <martin.smith@digia.com>
| | * OS X: Fix broken 2x menu icon when style sheet is appliedMihailNaydenov2014-10-281-2/+2
| | | | | | | | | | | | | | | | | | | | | Task-number: QTBUG-41623 Change-Id: I4e0640a7739d0ce4f8758dd5d8d17882a6947467 Reviewed-by: Alessandro Portale <alessandro.portale@digia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
| | * Compile fix for QT_NO_IM in QtWidgetsSteffen Imhof2014-10-283-1/+10
| | | | | | | | | | | | | | | | | | | | | Added some #ifdef guards around usages of composeMode(). Change-Id: If2f2d3cae21b270933b38ea67dcc885f5871785f Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
| | * Move animation-related header out of QT_NO_IM #ifndef.Steffen Imhof2014-10-281-1/+1
| | | | | | | | | | | | | | | Change-Id: I7f0bfed4ff9a608575cf6795016b2fa134fd273f Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
* | | Fix QWidget::scroll during paintingAllan Sandfeld Jensen2014-10-291-1/+1
|/ / | | | | | | | | | | | | | | | | | | Calling scroll during painting fails in cases where the scroll is attempted accelerated. This is easily fixed by not using accelerated scrolling during painting. Task-number: QTBUG-41615 Change-Id: I38d2428d5679c242f13d53793a3dc3b8e01b538f Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
* | Doc: Fix method names for QFileSystemModelAlexander Volkov2014-10-281-1/+1
| | | | | | | | | | | | | | | | | | There are no methods called name() and path(), replace them by fileName() and filePath(). Task-number: QTBUG-41881 Change-Id: I001a8ead197327fac69e69d94230587ddb1a4692 Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com>
* | Check geometry correctly when replaying popup mouse events.Friedemann Kleint2014-10-281-8/+13
| | | | | | | | | | | | | | Task-number: QTBUG-41869 Task-number: QTBUG-39313 Change-Id: I2b59f5db6f0ae4007b1a3b58a79eed958e662272 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* | QMacStyle: Remove code depending depending on OS X 10.6 and olderGabriel de Dietrich2014-10-272-121/+36
| | | | | | | | | | | | | | Snow Leopard is unsupported from 5.4.0. Change-Id: I0c49a8353d5dc38169ab9679a986c35ab2df8d2f Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | QMacStyle: Refactor painter offset into drawNSViewInRect()Gabriel de Dietrich2014-10-272-39/+40
| | | | | | | | | | Change-Id: I05067ee400f0b776b0f0418ee1c5fbd45126c29e Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | QGtkStyle: fix segfault after re-creating QAppJ-P Nurmi2014-10-271-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | QGtkStylePrivate::setupGtkWidget() cannot use a local static variable for the container, but it must insert it to the GTK widget map together with all other GTK widgets. The container is destructed as a GtkWindow child in the Qt post routine QGtkStylePrivate::destroyWidgetMap(). Task-number: QTBUG-41145 Change-Id: If1fda372ed1227edc779fa4951cbd6fbf6038499 Reviewed-by: Andy Shaw <andy.shaw@digia.com> Reviewed-by: Dmitry Shachnev <mitya57@gmail.com> Reviewed-by: Jens Bache-Wiig <jensbw@gmail.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
* | QSwipeGestureRecognizer: Prevent cancel in startup-phase.Friedemann Kleint2014-10-272-10/+23
| | | | | | | | | | | | | | | | | | | | Replace the boolean 'started' member by an enumeration which indicates the startup phase. While in that phase, do not cancel when pressed points are detected for fewer than 3 touch points. Task-number: QTBUG-15768 Change-Id: Ic57b19e3002392fb632f551f615d80ada9831d34 Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
* | Doc: Include QtWidgets instead of QtGuiAlexander Volkov2014-10-271-1/+1
| | | | | | | | | | Change-Id: Ib7f3183efd446abb7cc191f33128b4e230ee372c Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
* | Android: Keyboard doesn't hide from done buttonSamuel Nevala2014-10-251-0/+7
| | | | | | | | | | | | | | | | | | | | QLineEdit commits and hides QInputMethod on enter key press. When Qt::ImhMultiLine input method hint is set, virtual keyboard is not hidden. Task-number: QTBUG-37850 Change-Id: I018351caa18bd2116665771e5f024a57182a01b9 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
* | Doc: Fix CustomStyle snippetAlexander Volkov2014-10-245-4/+5
| | | | | | | | | | | | | | | | | | | | Add missing semicolon, include QtWidgets instead of QtGui and use cast for a const pointer because the example with casting relates to the code above where 'widget' is const. Task-number: QTBUG-31736 Change-Id: I5cb6d33ec692deaf41e9a1be9e36e752a8da8739 Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com>
* | QGraphicsScene: stabilize stacking order of toplevel itemsaavit2014-10-241-1/+1
| | | | | | | | | | | | | | | | | | Removing and adding toplevel items could result in invalid stacking order (not corresponding to insertion order). Task-number: QTBUG-19316 Change-Id: Ia8646784a2181cfa936b101e2adaf7e7e73bb83d Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
* | Fix rubberband selection in rotated GraphicsViewaavit2014-10-241-1/+1
| | | | | | | | | | | | | | | | | | | | Selection rectangle was incorrectly mapped to scene space when the view was rotated. It became a rotated rectangle instead of the correct polygon (rhombus). Task-number: QTBUG-42008 Change-Id: Ib7b366bec7e1f83109e03c434268ad6897138f30 Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
* | QStyleSheetStyle: Don't interfere with QFontDialogPierre Rossi2014-10-242-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | The sample lineedit in Qt's own font dialog shouldn't have its font affected by stylesheets. Not only does this hampers the ability to preview the font, it actually overrides the font selection as that one is taken directly from the widget. Task-number: QTBUG-41513 Change-Id: I11d0bef8c7bf7bdae4cc08b6b9276d0fc14a75fb Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
* | Correctly update QComboBox appearance on editable changeEskil Abrahamsen Blomfeldt2014-10-242-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The updateDelegate() function checks isEditable() which in turn checks if d->lineEdit != 0, so we need to make the call after the lineEdit has actually been set/unset, otherwise the change to the delegate will not come until the next time you update the delegate. [ChangeLog][QComboBox] Fixed updating appearance of popup menu when changing the editable state of the combo box. Change-Id: Ib32f36cabd53c2c30d6256484a1eae131419960a Task-number: QTBUG-33537 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
* | Item view: Update item positions when delegate changesEskil Abrahamsen Blomfeldt2014-10-241-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In QComboBox, when you set editable to true on the QComboBox, the delegates will change from QComboBoxMenuDelegate to QComboBoxDelegate. In some styles, such as Fusion, the size of the delegates will be different. So when the delegate is updated, we need to redo the list view layout, otherwise the items will be positioned based on the size of the old delegates, but the popup for the combo box will be sized for the new. This caused the popup to be too small for its items and display a scroll bar. [ChangeLog][QComboBox] Fixed positions of items when QComboBox is set as editable in Fusion style. Change-Id: Ia43ef96efbeee4d6d596c0674bf3898ef94f89a1 Task-number: QTBUG-33537 Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
* | QMainWindow: respect the maximum size of the central widgetPaul Olav Tvete2014-10-241-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | Make sure the dock widgets get the available space when the central widget cannot expand any more. [ChangeLog][QtWidgets][QMainWindow] Dock widgets will now be resized properly when the central widget has a fixed size. Task-number: QTBUG-40410 Change-Id: Id06c07b79aa3102aa41212fa2c621f5fa426fe02 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
* | Doc: warn about preserving input method hintsPaul Olav Tvete2014-10-241-0/+4
| | | | | | | | | | | | Task-number: QTBUG-41252 Change-Id: I8ea2094c440b3c78b4bc78a69a5f6b18533e4927 Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com>
* | QSwipeGestureRecognizer: Fix gesture cancel on direction change.Friedemann Kleint2014-10-231-2/+2
| | | | | | | | | | | | | | Task-number: QTBUG-12736 Change-Id: I6d8d09843b45df17cb9158070f63b3397c5b4c07 Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
* | Fix styled vertical dockwidget title cut off bug and elide text if longMarko Kangas2014-10-231-4/+6
| | | | | | | | | | | | | | | | Change common stylesheet to elide text correctly for both direction. Change-Id: I045f6f74733ca8fa67b3e4fbb9d3845a1bea777d Task-number: QTBUG-41466 Reviewed-by: Jens Bache-Wiig <jensbw@gmail.com>
* | Adjust the layout if a QGraphicsWidget is explicitly hiddenJan Arve Saether2014-10-233-0/+28
| | | | | | | | | | | | | | | | | | Since layout items can now be hidden, this also makes sure we respect the QSizePolicy::retainSizeWhenHidden Task-number: QTBUG-20132 Change-Id: Iab59fc9b61d4ca1bb2208c479a027da6eb0283a9 Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
* | Fix title font of Vista-style wizards.Friedemann Kleint2014-10-231-4/+1
| | | | | | | | | | | | | | | | Reverse invalid check. Task-number: QTBUG-41878 Change-Id: I05015407e5cfad94aca65594962b897a1d0a0cbd Reviewed-by: Alessandro Portale <alessandro.portale@digia.com>
* | Fix QWidget::mapTo/FromGlobal() when embedded in QGraphicsView.Friedemann Kleint2014-10-231-0/+22
| | | | | | | | | | | | | | | | | | | | Map the positions via QGraphicsScene and the first QGraphicsView (as is done in existing code). Fall back to the previous code path when no QGraphicsView exists, which is hit in the tests. Change-Id: I0754765d05cded6bc1b64045f2513fef8afde337 Task-number: QTBUG-41135 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
* | Doc: Fix obsoleteness of some QStyle::PixelMetric enum itemsAlexander Volkov2014-10-221-6/+6
| | | | | | | | | | | | | | | | | | | | The enum items PM_ScrollView_ScrollBarSpacing, PM_ScrollView_ScrollBarOverlap and PM_SubMenuOverlap were mistakenly put together with obsolete enum items. Move them up to fix it. Change-Id: I90bd3a8ab68c99db27134d976fe69df56c9af2b8 Reviewed-by: Sean Harmer <sean.harmer@kdab.com> Reviewed-by: Martin Smith <martin.smith@digia.com>
* | Windows XP style: Fix size calculation of QScrollBar's grip.Friedemann Kleint2014-10-223-37/+17
| | | | | | | | | | | | | | | | | | Factor out function to calculate the geometry for the styles >= XP. Task-number: QTBUG-41944 Task-number: QTBUG-40277 Change-Id: Ifad1519b99fd587158c790dd241cb3e4bac3bfc3 Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
* | Respect contents margins when calculating the size hintLars Knoll2014-10-221-0/+3
| | | | | | | | | | | | | | | | | | | | | | Without this part of the calendar widget get cut off when put in a layout and the contentsMargins are non zero. Task-number: QTBUG-40352 Change-Id: I9ce90476c59c270d92e876a5dc81ea8ce325848c Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com> Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
* | Respect minimum size of heightForWidth layoutsPaul Olav Tvete2014-10-221-9/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since we cannot support heightForWidth constraints on toplevel windows, it is impossible to solve this perfectly: if the window is resizable at all, the user will be able to resize it too small. Our old solution was just to give up and allow completely free resizing, even down to 0x0. This makes very little sense. It is clearly better to use the minimum size that we have already computed, even though it is not perfect. This reverts a behavior change introduced in commit 36e9516f85fbb9c9a236f5ca034d5a0126d86c12 (September 9th, 2002) [ChangeLog][QtWidgets][QLayout] Widgets and dialogs containing layouts with heightForWidth (such as a label with word wrap) will no longer get a minimum size of 0x0. Task-number: QTBUG-37673 Change-Id: If26b7ef9c80edbf9d54c6519b36646df408b7652 Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
* | Fix helper function call in QWindowsVistaStyle::pixelMetric().Friedemann Kleint2014-10-221-1/+1
| | | | | | | | | | | | | | | | Task-number: QTBUG-41944 Task-number: QTBUG-40277 Change-Id: I1da9ffddce8edfcaa87d27058ed73ac7ec63d081 Reviewed-by: Adam Light <aclight@gmail.com> Reviewed-by: Alessandro Portale <alessandro.portale@digia.com>
* | Windows: Implement Qt::WA_ShowWithoutActivating.Friedemann Kleint2014-10-221-2/+0
| | | | | | | | | | | | | | | | | | | | Set dynamic property for all platforms and query it in QWindowsWindow::show_sys(). Task-number: QTBUG-19194 Task-number: QTBUG-34504 Change-Id: I4199a2ed835d3de928405d470a81c54da93cc768 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
* | Fix height of combo popup when the list view has non-zero spacing.Friedemann Kleint2014-10-222-5/+23
| | | | | | | | | | | | | | | | | | | | | | | | QListView::spacing() is the space around the item (layout margin), so the effective spacing is twice as big. This differs conceptionally from QTableView, which has a spacing of 1 and a line on top/bottom. Split up QComboBoxPrivateContainer::spacing() into functions return spacing and top/bottom margins to reflect this. Task-number: QTBUG-37865 Change-Id: I1ff812e7856e00a53f1119ef3304956cbb7cbfca Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
* | Produce more correct clip path for QGraphicsShapeItemLars Knoll2014-10-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | If no pen is set on the item, we can completely ignore the pen for the creation of the items shape. This both speeds up the creation of the shape and applying it as a clip mask as well as creating more correct results. Task-number: QTBUG-32846 Change-Id: I5f6f690256c71309713d8f746e67599af3088dd7 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* | OS X: Retina displays and blurry QToolButtonTimur Pocheptsov2014-10-211-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | Checkable QToolButton has a special pixmap in the background, painted with a 'smooth pixmaps' hint. This hint also affects how an icon on a toolbutton itself is painted later. The difference can be quite visible on a Retina display, so this patch makes the toolbutton's image always look the same in checked/unchecked state. Task-number: QTBUG-35162 Change-Id: I2adc8006371fa10d89d4b77da6b3aa168aa5abc8 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | Set correct transient parent in q_createNativeChildrenAndSetParent().Friedemann Kleint2014-10-211-5/+5
| | | | | | | | | | | | | | | | | | | | | | Fix warning: void QWindow::setTransientParent(QWindow*) ... must be a top level window. which occurred for example when parenting a QMenu onto a native child widget. Task-number: QTBUG-41898 Change-Id: Icc25fb2108bd68b2d9c0e551949b90fc7a82d358 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
* | Always report focusObjectChanged on QWidget::clearFocus()Tor Arne Vestbø2014-10-201-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | The focusObject() of a QWidgetWindow is based on the focusWidget() of the top level widget of the window, which is resolved through the focus_child chain of the widget. This is not the same thing as the focusWidget of the application. The hasFocus() function of a QWidget queries the latter, so we can't put the focusObjectChanged signal inside hasFocus() when we unconditionally clear the focus_child chain (and hence the focusObject) earlier in the function. Change-Id: Iae39da5d6031d22b21e9dc9f18e5fe6e6fd11a5c Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
* | Clear specific QWindow::focusObject() on QWindowPrivate::clearFocusObject()Tor Arne Vestbø2014-10-201-2/+4
| | | | | | | | | | | | | | | | | | | | The focusObject of a QWidgetWindow is the focusWidget() of the top level widget, so when clearing the focus object of the window we should clear focus of the same focusWidget, not the application-wide focus widget, which may live in another window. Change-Id: Ib9162418865c225e23aac7987e119b3b651983eb Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
* | Widgets: only update IM if the widget is the current focus objectRichard Moe Gustavsen2014-10-191-4/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QInputMethod works on focusObject, not focusWidget. These two are not always the same, and sometimes the focusObject is also NULL. In either case, we should not tell QInputMethod to commit, reset or otherwise emit signals based on the internal state of widgets that are not the focus object. This led to a crash on iOS, since we got a call to cursorRectangleChanged when focus object was NULL, which the code didn't (and shouldn't need to) take into account. Change-Id: I54e40d7ec35210ba6599a78c5a8c7f982a1c3dbb Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
* | QSizePolicy: remind to mark as Q_PRIMITIVE_TYPE in Qt 6Marc Mutz2014-10-191-0/+4
| | | | | | | | | | Change-Id: I1f18b4cd99f37aadf199e70d3acade9c8f5f9799 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Merge "Merge remote-tracking branch 'origin/5.3' into 5.4" into refs/staging/5.4Gabriel de Dietrich2014-10-183-20/+45
|\ \
| * | Merge remote-tracking branch 'origin/5.3' into 5.4Frederik Gladhorn2014-10-143-20/+45
| |\| | | | | | | | | | Change-Id: Ic01820f2390e419a5b286643e7351e85ae032473
| | * QMacStyle: Fix QPushButton with menu appearance on 10.10Gabriel de Dietrich2014-10-132-16/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As usual, this includes small and mini control sizes. Flat and oversized buttons will fall back to the HITheme rendering for now. Task-number: QTBUG-40833 Change-Id: I08d67c48b2e72681af4dc4a37ea498f7aac1dca0 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
| | * QAbstractItemView: fix CTRL+A select all behaviorMaximilian Hrabowski2014-10-131-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The check for Qt::Key_A to handle selectAll was changed to directly compare to QKeySequence::SelectAll as this will only match Ctrl. The former implementation also triggered when e.g. Shift was pressed. Added a check that selectAll is only called when selection is not disabled, i.e. selectionMode=NoSelection. Added a unit test for selectAll(). Task-number: QTBUG-26687 Change-Id: I721e7ab590b55d7d754b3b74ef01756fa5aa1315 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
| | * QMacStyle: save context state before changing to avoid crashDyami Caliri2014-10-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qt_drawFocusRingOnPath was saving the graphics state after setting a new context. This leads to zombie NSBitmapGraphicsContext access with QFileDialog. Task-number: QTBUG-41879 Change-Id: I7fc7d959d2b0f01cb3491d639023083f1b46d175 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | | QMacStyle: Fix QSlider appearance on YosemiteGabriel de Dietrich2014-10-182-10/+142
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | First, we adjust the min and max positions, which HITheme has been unable to render properly for years. This involves separating the knob and track rendering. Also, on Yosemite, the tickmarks-less slider shows a blue progress fill in the track, on the knob's left side. Finaly, and this is valid for all versions, the tickmarks are being drawn before the knob (or the whole slider for OS X versions before 10.10) Change-Id: I6fce2e298a80858a18fd9fe1e799b65265a8aefd Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | | QMacStyle: Add optional block parameter to drawNSViewInRect()Gabriel de Dietrich2014-10-182-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | In some cases we want to do something different than just calling - [NSView drawRect:]. Change-Id: I7db704daa39611f33f270b0192c4301de62ec1bf Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
* | | Avoid breaking BC with new virtuals in QOpenGLPaintDeviceLaszlo Agocs2014-10-161-11/+22
| | | | | | | | | | | | | | | | | | Task-number: QTBUG-41046 Change-Id: Iab628d2d6811d528e2cc513b6f8a74baa628541d Reviewed-by: Gunnar Sletta <gunnar@sletta.org>