summaryrefslogtreecommitdiffstats
path: root/kdeui/kbuttonbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeui/kbuttonbox.cpp')
-rw-r--r--kdeui/kbuttonbox.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/kdeui/kbuttonbox.cpp b/kdeui/kbuttonbox.cpp
new file mode 100644
index 000000000..eab9fa072
--- /dev/null
+++ b/kdeui/kbuttonbox.cpp
@@ -0,0 +1,377 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Mario Weilguni (mweilguni@sime.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/*
+ * KButtonBox class
+ *
+ * A container widget for buttons. Uses Qt layout control to place the
+ * buttons, can handle both vertical and horizontal button placement.
+*
+ * HISTORY
+ *
+ * 05/11/2004 Andrew Coles <andrew_coles@yahoo.co.uk>
+ * Now uses QPtrListIterators instead of indexing through data->buttons
+ * Item.button and data are now const pointers, set in the relevant constructors
+ *
+ * 03/08/2000 Mario Weilguni <mweilguni@kde.org>
+ * Removed all those long outdated Motif stuff
+ * Improved and clarified some if conditions (easier to understand)
+ *
+ * 11/13/98 Reginald Stadlbauer <reggie@kde.org>
+ * Now in Qt 1.4x motif default buttons have no extra width/height anymore.
+ * So the KButtonBox doesn't add this width/height to default buttons anymore
+ * which makes the buttons look better.
+ *
+ * 01/17/98 Mario Weilguni <mweilguni@sime.com>
+ * Fixed a bug in sizeHint()
+ * Improved the handling of Motif default buttons
+ *
+ * 01/09/98 Mario Weilguni <mweilguni@sime.com>
+ * The last button was to far right away from the right/bottom border.
+ * Fixed this. Removed old code. Buttons get now a minimum width.
+ * Programmer may now override minimum width and height of a button.
+ *
+ */
+
+#include "kbuttonbox.moc"
+#include <kglobalsettings.h>
+#include <kguiitem.h>
+#include <kpushbutton.h>
+#include <qptrlist.h>
+#include <assert.h>
+
+#define minButtonWidth 50
+
+class KButtonBox::Item {
+public:
+ KPushButton* const button;
+ bool noexpand;
+ unsigned short stretch;
+ unsigned short actual_size;
+
+ Item(KPushButton* const _button) : button(_button) {}
+};
+
+template class QPtrList<KButtonBox::Item>;
+
+class KButtonBoxPrivate {
+public:
+ unsigned short border;
+ unsigned short autoborder;
+ unsigned short orientation;
+ bool activated;
+ QPtrList<KButtonBox::Item> buttons;
+};
+
+KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation,
+ int border, int autoborder)
+ : QWidget(parent), data(new KButtonBoxPrivate)
+{
+ assert(data);
+
+ data->orientation = _orientation;
+ data->border = border;
+ data->autoborder = autoborder < 0 ? border : autoborder;
+ data->buttons.setAutoDelete(true);
+}
+
+KButtonBox::~KButtonBox() {
+ delete data;
+}
+
+QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) {
+ Item* const item = new Item(new KPushButton(text, this));
+
+ item->noexpand = noexpand;
+ data->buttons.append(item);
+ item->button->adjustSize();
+
+ this->updateGeometry();
+
+ return item->button;
+}
+
+QPushButton *KButtonBox::addButton(const KGuiItem& guiitem, bool noexpand) {
+ Item* const item = new Item(new KPushButton(guiitem, this));
+
+ item->noexpand = noexpand;
+ data->buttons.append(item);
+ item->button->adjustSize();
+
+ this->updateGeometry();
+
+ return item->button;
+}
+
+ QPushButton *
+KButtonBox::addButton(
+ const QString & text,
+ QObject * receiver,
+ const char * slot,
+ bool noexpand
+)
+{
+ QPushButton * pb = addButton(text, noexpand);
+
+ if ((0 != receiver) && (0 != slot))
+ QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
+
+ return pb;
+}
+
+ QPushButton *
+KButtonBox::addButton(
+ const KGuiItem& guiitem,
+ QObject * receiver,
+ const char * slot,
+ bool noexpand
+)
+{
+ QPushButton * pb = addButton(guiitem, noexpand);
+
+ if ((0 != receiver) && (0 != slot))
+ QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
+
+ return pb;
+}
+
+void KButtonBox::addStretch(int scale) {
+ if(scale > 0) {
+ Item* const item = new Item(0);
+ item->noexpand = false;
+ item->stretch = scale;
+ data->buttons.append(item);
+ }
+}
+
+void KButtonBox::layout() {
+ // resize all buttons
+ const QSize bs = bestButtonSize();
+
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item* item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+ if(b) {
+ if(item->noexpand)
+ b->setFixedSize(buttonSizeHint(b));
+ else
+ b->setFixedSize(bs);
+ }
+ ++itr;
+ }
+
+ setMinimumSize(sizeHint());
+}
+
+void KButtonBox::placeButtons() {
+
+ if(data->orientation == Horizontal) {
+ // calculate free size and stretches
+ int fs = width() - 2 * data->border;
+ int stretch = 0;
+ {
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+ if(b) {
+ fs -= b->width();
+
+ // Last button?
+ if(!itr.atLast())
+ fs -= data->autoborder;
+ } else {
+ stretch +=item->stretch;
+ }
+
+ ++itr;
+ }
+ }
+
+ // distribute buttons
+ int x_pos = data->border;
+ {
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+ if(b) {
+ b->move(x_pos, (height() - b->height()) / 2);
+
+ x_pos += b->width() + data->autoborder;
+ } else {
+ x_pos += (int)((((double)fs) * item->stretch) / stretch);
+ }
+
+ ++itr;
+ }
+ }
+
+ } else { // VERTICAL
+ // calcualte free size and stretches
+ int fs = height() - 2 * data->border;
+ int stretch = 0;
+ {
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+ if(b)
+ fs -= b->height() + data->autoborder;
+ else
+ stretch +=item->stretch;
+
+ ++itr;
+ }
+
+ }
+
+ // distribute buttons
+ int y_pos = data->border;
+ {
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+ if(b) {
+ b->move((width() - b->width()) / 2, y_pos);
+
+ y_pos += b->height() + data->autoborder;
+ } else {
+ y_pos += (int)((((double)fs) * item->stretch) / stretch);
+ }
+
+ ++itr;
+ }
+ }
+ }
+}
+
+void KButtonBox::resizeEvent(QResizeEvent *) {
+ placeButtons();
+}
+
+QSize KButtonBox::bestButtonSize() const {
+ QSize s(0, 0);
+
+ // calculate optimal size
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+
+ if(b && !item->noexpand) {
+ const QSize bs = buttonSizeHint(b);
+
+ const int bsWidth = bs.width();
+ const int bsHeight = bs.height();
+
+ if(bsWidth > s.width())
+ s.setWidth(bsWidth);
+ if(bsHeight > s.height())
+ s.setHeight(bsHeight);
+ }
+ ++itr;
+ }
+
+ return s;
+}
+
+QSize KButtonBox::sizeHint() const {
+ unsigned int dw;
+
+ if(data->buttons.isEmpty())
+ return QSize(0, 0);
+ else {
+ dw = 2 * data->border;
+
+ const QSize bs = bestButtonSize();
+
+ QPtrListIterator<KButtonBox::Item> itr(data->buttons);
+ Item *item;
+
+ while ( (item = itr.current()) != 0 ) {
+ QPushButton* const b = item->button;
+
+ if(b) {
+ QSize s;
+ if(item->noexpand)
+ s = buttonSizeHint(b);
+ else
+ s = bs;
+
+ if(data->orientation == Horizontal)
+ dw += s.width();
+ else
+ dw += s.height();
+
+ if( !itr.atLast() )
+ dw += data->autoborder;
+ }
+
+ ++itr;
+ }
+
+ if(data->orientation == Horizontal)
+ return QSize(dw, bs.height() + 2 * data->border);
+ else
+ return QSize(bs.width() + 2 * data->border, dw);
+ }
+}
+
+QSizePolicy KButtonBox::sizePolicy() const
+{
+ return data->orientation == Horizontal?
+ QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
+ QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
+}
+
+/*
+ * Returns the best size for a button. If a button is less than
+ * minButtonWidth pixels wide, return minButtonWidth pixels
+ * as minimum width
+ */
+QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
+ QSize s = b->sizeHint();
+ const QSize ms = b->minimumSize();
+ if(s.width() < minButtonWidth)
+ s.setWidth(minButtonWidth);
+
+ // allows the programmer to override the settings
+ const int msWidth = ms.width();
+ const int msHeight = ms.height();
+
+ if(msWidth > s.width())
+ s.setWidth(msWidth);
+ if(msHeight > s.height())
+ s.setHeight(msHeight);
+
+ return s;
+}
+
+void KButtonBox::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+