//////////////////////////////////////////////////////////////////////////////
// phasestyle.cpp
// -------------------
// TQt/TDE widget style
// -------------------
// Copyright (c) 2004 David Johnson
// Please see the header file for copyright and license information.
//////////////////////////////////////////////////////////////////////////////
//
// Some miscellaneous notes
//
// Reimplemented scrollbar metric and drawing routines from TDEStyle to allow
// better placement of subcontrols. This is because the subcontrols slightly
// overlap to share part of their border.
//
// Menu and toolbars are painted with the background color by default. This
// differs from the TQt default of giving them PaletteButton backgrounds.
// Menubars have normal gradients, toolbars have reverse.
//
// Some toolbars are not part of a TQMainWindows, such as in a TDE file dialog.
// In these cases we treat the toolbar as "floating" and paint it flat.
//
//////////////////////////////////////////////////////////////////////////////

#include <kdrawutil.h>
#include <kpixmap.h>
#include <kpixmapeffect.h>

#include <tqapplication.h>
#include <tqintdict.h>
#include <tqpainter.h>
#include <tqpointarray.h>
#include <tqsettings.h>
#include <tqstyleplugin.h>

#include <tqcheckbox.h>
#include <tqcombobox.h>
#include <tqheader.h>
#include <tqmainwindow.h>
#include <tqmenubar.h>
#include <tqpopupmenu.h>
#include <tqprogressbar.h>
#include <tqpushbutton.h>
#include <tqradiobutton.h>
#include <tqscrollbar.h>
#include <tqslider.h>
#include <tqsplitter.h>
#include <tqtabbar.h>
#include <tqtabwidget.h>
#include <tqtoolbar.h>
#include <tqtoolbox.h>
#include <tqtoolbutton.h>

#include "phasestyle.h"
#include "bitmaps.h"

static const char* TQSPLITTERHANDLE    = "TQSplitterHandle";
static const char* TQTOOLBAREXTENSION  = "TQToolBarExtensionWidget";
static const char* KTOOLBARWIDGET     = "tde toolbar widget";

// some convenient constants
static const int ITEMFRAME       = 1; // menu stuff
static const int ITEMHMARGIN     = 3;
static const int ITEMVMARGIN     = 0;
static const int ARROWMARGIN     = 6;
static const int RIGHTBORDER     = 6;
static const int MINICONSIZE     = 16;
static const int CHECKSIZE       = 9;
static const int MAXGRADIENTSIZE = 64;

static unsigned contrast = 110;


//////////////////////////////////////////////////////////////////////////////
// Construction, Destruction, Initialization                                //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// PhaseStyle()
// -----------
// Constructor

PhaseStyle::PhaseStyle()
    : TDEStyle(FilledFrameWorkaround | AllowMenuTransparency,
             ThreeButtonScrollBar),
      gradients_(TQPixmap::defaultDepth() > 8), kicker_(false)
{
    TQSettings settings;
    if (gradients_) { // don't bother setting if already false
        gradients_ =
            settings.readBoolEntry("/phasestyle/Settings/gradients", true);
        contrast = 100 + settings.readNumEntry("/TQt/TDE/contrast", 5);
    }
    highlights_ =
        settings.readBoolEntry("/phasestyle/Settings/highlights", true);

    gradients = new TQMap<unsigned int, TQIntDict<GradientSet> >;

    reverse_ = TQApplication::reverseLayout();

    // create bitmaps
    uarrow = TQBitmap(6, 6, uarrow_bits, true);
    uarrow.setMask(uarrow);
    darrow = TQBitmap(6, 6, darrow_bits, true);
    darrow.setMask(darrow);
    larrow = TQBitmap(6, 6, larrow_bits, true);
    larrow.setMask(larrow);
    rarrow = TQBitmap(6, 6, rarrow_bits, true);
    rarrow.setMask(rarrow);
    bplus = TQBitmap(6, 6, bplus_bits, true);
    bplus.setMask(bplus);
    bminus = TQBitmap(6, 6, bminus_bits, true);
    bminus.setMask(bminus);
    bcheck = TQBitmap(9, 9, bcheck_bits, true);
    bcheck.setMask(bcheck);
    dexpand = TQBitmap(9, 9, dexpand_bits, true);
    dexpand.setMask(dexpand);
    rexpand = TQBitmap(9, 9, rexpand_bits, true);
    rexpand.setMask(rexpand);
    doodad_mid = TQBitmap(4, 4, doodad_mid_bits, true);
    doodad_light = TQBitmap(4, 4, doodad_light_bits, true);
}

PhaseStyle::~PhaseStyle() 
{
    delete gradients;
    gradients = 0;
}

//////////////////////////////////////////////////////////////////////////////
// Polishing                                                                //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// polish()
// --------
// Initialize application specific

void PhaseStyle::applicationPolish(const TQStyleControlElementData &ceData, ControlElementFlags, void *ptr)
{
    if (ceData.widgetObjectTypes.contains("TQApplication")) {
        TQApplication *app = reinterpret_cast<TQApplication*>(ptr);
        if (!qstrcmp(app->argv()[0], "kicker")) kicker_ = true;
    }
}

//////////////////////////////////////////////////////////////////////////////
// polish()
// --------
// Initialize the appearance of a widget

void PhaseStyle::polish(const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *ptr)
{
    if (ceData.widgetObjectTypes.contains("TQWidget")) {
	TQWidget *widget = reinterpret_cast<TQWidget*>(ptr);

	if (::tqt_cast<TQMenuBar*>(widget) ||
		::tqt_cast<TQPopupMenu*>(widget)) {
		// anti-flicker optimization
		widget->setBackgroundMode(NoBackground);
	} else if (::tqt_cast<TQFrame*>(widget) ||
		widget->inherits(TQTOOLBAREXTENSION) ||
		(!qstrcmp(widget->name(), KTOOLBARWIDGET))) {
		// needs special handling on paint events
		installObjectEventHandler(ceData, elementFlags, ptr, this);
	} else if (highlights_ &&
		(::tqt_cast<TQPushButton*>(widget) ||
			::tqt_cast<TQComboBox*>(widget) ||
			::tqt_cast<TQSpinWidget*>(widget) ||
			::tqt_cast<TQCheckBox*>(widget) ||
			::tqt_cast<TQRadioButton*>(widget) ||
			::tqt_cast<TQSlider*>(widget) ||
			widget->inherits(TQSPLITTERHANDLE))) {
		// mouseover highlighting
		installObjectEventHandler(ceData, elementFlags, ptr, this);
	} else if (highlights_ && ::tqt_cast<TQTabBar*>(widget)) {
		// highlighting needing mouse tracking
		widget->setMouseTracking(true);
		installObjectEventHandler(ceData, elementFlags, ptr, this);
	}
    }

    TDEStyle::polish(ceData, elementFlags, ptr);
}

//////////////////////////////////////////////////////////////////////////////
// polish()
// --------
// Initialize the palette

void PhaseStyle::polish(TQPalette &pal)
{
    // clear out gradients on a color change
    gradients->clear();

    // lighten up a bit, so the look is not so "crisp"
    if (TQPixmap::defaultDepth() > 8) { // but not on low color displays
        pal.setColor(TQPalette::Disabled, TQColorGroup::Dark,
            pal.color(TQPalette::Disabled, TQColorGroup::Dark).light(contrast));
        pal.setColor(TQPalette::Active, TQColorGroup::Dark,
            pal.color(TQPalette::Active, TQColorGroup::Dark).light(contrast));
        pal.setColor(TQPalette::Inactive, TQColorGroup::Dark,
            pal.color(TQPalette::Inactive, TQColorGroup::Dark).light(contrast));
    }

    TQStyle::polish(pal);
}

//////////////////////////////////////////////////////////////////////////////
// unPolish()
// ----------
// Undo the initialization of a widget's appearance

void PhaseStyle::unPolish(const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *ptr)
{
    if (ceData.widgetObjectTypes.contains("TQWidget")) {
	TQWidget *widget = reinterpret_cast<TQWidget*>(ptr);

	if (::tqt_cast<TQMenuBar*>(widget) ||
		::tqt_cast<TQPopupMenu*>(widget)) {
		widget->setBackgroundMode(PaletteBackground);
	} else if (::tqt_cast<TQFrame*>(widget) ||
		widget->inherits(TQTOOLBAREXTENSION) ||
		(!qstrcmp(widget->name(), KTOOLBARWIDGET))) {
		removeObjectEventHandler(ceData, elementFlags, ptr, this);
	} else if (highlights_ && // highlighting
		(::tqt_cast<TQPushButton*>(widget) ||
			::tqt_cast<TQComboBox*>(widget) ||
			::tqt_cast<TQSpinWidget*>(widget) ||
			::tqt_cast<TQCheckBox*>(widget) ||
			::tqt_cast<TQRadioButton*>(widget) ||
			::tqt_cast<TQSlider*>(widget) ||
			widget->inherits(TQSPLITTERHANDLE))) {
		removeObjectEventHandler(ceData, elementFlags, ptr, this);
	} else if (highlights_ && ::tqt_cast<TQTabBar*>(widget)) {
		widget->setMouseTracking(false);
		removeObjectEventHandler(ceData, elementFlags, ptr, this);
	}
    }

    TDEStyle::unPolish(ceData, elementFlags, ptr);
}

//////////////////////////////////////////////////////////////////////////////
// Drawing                                                                  //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// drawPhaseGradient()
// ------------------
// Draw gradient

void PhaseStyle::drawPhaseGradient(TQPainter *painter,
                                   const TQRect &rect,
                                   TQColor color,
                                   bool horizontal,
                                   int px, int py,
                                   int pw, int ph,
                                   bool reverse) const
{
    if (!gradients_) {
        painter->fillRect(rect, color);
        return;
    }

    // px, py, pw, ph used for parent-relative pixmaps
    int size;
    if (horizontal)
        size = (pw > 0) ? pw : rect.width();
    else
        size = (ph > 0) ? ph : rect.height();

    if (size > MAXGRADIENTSIZE) { // keep it sensible
        painter->fillRect(rect, color);
    } else {
        // lazy allocation
        GradientSet *set = (*gradients)[color.rgb()][size];
        if (!set) {
            set = new GradientSet(color, size);
            (*gradients)[color.rgb()].setAutoDelete(true);
            (*gradients)[color.rgb()].insert(size, set);
        }
        painter->drawTiledPixmap(rect, *set->gradient(horizontal, reverse),
                                 TQPoint(px, py));
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawPhaseBevel()
// ----------------
// Draw the basic Phase bevel

void PhaseStyle::drawPhaseBevel(TQPainter *painter,
				int x, int y, int w, int h,
				const TQColorGroup &group,
				const TQColor &fill,
				bool sunken,
				bool horizontal,
				bool reverse) const
{
    int x2 = x + w - 1;
    int y2 = y + h - 1;
    painter->save();

    painter->setPen(group.dark());
    painter->drawRect(x, y, w, h);

    painter->setPen(sunken ? group.mid() : group.midlight());
    painter->drawLine(x+1, y+1, x2-2, y+1);
    painter->drawLine(x+1, y+2, x+1, y2-2);

    painter->setPen(sunken ? group.midlight() : group.mid());
    painter->drawLine(x+2, y2-1, x2-1, y2-1);
    painter->drawLine(x2-1, y+2, x2-1, y2-2);

    painter->setPen(group.button());
    painter->drawPoint(x+1, y2-1);
    painter->drawPoint(x2-1, y+1);

    if (sunken) {
        // sunken bevels don't get gradients
        painter->fillRect(x+2, y+2, w-4, h-4, fill);
    } else {
        drawPhaseGradient(painter, TQRect(x+2, y+2, w-4, h-4), fill,
                          horizontal, 0, 0, w-4, h-4, reverse);
    }
    painter->restore();
}

//////////////////////////////////////////////////////////////////////////////
// drawPhaseButton()
// ----------------
// Draw the basic Phase button

void PhaseStyle::drawPhaseButton(TQPainter *painter,
                                 int x, int y, int w, int h,
                                 const TQColorGroup &group,
                                 const TQColor &fill,
                                 bool sunken) const
{
    int x2 = x + w - 1;
    int y2 = y + h - 1;

    painter->setPen(group.midlight());
    painter->drawLine(x+1, y2, x2, y2);
    painter->drawLine(x2, y+1, x2, y2-1);

    painter->setPen(group.mid());
    painter->drawLine(x, y,  x2-1, y);
    painter->drawLine(x, y+1, x, y2-1);

    painter->setPen(group.button());
    painter->drawPoint(x, y2);
    painter->drawPoint(x2, y);

    drawPhaseBevel(painter, x+1, y+1, w-2, h-2, group, fill,
                   sunken, false, false);
}

//////////////////////////////////////////////////////////////////////////////
// drawPhasePanel()
// ----------------
// Draw the basic Phase panel

void PhaseStyle::drawPhasePanel(TQPainter *painter,
                                int x, int y, int w, int h,
                                const TQColorGroup &group,
                                bool sunken,
                                const TQBrush *fill) const
{
    int x2 = x + w - 1;
    int y2 = y + h - 1;
    painter->save();

    if (sunken) {
        painter->setPen(group.dark());
        painter->drawRect(x+1, y+1, w-2, h-2);
        painter->setPen(group.midlight());
        painter->drawLine(x+1, y2, x2, y2);
        painter->drawLine(x2, y+1, x2, y2-1);
        painter->setPen(group.mid());
        painter->drawLine(x, y, x, y2-1);
        painter->drawLine(x+1, y, x2-1, y);
        painter->setPen(group.background());
        painter->drawPoint(x, y2);
        painter->drawPoint(x2, y);
    } else {
        painter->setPen(group.dark());
        painter->drawRect(x, y, w, h);
        painter->setPen(group.midlight());
        painter->drawLine(x+1, y+1, x2-2, y+1);
        painter->drawLine(x+1, y+2, x+1, y2-2);
        painter->setPen(group.mid());
        painter->drawLine(x+2, y2-1, x2-1, y2-1);
        painter->drawLine(x2-1, y+2, x2-1, y2-2);
        painter->setPen(group.background());
        painter->drawPoint(x+1, y2-1);
        painter->drawPoint(x2-1, y+1);
    }

    if (fill) {
        painter->fillRect(x+2, y+2, w-4, h-4, fill->color());
    }
    painter->restore();
}

//////////////////////////////////////////////////////////////////////////////
// drawPhaseTab()
// -------------
// Draw a Phase style tab

void PhaseStyle::drawPhaseTab(TQPainter *painter,
                              int x, int y, int w, int h,
                              const TQColorGroup &group,
                              const TQStyleControlElementData &ceData,
                              ControlElementFlags /*elementFlags*/,
                              const TQStyleOption &option,
                              SFlags flags) const
{
    bool selected = (flags & Style_Selected);
    bool edge; // tab is at edge of bar
    const int x2 = x + w - 1;
    const int y2 = y + h - 1;

    painter->save();

    // what position is the tab?
    if ((ceData.tabBarData.tabCount == 1)
	|| (ceData.tabBarData.identIndexMap[option.tab()->identifier()] == 0)) {
	edge = true;
    } else {
	edge = false;
    }

    switch (TQTabBar::Shape(ceData.tabBarData.shape)) {
      case TQTabBar::RoundedAbove:
      case TQTabBar::TriangularAbove: {
	  // is there a corner widget?
	  if (!ceData.tabBarData.cornerWidgets[reverse_ ? TQStyleControlElementTabBarData::CWL_TopRight : TQStyleControlElementTabBarData::CWL_TopLeft].widgetObjectTypes.isEmpty()) {
	      edge = false;
	  }

          if (!selected) { // shorten
              y += 2; h -= 2;
          }
          if (selected) {
              painter->setPen(TQt::NoPen);
              painter->fillRect(x+1, y+1, w-1, h-1,
                                group.brush(TQColorGroup::Background));
          } else {
              drawPhaseGradient(painter, TQRect(x+1, y+1, w-1, h-2),
                                (flags & Style_MouseOver)
                                ? group.background()
                                : TQColor(group.background().dark(contrast)),
                                false, 0, 0, 0, h*2, false);
          }

          // draw tab
          painter->setPen(group.dark());
          painter->drawLine(x, y, x, y2-2);
          painter->drawLine(x+1, y, x2, y);
          painter->drawLine(x2, y+1, x2, y2-2);

          painter->setPen(group.mid());
          painter->drawLine(x2-1, y+2, x2-1, y2-2);

          painter->setPen(group.midlight());
          painter->drawLine(x+1, y+1, x2-2, y+1);
          if ((selected) || edge) painter->drawLine(x+1, y+2, x+1, y2-2);

          // finish off bottom
          if (selected) {
              painter->setPen(group.dark());
              painter->drawPoint(x, y2-1);
              painter->drawPoint(x2, y2-1);

              painter->setPen(group.midlight());
              painter->drawPoint(x, y2);
              painter->drawLine(x+1, y2-1, x+1, y2);
              painter->drawPoint(x2, y2);

              painter->setPen(group.mid());
              painter->drawPoint(x2-1, y2-1);

              if (!reverse_ && edge) {
                  painter->setPen(group.dark());
                  painter->drawLine(x, y2-1, x, y2);
                  painter->setPen(group.midlight());
                  painter->drawPoint(x+1, y2);
              }
          } else {
              painter->setPen(group.dark());
              painter->drawLine(x, y2-1, x2, y2-1);

              painter->setPen(group.midlight());
              painter->drawLine(x, y2, x2, y2);

              if (!reverse_ && edge) {
                  painter->setPen(group.dark());
                  painter->drawLine(x, y2-1, x, y2);
              }
          }
          if (reverse_ && edge) {
              painter->setPen(group.dark());
              painter->drawPoint(x2, y2);
              painter->setPen(selected ? group.mid() : group.background());
              painter->drawPoint(x2-1, y2);
          }
          break;
      }

      case TQTabBar::RoundedBelow:
      case TQTabBar::TriangularBelow: {
	  // is there a corner widget?
	  if (!ceData.tabBarData.cornerWidgets[reverse_ ? TQStyleControlElementTabBarData::CWL_BottomRight : TQStyleControlElementTabBarData::CWL_BottomLeft].widgetObjectTypes.isEmpty()) {
	      edge = false;
	  }

          painter->setBrush((selected || (flags & Style_MouseOver))
                            ? group.background()
                            : TQColor(group.background().dark(contrast)));
          painter->setPen(TQt::NoPen);
          painter->fillRect(x+1, y+1, w-1, h-1, painter->brush());

          // draw tab
          painter->setPen(group.dark());
          painter->drawLine(x, y+1, x, y2);
          painter->drawLine(x+1, y2, x2, y2);
          painter->drawLine(x2, y+1, x2, y2-1);

          painter->setPen(group.mid());
          painter->drawLine(x2-1, y+1, x2-1, y2-1);
          painter->drawLine(x+2, y2-1, x2-1, y2-1);
          painter->drawPoint(x, y);
          painter->drawPoint(x2, y);

          if ((selected) || edge) {
              painter->setPen(group.midlight());
              painter->drawLine(x+1, y+1, x+1, y2-2);
          }

          // finish off top
          if (selected) {
              if (!reverse_ && edge) {
                  painter->setPen(group.dark());
                  painter->drawPoint(x, y);
                  painter->setPen(group.midlight());
                  painter->drawPoint(x+1, y);
              }
          } else {
              painter->setPen(group.dark());
              painter->drawLine(x, y+1, x2, y+1);

              painter->setPen(group.mid());
              painter->drawLine(x, y, x2, y);

              if (!reverse_ && edge) {
                  painter->setPen(group.dark());
                  painter->drawPoint(x, y);
              }
          }
          if (reverse_ && edge) {
              painter->setPen(group.dark());
              painter->drawPoint(x2, y);
              painter->setPen(group.mid());
              painter->drawPoint(x2-1, y);
          }
          break;
      }
    }
    painter->restore();
}

//////////////////////////////////////////////////////////////////////////////
// drawPrimitive()
// ---------------
// Draw the primitive element

void PhaseStyle::drawPrimitive(PrimitiveElement element,
                               TQPainter *painter,
                               const TQStyleControlElementData &ceData,
                               ControlElementFlags elementFlags,
                               const TQRect &rect,
                               const TQColorGroup &group,
                               SFlags flags,
                               const TQStyleOption &option) const
{
    // common locals
    bool down      = flags & Style_Down;
    bool on        = flags & Style_On;
    bool depress   = (down || on);
    bool enabled   = flags & Style_Enabled;
    bool horiz     = flags & Style_Horizontal;
    bool active    = flags & Style_Active;
    bool mouseover = highlights_ && (flags & Style_MouseOver);
    int x, y, w, h, x2, y2, n, cx, cy;
    TQPointArray parray;
    TQWidget* widget;

    rect.rect(&x, &y, &w, &h);
    x2 = rect.right();
    y2 = rect.bottom();

    switch(element) {
      case PE_ButtonBevel:
      case PE_ButtonDefault:
      case PE_ButtonDropDown:
      case PE_ButtonTool:
          drawPhaseBevel(painter, x,y,w,h, group, group.button(),
                         depress, false, false);
          break;

      case PE_ButtonCommand:
              drawPhaseButton(painter, x, y, w, h, group,
                              mouseover ?
                              TQColor(group.button().light(contrast)) :
                              group.button(), depress);
          break;

      case PE_FocusRect: {
          TQPen old = painter->pen();
          painter->setPen(group.highlight().dark(contrast));

          painter->drawRect(rect);

          painter->setPen(old);
          break;
      }

      case PE_HeaderSection: {
          // covers kicker taskbar buttons and menu titles
          TQHeader* header = dynamic_cast<TQHeader*>(painter->device());
          widget =dynamic_cast<TQWidget*>(painter->device());

          if (header) {
              horiz = (header->orientation() ==TQt::Horizontal);
          } else {
              horiz = true;
          }

          if ((ceData.widgetObjectTypes.contains("TQPopupMenu")) ||
                           (ceData.widgetObjectTypes.contains("TDEPopupTitle"))) {
              // kicker/kdesktop menu titles
              drawPhaseBevel(painter, x,y,w,h,
                             group, group.background(), depress, !horiz);
          } else if (kicker_) {
              // taskbar buttons (assuming no normal headers used in kicker)
              if (depress) {
                  painter->setPen(group.dark());
                  painter->setBrush(group.brush(TQColorGroup::Mid));
                  painter->drawRect(x-1, y-1, w+1, h+1);
              }
              else {
                  drawPhaseBevel(painter, x-1, y-1, w+1, h+1,
                                 group, group.button(), false, !horiz, true);
              }
          } else {
              // other headers
              if (depress) {
                  painter->setPen(group.dark());
                  painter->setBrush(group.brush(TQColorGroup::Mid));
                  painter->drawRect(x-1, y-1, w+1, h+1);
              }
              else {
                  drawPhaseBevel(painter, x-1, y-1, w+1, h+1, group,
                                 group.background(), false, !horiz, true);
              }
          }
          break;
      }

      case PE_HeaderArrow:
          if (flags & Style_Up)
              drawPrimitive(PE_ArrowUp, painter, ceData, elementFlags, rect, group, Style_Enabled);
          else
              drawPrimitive(PE_ArrowDown, painter, ceData, elementFlags, rect, group, Style_Enabled);
          break;

      case PE_ScrollBarAddPage:
      case PE_ScrollBarSubPage:
          if (h) { // has a height, thus visible
              painter->fillRect(rect, group.mid());
              painter->setPen(group.dark());
              if (horiz) { // vertical
                  painter->drawLine(x, y, x2, y);
                  painter->drawLine(x, y2, x2, y2);
              } else { // horizontal
                  painter->drawLine(x, y, x, y2);
                  painter->drawLine(x2, y, x2, y2);
              }
          }
          break;

      case PE_ScrollBarAddLine:
      case PE_ScrollBarSubLine: {
          drawPhaseBevel(painter, x, y, w, h,
                         group, group.button(), down, !horiz, true);

          PrimitiveElement arrow = ((horiz) ?
                                    ((element == PE_ScrollBarAddLine) ?
                                     PE_ArrowRight : PE_ArrowLeft) :
                                    ((element == PE_ScrollBarAddLine) ?
                                     PE_ArrowDown : PE_ArrowUp));
          if (down) { // shift arrow
              switch (arrow) {
                case PE_ArrowRight: x++; break;
                case PE_ArrowLeft:  x--; break;
                case PE_ArrowDown:  y++; break;
                case PE_ArrowUp:    y--; break;
                default: break;
              }
          }

          drawPrimitive(arrow, painter, ceData, elementFlags, TQRect(x,y,h,w), group, flags);
          break;
      }

      case PE_ScrollBarSlider:
          drawPhaseBevel(painter, x, y, w, h, group, group.button(),
                         false, !horiz, true);
          // draw doodads
          cx = x + w/2 - 2; cy = y + h/2 - 2;
          if (horiz && (w >=20)) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx+n, cy,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          } else if (!horiz && (h >= 20)) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx, cy+n,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          }
          break;

      case PE_Indicator:
          drawPhasePanel(painter, x+1, y+1, w-2, h-2, group, true, enabled ?
                         &group.brush(TQColorGroup::Base) :
                         &group.brush(TQColorGroup::Background));

          if (on) {
              painter->setPen(mouseover
                              ? TQColor(group.highlight().dark(contrast))
                              : group.dark());
              painter->drawRect(x+4, y+4, w-8, h-8);
              painter->fillRect(x+5, y+5, w-10, h-10,
                                group.brush(TQColorGroup::Highlight));
          } else if (mouseover) {
              painter->setPen(TQColor(group.highlight().dark(contrast)));
              painter->drawRect(x+4, y+4, w-8, h-8);
          }
          break;

      case PE_IndicatorMask:
          painter->fillRect(x+1, y+1, w-2, h-2, TQt::color1);
          painter->setPen(TQt::color0);
          break;

      case PE_ExclusiveIndicator: {
          // note that this requires an even size from pixelMetric
          cx = (x + x2) / 2;
          cy = (y + y2) / 2;

          painter->setBrush(enabled
                            ? group.brush(TQColorGroup::Base)
                            : group.brush(TQColorGroup::Background));

          painter->setPen(group.dark());
          parray.putPoints(0, 8,
                           x+1,cy+1, x+1,cy,    cx,y+1,    cx+1,y+1,
                           x2-1,cy,  x2-1,cy+1, cx+1,y2-1, cx,y2-1);
          painter->drawConvexPolygon(parray, 0, 8);

          painter->setPen(group.mid());
          parray.putPoints(0, 4, x,cy, cx,y, cx+1,y, x2,cy);
          painter->drawPolyline(parray, 0, 4);
          painter->setPen(group.midlight());
          parray.putPoints(0, 4, x2,cy+1, cx+1,y2, cx,y2, x,cy+1);
          painter->drawPolyline(parray, 0, 4);

          if (on) {
              painter->setBrush(group.brush(TQColorGroup::Highlight));
              painter->setPen(mouseover
                              ? TQColor(group.highlight().dark(contrast))
                              : group.dark());
              parray.putPoints(0, 8,
                               x+4,cy+1, x+4,cy,    cx,y+4,    cx+1,y+4,
                               x2-4,cy,  x2-4,cy+1, cx+1,y2-4, cx,y2-4);
              painter->drawConvexPolygon(parray, 0, 8);
          } else if (mouseover) {
              painter->setPen(TQColor(group.highlight().dark(contrast)));
              parray.putPoints(0, 9,
                               x+4,cy+1, x+4,cy,    cx,y+4,    cx+1,y+4,
                               x2-4,cy,  x2-4,cy+1, cx+1,y2-4, cx,y2-4,
                               x+4,cy+1);
              painter->drawPolyline(parray, 0, 9);
          }
          break;
      }

      case PE_ExclusiveIndicatorMask:
          cx = (x + x2) / 2;
          cy = (y + y2) / 2;
          painter->setBrush(TQt::color1);
          painter->setPen(TQt::color1);
          parray.putPoints(0, 8,
                           x,cy+1, x,cy,    cx,y,    cx+1,y,
                           x2,cy,  x2,cy+1, cx+1,y2, cx,y2);
          painter->drawConvexPolygon(parray, 0, 8);
          painter->setPen(TQt::color0);
          break;

      case PE_DockWindowResizeHandle:
          drawPhasePanel(painter, x, y, w, h, group, false,
                         &group.brush(TQColorGroup::Background));
          break;

      case PE_Splitter:
          cx = x + w/2 - 2; cy = y + h/2 - 2;
          painter->fillRect(rect,
                            (flags & Style_MouseOver)
                            ? TQColor(group.background().light(contrast))
                            : group.background());

          if (!horiz && (w >=20)) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx+n, cy,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          } else if (horiz && (h >= 20)) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx, cy+n,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          }
          break;

      case PE_Panel:
      case PE_PanelLineEdit:
      case PE_PanelTabWidget:
      case PE_TabBarBase:
          drawPhasePanel(painter, x, y, w, h, group, flags & Style_Sunken);
          break;

      case PE_PanelPopup:
      case PE_WindowFrame:
          drawPhasePanel(painter, x, y, w, h, group, false);
          break;

      case PE_GroupBoxFrame:
      case PE_PanelGroupBox:
          painter->setPen(group.dark());
          painter->drawRect(rect);
          break;

      case PE_Separator:
          painter->setPen(group.dark());
          if (w < h)
              painter->drawLine(w/2, y, w/2, y2);
          else
              painter->drawLine(x, h/2, x2, h/2);
          break;

      case PE_StatusBarSection:
          painter->setPen(group.mid());
          painter->drawLine(x, y,  x2-1, y);
          painter->drawLine(x, y+1, x, y2-1);
          painter->setPen(group.midlight());
          painter->drawLine(x+1, y2, x2, y2);
          painter->drawLine(x2, y+1, x2, y2-1);
          break;

      case PE_PanelMenuBar:
      case PE_PanelDockWindow:
          if (kicker_ && (w == 2)) { // kicker handle separator
              painter->setPen(group.mid());
              painter->drawLine(x, y,  x, y2);
              painter->setPen(group.midlight());
              painter->drawLine(x+1, y,  x+1, y2);
          } else if (kicker_ && (h == 2)) { // kicker handle separator
              painter->setPen(group.mid());
              painter->drawLine(x, y,  x2, y);
              painter->setPen(group.midlight());
              painter->drawLine(x, y+1,  x2, y+1);
          } else {
              --x; --y; ++w; ++h; // adjust rect so we can use bevel
              drawPhaseBevel(painter, x, y, w, h,
                             group, group.background(), false, (w < h),
                             (element==PE_PanelDockWindow) ? true : false);
          }
          break;

      case PE_DockWindowSeparator: {
          widget = dynamic_cast<TQWidget*>(painter->device());
          bool flat = true;

          if (ceData.parentWidgetData.widgetObjectTypes.contains("TQToolBar")) {
              TQToolBar *toolbar = ::tqt_cast<TQToolBar*>(widget->parent());
              if (toolbar) {
                  // toolbar not floating or in a TQMainWindow
                  flat = flatToolbar(ceData, elementFlags, toolbar);
              }
          }

          if (flat)
              painter->fillRect(rect, group.background());
          else
              drawPhaseGradient(painter, rect, group.background(),
                                !(horiz), 0, 0, -1, -1, true);

          if (horiz) {
              int cx = w/2 - 1;
              painter->setPen(group.mid());
              painter->drawLine(cx, 0, cx, h-2);
              if (!flat) painter->drawLine(0, h-1, w-1, h-1);

              painter->setPen(group.midlight());
              painter->drawLine(cx+1, 0, cx+1, h-2);
          } else {
              int cy = h/2 - 1;
              painter->setPen(group.mid());
              painter->drawLine(0, cy, w-2, cy);
              if (!flat) painter->drawLine(w-1, 0, w-1, h-1);

              painter->setPen(group.midlight());
              painter->drawLine(0, cy+1, w-2, cy+1);
          }
          break;
      }

      case PE_SizeGrip: {
          int sw = TQMIN(h, w) - 1;
          y = y2 - sw;

          if (reverse_) {
              x2 = x + sw;
              for (int n = 0; n < 4; ++n) {
                  painter->setPen(group.dark());
                  painter->drawLine(x, y, x2, y2);
                  painter->setPen(group.midlight());
                  painter->drawLine(x, y+1, x2-1, y2);
                  y += 3;;
                  x2 -= 3;;
              }
          } else {
              x = x2 - sw;
              for (int n = 0; n < 4; ++n) {
                  painter->setPen(group.dark());
                  painter->drawLine(x, y2, x2, y);
                  painter->setPen(group.midlight());
                  painter->drawLine(x+1, y2, x2, y+1);
                  x += 3;
                  y += 3;
              }
          }

          break;
      }

      case PE_CheckMark:
          painter->setPen(group.text());
          painter->drawPixmap(x+w/2-4, y+h/2-4, bcheck);
          break;

      case PE_SpinWidgetPlus:
      case PE_SpinWidgetMinus:
          if (enabled)
              painter->setPen((flags & Style_Sunken)
                              ? group.midlight() : group.dark());
          else
              painter->setPen(group.mid());
          painter->drawPixmap(x+w/2-3, y+h/2-3,
                              (element==PE_SpinWidgetPlus) ? bplus : bminus);
          break;

      case PE_SpinWidgetUp:
      case PE_ArrowUp:
          if (flags & Style_Enabled)
              painter->setPen((flags & Style_Sunken)
                              ? group.midlight() : group.dark());
          else
              painter->setPen(group.mid());
          painter->drawPixmap(x+w/2-3, y+h/2-3, uarrow);
          break;

      case PE_SpinWidgetDown:
      case PE_ArrowDown:
          if (enabled) painter->setPen((flags & Style_Sunken)
                                       ? group.midlight() : group.dark());
          else painter->setPen(group.mid());
          painter->drawPixmap(x+w/2-3, y+h/2-3, darrow);
          break;

      case PE_ArrowLeft:
          if (enabled) painter->setPen((flags & Style_Sunken)
                                       ? group.midlight() : group.dark());
          else painter->setPen(group.mid());
          painter->drawPixmap(x+w/2-3, y+h/2-3, larrow);
          break;

      case PE_ArrowRight:
          if (enabled) painter->setPen((flags & Style_Sunken)
                                       ? group.midlight() : group.dark());
          else painter->setPen(group.mid());
          painter->drawPixmap(x+w/2-3, y+h/2-3, rarrow);
          break;

      case PE_MenuItemIndicatorFrame: {
          // Draw nothing
          break;
      }
      case PE_MenuItemIndicatorIconFrame: {
          // Draw nothing
          break;
      }
      case PE_MenuItemIndicatorCheck: {
          int checkwidth = styleHint(SH_MenuIndicatorColumnWidth, ceData, elementFlags, option, NULL, NULL);
          int cx = reverse_ ? x+w - checkwidth : x;
          drawPrimitive(PE_CheckMark, painter, ceData, elementFlags,
                            TQRect(cx + ITEMFRAME, y + ITEMFRAME,
                                  checkwidth - ITEMFRAME*2, h - ITEMFRAME*2),
                            group, Style_Default |
                            (active ? Style_Enabled : Style_On));
          break;
      }

      default:
          TDEStyle::drawPrimitive(element, painter, ceData, elementFlags, rect, group, flags, option);
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawTDEStylePrimitive()
// ---------------------
// Draw the element

void PhaseStyle::drawTDEStylePrimitive(TDEStylePrimitive element,
                                     TQPainter *painter,
                                     const TQStyleControlElementData &ceData,
                                     ControlElementFlags elementFlags,
                                     const TQRect &rect,
                                     const TQColorGroup &group,
                                     SFlags flags,
                                     const TQStyleOption &option,
                                     const TQWidget *widget) const
{
    bool horiz = flags & Style_Horizontal;
    int x, y, w, h, x2, y2, n, cx, cy;

    rect.rect(&x, &y, &w, &h);
    x2 = rect.right();
    y2 = rect.bottom();
    cx = x + w/2;
    cy = y + h/2;

    switch (element) {
      case KPE_ToolBarHandle:
          cx-=2; cy-=2;
          drawPhaseGradient(painter, rect, group.background(),
                            !horiz, 0, 0, w-1, h-1, true);
          if (horiz) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx, cy+n,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
              painter->setPen(group.mid());
              painter->drawLine(x, y2, x2, y2);
          } else {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx+n, cy,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
              painter->setPen(group.mid());
              painter->drawLine(x2, y, x2, y2);
          }
          break;

      //case KPE_DockWindowHandle:
      case KPE_GeneralHandle:
          cx-=2; cy-=2;
          painter->fillRect(rect, group.brush(TQColorGroup::Background));

          if (horiz) {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx, cy+n,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          } else {
              for (n = -5; n <= 5; n += 5) {
                  kColorBitmaps(painter, group, cx+n, cy,
                                0, &doodad_mid, &doodad_light, 0, 0, 0);
              }
          }
          break;

      case KPE_ListViewExpander:
          painter->setPen(group.mid());
          if (flags & Style_On) {
              painter->drawPixmap(x+w/2-4, y+h/2-4, rexpand);
          } else {
              painter->drawPixmap(x+w/2-4, y+h/2-4, dexpand);
          }
          break;

      case KPE_ListViewBranch:
          painter->setPen(group.mid());
          if (flags & Style_Horizontal) {
              painter->drawLine(x, cy, x2, cy);
          } else {
              painter->drawLine(cx, y, cx, y2);
          }
          break;

      case KPE_SliderGroove: {
          if (ceData.orientation == TQt::Horizontal) {
              y = cy - 3;
              h = 7;
          } else {
              x = cx - 3;
              w = 7;
          }
          drawPhasePanel(painter, x, y, w, h, group, true,
                         &group.brush(TQColorGroup::Mid));
          break;
      }

      case KPE_SliderHandle: {
          TQColor color = (flags & Style_MouseOver)
              ? TQColor(group.button().light(contrast))
              : group.button();
          if (ceData.orientation == TQt::Horizontal) {
              drawPhaseBevel(painter, cx-5, y, 6, h, group, color,
                             false, false,  false);
              drawPhaseBevel(painter, cx, y, 6, h, group, color,
                             false, false, false);
          } else {
              drawPhaseBevel(painter, x, cy-5, w, 6, group, color,
                             false, true, false);
              drawPhaseBevel(painter, x, cy, w, 6, group, color,
                             false, true, false);
          }
          break;
      }

      default:
          TDEStyle::drawTDEStylePrimitive(element, painter, ceData, elementFlags, rect,
                                      group, flags, option, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawControl()
// -------------
// Draw the control

void PhaseStyle::drawControl(ControlElement element,
                             TQPainter *painter,
                             const TQStyleControlElementData &ceData,
                             ControlElementFlags elementFlags,
                             const TQRect &rect,
                             const TQColorGroup &group,
                             SFlags flags,
                             const TQStyleOption &option,
                             const TQWidget *widget) const
{
    bool active, enabled, depress;
    int x, y, w, h, x2, y2, dx;
    TQMenuItem *mi;
    TQIconSet::Mode mode;
    TQIconSet::State state;
    TQPixmap pixmap;

    rect.rect(&x, &y, &w, &h);
    x2 = rect.right();
    y2 = rect.bottom();

    switch (element) {
      case CE_PushButton: {
          depress = flags & (Style_Down | Style_On);
          int bd = pixelMetric(PM_ButtonDefaultIndicator, ceData, elementFlags, widget) + 1;

          if ((flags & Style_ButtonDefault) && !depress) {
              drawPhasePanel(painter, x, y, w, h, group, true,
                             &group.brush(TQColorGroup::Mid));
              drawPhaseBevel(painter, x+bd, y+bd, w-bd*2, h-bd*2, group,
                             (flags & Style_MouseOver)
                             ? TQColor(group.button().light(contrast))
                             : group.button(),
                             false, false, false);
          } else {
              drawPhaseButton(painter, x, y, w, h, group,
                              (flags & Style_MouseOver)
                              ? TQColor(group.button().light(contrast))
                              : group.button(), depress);
          }

          if (flags & Style_HasFocus) { // draw focus
              drawPrimitive(PE_FocusRect, painter, ceData, elementFlags,
                            subRect(SR_PushButtonFocusRect, ceData, elementFlags, widget),
                            group, flags);
          }
          break;
      }

      case CE_PushButtonLabel: {
          const TQPushButton* button = ::tqt_cast<const TQPushButton*>(widget);
          if (!button) {
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }
          active = button->isOn() || button->isDown();

          if (active) { // shift contents
              x++; y++;
              flags |= Style_Sunken;
          }

          if (button->isMenuButton()) { // menu indicator
              int dx = pixelMetric(PM_MenuButtonIndicator, ceData, elementFlags, widget);
              drawPrimitive(PE_ArrowDown, painter, ceData, elementFlags,
                            TQRect(x+w-dx-2, y+2, dx, h-4),
                            group, flags, option);
              w -= dx;
          }

          if (button->iconSet() && !button->iconSet()->isNull()) { // draw icon
              if (button->isEnabled()) {
                  if (button->hasFocus()) {
                      mode = TQIconSet::Active;
                  } else {
                      mode = TQIconSet::Normal;
                  }
              } else {
                  mode = TQIconSet::Disabled;
              }

              if (button->isToggleButton() && button->isOn()) {
                  state = TQIconSet::On;
              } else {
                  state = TQIconSet::Off;
              }

              pixmap = button->iconSet()->pixmap(TQIconSet::Small, mode, state);
              if (button->text().isEmpty() && !button->pixmap()) {
                  painter->drawPixmap(x+w/2 - pixmap.width()/2,
                                      y+h/2 - pixmap.height()/2, pixmap);
              } else {
                  painter->drawPixmap(x+4, y+h/2 - pixmap.height()/2, pixmap);
              }
              x += pixmap.width() + 4;
              w -= pixmap.width() + 4;
          }

          if (active || button->isDefault()) { // default button
              for(int n=0; n<2; n++) {
                  drawItem(painter, TQRect(x+n, y, w, h),
                           AlignCenter | ShowPrefix,
                           button->colorGroup(),
                           button->isEnabled(),
                           button->pixmap(),
                           button->text(), -1,
                           (button->isEnabled()) ?
                           &button->colorGroup().buttonText() :
                           &button->colorGroup().mid());
              }
          } else { // normal button
              drawItem(painter, TQRect(x, y, w, h),
                       AlignCenter | ShowPrefix,
                       button->colorGroup(),
                       button->isEnabled(),
                       button->pixmap(),
                       button->text(), -1,
                       (button->isEnabled()) ?
                       &button->colorGroup().buttonText() :
                       &button->colorGroup().mid());
          }
          break;
      }

      case CE_CheckBoxLabel:
      case CE_RadioButtonLabel: {
          const TQButton *b = ::tqt_cast<const TQButton*>(widget);
          if (!b) return;

          int alignment = reverse_ ? AlignRight : AlignLeft;
          drawItem(painter, rect, alignment | AlignVCenter | ShowPrefix,
                   group, flags & Style_Enabled, b->pixmap(), b->text());

          // only draw focus if content (forms on html won't)
          if ((flags & Style_HasFocus) && ((!b->text().isNull()) || b->pixmap())) {
              drawPrimitive(PE_FocusRect, painter, ceData, elementFlags,
                            visualRect(subRect(SR_RadioButtonFocusRect, ceData, elementFlags,
                                               widget), ceData, elementFlags),
                            group, flags);
          }
          break;
      }

      case CE_DockWindowEmptyArea:  {
          const TQToolBar *tb = ::tqt_cast<const TQToolBar*>(widget);
          if (tb) {
              // toolbar not floating or in a TQMainWindow
              if (flatToolbar(ceData, elementFlags, tb)) {
                  if (tb->backgroundMode() == PaletteButton)
                      // force default button color to background color
                      painter->fillRect(rect, group.background());
                  else
                      painter->fillRect(rect, tb->paletteBackgroundColor());
              }
          }
          break;
      }

      case CE_MenuBarEmptyArea:
          drawPhaseGradient(painter, TQRect(x, y, w, h), group.background(),
                            (w<h), 0, 0, 0, 0, false);
          break;

      case CE_MenuBarItem: {
          const TQMenuBar *mbar = ::tqt_cast<const TQMenuBar*>(widget);
          if (!mbar) {
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }
          mi = option.menuItem();
          TQRect prect = mbar->rect();

          if ((flags & Style_Active) && (flags & Style_HasFocus)) {
              if (flags & Style_Down) {
                  drawPhasePanel(painter, x, y, w, h, group, true,
                                 &group.brush(TQColorGroup::Background));
              } else {
                  drawPhaseBevel(painter, x, y, w, h,
                                 group, group.background(),
                                 false, false, false);
              }
          } else {
              drawPhaseGradient(painter, rect, group.background(), false, x, y,
                                prect.width()-2, prect.height()-2, false);
          }
          drawItem(painter, rect,
                   AlignCenter | AlignVCenter |
                   DontClip | ShowPrefix | SingleLine,
                   group, flags & Style_Enabled,
                   mi->pixmap(), mi->text());
          break;
      }

      case CE_PopupMenuItem: {
          if (!ceData.widgetObjectTypes.contains("TQPopupMenu")) {
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }

          mi = option.menuItem();
          if (!mi) {
              painter->fillRect(rect, group.button());
              break;
          }

          int tabwidth   = option.tabWidth();
          int checkwidth = option.maxIconWidth();
          bool checkable = (elementFlags & CEF_IsCheckable);
          bool etchtext  = styleHint(SH_EtchDisabledText, ceData, elementFlags);
          active         = flags & Style_Active;
          enabled        = mi->isEnabled();
          TQRect vrect;

          if (checkable) checkwidth = TQMAX(checkwidth, 20);

          // draw background
          if (active && enabled) {
              painter->fillRect(x, y, w, h, group.highlight());
          } else if (!ceData.bgPixmap.isNull()) {
              painter->drawPixmap(x, y, ceData.bgPixmap, x, y, w, h);
          } else {
              painter->fillRect(x, y, w, h, group.background());
          }

          // draw separator
          if (mi->isSeparator()) {
              painter->setPen(group.dark());
              painter->drawLine(x+checkwidth+1, y+1, x2-checkwidth-1, y+1);
              painter->setPen(group.mid());
              painter->drawLine(x+checkwidth, y, x2-checkwidth-1, y);
              painter->drawPoint(x+checkwidth, y+1);
              painter->setPen(group.midlight());
              painter->drawLine(x+checkwidth+1, y2, x2-checkwidth, y2);
              painter->drawPoint(x2-checkwidth, y2-1);
              break;
          }

          // draw icon
          if (mi->iconSet() && !mi->isChecked()) {
              if (active)
                  mode = enabled ? TQIconSet::Active : TQIconSet::Disabled;
              else
                  mode = enabled ? TQIconSet::Normal : TQIconSet::Disabled;

              pixmap = mi->iconSet()->pixmap(TQIconSet::Small, mode);
              TQRect pmrect(0, 0, pixmap.width(), pixmap.height());
              vrect = visualRect(TQRect(x, y, checkwidth, h), rect);
              pmrect.moveCenter(vrect.center());
              painter->drawPixmap(pmrect.topLeft(), pixmap);
          }

          // draw check
          if (mi->isChecked()) {
              drawPrimitive(PE_MenuItemIndicatorCheck, painter, ceData, elementFlags, TQRect(x, y, checkwidth, h), group, flags, option);
          }

          // draw text
          int xm = ITEMFRAME + checkwidth + ITEMHMARGIN;
          int xp = reverse_ ?
              x + tabwidth + RIGHTBORDER + ITEMHMARGIN + ITEMFRAME - 1 :
              x + xm;
          int offset = reverse_ ? -1 : 1;
          int tw = w - xm - tabwidth - ARROWMARGIN - ITEMHMARGIN * 3
              - ITEMFRAME + 1;

          painter->setPen(enabled ? (active ? group.highlightedText() :
                                     group.buttonText()) : group.mid());

          if (mi->custom()) { // draws own label
              painter->save();
              if (etchtext && !enabled && !active) {
                  painter->setPen(group.light());
                  mi->custom()->paint(painter, group, active, enabled,
                                      xp+offset, y+ITEMVMARGIN+1,
                                      tw, h-2*ITEMVMARGIN);
                  painter->setPen(group.mid());
              }
              mi->custom()->paint(painter, group, active, enabled,
                                  xp, y+ITEMVMARGIN, tw, h-2*ITEMVMARGIN);
              painter->restore();
          }
          else { // draw label
              TQString text = mi->text();

              if (!text.isNull()) {
                  int t = text.find('\t');
                  int tflags = AlignVCenter | DontClip |
                      ShowPrefix |  SingleLine |
                      (reverse_ ? AlignRight : AlignLeft);

                  if (t >= 0) {
                      int tabx = reverse_ ?
                          x + RIGHTBORDER + ITEMHMARGIN + ITEMFRAME :
                          x + w - tabwidth - RIGHTBORDER - ITEMHMARGIN
                          - ITEMFRAME;

                      // draw right label (accerator)
                      if (etchtext && !enabled) { // etched
                          painter->setPen(group.light());
                          painter->drawText(tabx+offset, y+ITEMVMARGIN+1,
                                            tabwidth, h-2*ITEMVMARGIN,
                                            tflags, text.mid(t+1));
                          painter->setPen(group.mid());
                      }
                      painter->drawText(tabx, y+ITEMVMARGIN,
                                        tabwidth, h-2*ITEMVMARGIN,
                                        tflags, text.mid(t+1));
                      text = text.left(t);
                  }

                  // draw left label
                  if (etchtext && !enabled) { // etched
                      painter->setPen(group.light());
                      painter->drawText(xp+offset, y+ITEMVMARGIN+1,
                                        tw, h-2*ITEMVMARGIN,
                                        tflags, text, t);
                      painter->setPen(group.mid());
                  }
                  painter->drawText(xp, y+ITEMVMARGIN,
                                    tw, h-2*ITEMVMARGIN,
                                    tflags, text, t);
              }
              else if (mi->pixmap()) { // pixmap as label
                  pixmap = *mi->pixmap();
                  if (pixmap.depth() == 1)
                      painter->setBackgroundMode(TQt::OpaqueMode);

                  dx = ((w - pixmap.width()) / 2) + ((w - pixmap.width()) % 2);
                  painter->drawPixmap(x+dx, y+ITEMFRAME, pixmap);

                  if (pixmap.depth() == 1)
                      painter->setBackgroundMode(TQt::TransparentMode);
              }
          }

          if (mi->popup()) { // draw submenu arrow
              PrimitiveElement arrow = reverse_ ? PE_ArrowLeft : PE_ArrowRight;
              int dim = (h-2*ITEMFRAME) / 2;
              vrect = visualRect(TQRect(x + w - ARROWMARGIN - ITEMFRAME - dim,
                                       y + h / 2 - dim / 2, dim, dim), rect);
              drawPrimitive(arrow, painter, ceData, elementFlags, vrect, group,
                            enabled ? Style_Enabled : Style_Default);
          }
          break;
      }

      case CE_TabBarTab: {
          if (ceData.widgetObjectTypes.contains("TQTabBar")) {
              // this guy can get complicated, we we do it elsewhere
              drawPhaseTab(painter, x, y, w, h, group, ceData, elementFlags, option,
                           flags);
          } else { // not a tabbar
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }
          break;
      }

      case CE_ProgressBarGroove: {
          drawPhasePanel(painter, x, y, w, h, group, true,
                         &group.brush(TQColorGroup::Base));
          break;
      }

      case CE_ProgressBarContents: {
          if (!ceData.widgetObjectTypes.contains("TQProgressBar")) {
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }
          subRect(SR_ProgressBarContents, ceData, elementFlags, widget).rect(&x, &y, &w, &h);

          painter->setBrush(group.brush(TQColorGroup::Highlight));
          painter->setPen(group.dark());

          if (!ceData.totalSteps) {
              // busy indicator
              int bar = pixelMetric(PM_ProgressBarChunkWidth, ceData, elementFlags, widget) + 2;
              int progress = ceData.currentStep % ((w-bar) * 2);
              if (progress > (w-bar)) progress = 2 * (w-bar) - progress;
              painter->drawRect(x+progress+1, y+1, bar-2, h-2);
          } else {
              double progress = static_cast<double>(ceData.currentStep) /
                  static_cast<double>(ceData.totalSteps);
              dx = static_cast<int>(w * progress);
              if (dx < 4) break;
              if (reverse_) x += w - dx;
              painter->drawRect(x+1, y+1, dx-2, h-2);
          }
          break;
      }

      case CE_ToolBoxTab: {
          const TQToolBox *box = ::tqt_cast<const TQToolBox*>(widget);
          if (!box) {
              TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                                  flags, option, widget);
              return;
          }

          const int rx = x2 - 20;
          const int cx = rx - h + 1;

          TQPointArray parray(6);
          parray.putPoints(0, 6,
                           x-1,y, cx,y, rx-2,y2-2, x2+1,y2-2,
                           x2+1,y2+2, x-1,y2+2);

          if (box->currentItem() && (flags & Style_Selected)) {
              painter->setPen(group.dark());
              painter->setBrush(box->currentItem()->paletteBackgroundColor());
              painter->drawConvexPolygon(parray, 0, 6);
              painter->setBrush(NoBrush);
          } else {
              painter->setClipRegion(parray, TQPainter::CoordPainter);
              drawPhaseGradient(painter, rect,
                                group.background(),
                                false, 0, 0, 0, h*2, false);
              painter->setClipping(false);
              painter->drawPolyline(parray, 0, 4);
          }

          parray.putPoints(0, 4, x,y+1, cx,y+1, rx-2,y2-1, x2,y2-1);
          painter->setPen(group.midlight());
          painter->drawPolyline(parray, 0, 4);

          break;
      }

      default:
          TDEStyle::drawControl(element, painter, ceData, elementFlags, rect, group,
                              flags, option, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawControlMask()
// -----------------
// Draw a bitmask for the element

void PhaseStyle::drawControlMask(ControlElement element,
                                 TQPainter *painter,
                                 const TQStyleControlElementData &ceData,
                                 ControlElementFlags elementFlags,
                                 const TQRect &rect,
                                 const TQStyleOption &option,
                                 const TQWidget *widget) const
{
    switch (element) {
      case CE_PushButton:
          painter->fillRect(rect, TQt::color1);
          painter->setPen(TQt::color0);
          break;

      default:
          TDEStyle::drawControlMask(element, painter, ceData, elementFlags, rect, option, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawComplexControl()
// --------------------
// Draw a complex control

void PhaseStyle::drawComplexControl(ComplexControl control,
                                    TQPainter *painter,
                                    const TQStyleControlElementData &ceData,
                                    ControlElementFlags elementFlags,
                                    const TQRect &rect,
                                    const TQColorGroup &group,
                                    SFlags flags,
                                    SCFlags controls,
                                    SCFlags active,
                                    const TQStyleOption &option,
                                    const TQWidget *widget) const
{
    bool down = flags & Style_Down;
    bool on = flags & Style_On;
    bool raised = flags & Style_Raised;
    bool sunken = flags & Style_Sunken;
    TQRect subrect;
    int x, y, w, h, x2, y2;
    rect.rect(&x, &y, &w, &h);

    switch (control) {
      case CC_ComboBox: {
          sunken = (active == SC_ComboBoxArrow);
          drawPhaseButton(painter, x, y, w, h, group,
                          (flags & Style_MouseOver)
                          ? TQColor(group.button().light(contrast))
                          : group.button(), sunken);

          if (controls & SC_ComboBoxArrow) { // draw arrow box
              subrect = visualRect(querySubControlMetrics(CC_ComboBox, ceData, elementFlags,
                            SC_ComboBoxArrow, TQStyleOption::Default, widget), ceData, elementFlags);

              subrect.rect(&x, &y, &w, &h);
              int slot = TQMAX(h/4, 6) + (h % 2);
              drawPhasePanel(painter, x+3, y+(h/2)-(slot/2), w-6,
                             slot, group, true,
                             sunken ? &group.brush(TQColorGroup::Midlight)
                             : &group.brush(TQColorGroup::Mid));
          }

          if (controls & SC_ComboBoxEditField) { // draw edit box
              if (elementFlags & CEF_IsEditable) { // editable box
                  subrect = visualRect(querySubControlMetrics(CC_ComboBox,
                                ceData, elementFlags, SC_ComboBoxEditField, TQStyleOption::Default, widget), ceData, elementFlags);
                  x2 = subrect.right(); y2 = subrect.bottom();
                  painter->setPen(group.dark());
                  painter->drawLine(x2+1, y, x2+1, y2);
                  painter->setPen(group.midlight());
                  painter->drawLine(x2+2, y, x2+2, y2-1);
                  painter->setPen(group.button());
                  painter->drawPoint(x2+2, y2);
              } else if (elementFlags & CEF_HasFocus) { // non editable box
                  subrect = visualRect(subRect(SR_ComboBoxFocusRect, ceData, elementFlags,
                                               widget), ceData, elementFlags);
                  drawPrimitive(PE_FocusRect, painter, ceData, elementFlags, subrect, group,
                                Style_FocusAtBorder,
                                TQStyleOption(group.highlight()));
              }
          }

          painter->setPen(group.buttonText()); // for subsequent text
          break;
      }

      case CC_ScrollBar: {
          // always a three button scrollbar
          TQRect srect;
          bool horizontal = (ceData.orientation == TQt::Horizontal);
          SFlags scrollflags = (horizontal ? Style_Horizontal : Style_Default);

          if (ceData.minSteps == ceData.maxSteps) scrollflags |= Style_Default;
          else scrollflags |= Style_Enabled;

          // addline
          if (controls & SC_ScrollBarAddLine) {
              srect = querySubControlMetrics(control, ceData, elementFlags,
                                             SC_ScrollBarAddLine, option, widget);
              if (srect.isValid())
                  drawPrimitive(PE_ScrollBarAddLine, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarAddLine)
                                               ? Style_Down : Style_Default));
          }

          // subline (two of them)
          if (controls & SC_ScrollBarSubLine) {
              // top/left subline
              srect = querySubControlMetrics(control, ceData, elementFlags,
                                             SC_ScrollBarSubLine, option, widget);
              if (srect.isValid())
                  drawPrimitive(PE_ScrollBarSubLine, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarSubLine)
                                               ? Style_Down : Style_Default));
              // bottom/right subline
              srect = querySubControlMetrics(control, ceData, elementFlags,
                                             SC_ScrollBarAddLine, option, widget);
              if (srect.isValid()) {
                  if (horizontal) srect.moveBy(-srect.width()+1, 0);
                  else srect.moveBy(0, -srect.height()+1);
                  drawPrimitive(PE_ScrollBarSubLine, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarSubLine)
                                               ? Style_Down : Style_Default));
              }
          }

          // addpage
          if (controls & SC_ScrollBarAddPage) {
              srect = querySubControlMetrics(control, ceData, elementFlags,
                                             SC_ScrollBarAddPage, option, widget);
              if (srect.isValid()) {
                  if (horizontal) srect.addCoords(1, 0, 1, 0);
                  else srect.addCoords(0, 1, 0, 1);
                  drawPrimitive(PE_ScrollBarAddPage, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarAddPage)
                                               ? Style_Down : Style_Default));
              }
          }

          // subpage
          if (controls & SC_ScrollBarSubPage) {
              srect = querySubControlMetrics(control, ceData, elementFlags,
                                             SC_ScrollBarSubPage, option, widget);
              if (srect.isValid()) {
                  drawPrimitive(PE_ScrollBarSubPage, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarSubPage)
                                               ? Style_Down : Style_Default));
              }
          }

          // slider
          if (controls & SC_ScrollBarSlider) {
              if (ceData.minSteps == ceData.maxSteps) {
                  // maxed out
                  srect = querySubControlMetrics(control, ceData, elementFlags,
                                                 SC_ScrollBarGroove, option, widget);
              } else {
                  srect = querySubControlMetrics(control, ceData, elementFlags,
                                                 SC_ScrollBarSlider, option, widget);
              }
              if (srect.isValid()) {
                  if (horizontal) srect.addCoords(0, 0, 1, 0);
                  else srect.addCoords(0, 0, 0, 1);
                  drawPrimitive(PE_ScrollBarSlider, painter, ceData, elementFlags, srect, group,
                                scrollflags | ((active == SC_ScrollBarSlider)
                                               ? Style_Down : Style_Default));
                  // focus
                  if (elementFlags & CEF_HasFocus) {
                      srect.addCoords(2, 2, -2, -2);
                      drawPrimitive(PE_FocusRect, painter, ceData, elementFlags, srect, group,
                                    Style_Default);
                  }
              }
          }
          break;
      }

      case CC_SpinWidget: {
          const TQSpinWidget *spin = ::tqt_cast<const TQSpinWidget*>(widget);
          if (!spin) {
              TDEStyle::drawComplexControl(control, painter, ceData, elementFlags, rect, group,
                                         flags, controls, active, option, widget);
              return;
          }

          PrimitiveElement element;

          // draw frame
          if (controls & SC_SpinWidgetFrame) {
              drawPhasePanel(painter, x, y, w, h, group, true, NULL);
          }

          // draw button field
          if (controls & SC_SpinWidgetButtonField) {
              subrect = querySubControlMetrics(CC_SpinWidget, ceData, elementFlags,
                                               SC_SpinWidgetButtonField,
                                               option, widget);
              if (reverse_) subrect.moveLeft(spin->upRect().left());
              drawPhaseBevel(painter, subrect.x(), subrect.y(),
                             subrect.width(), subrect.height(), group,
                             (flags & Style_MouseOver)
                             ? TQColor(group.button().light(contrast))
                             : group.button(), false, false, false);
          }

          // draw up arrow
          if (controls & SC_SpinWidgetUp) {
              subrect = spin->upRect();

              sunken = (active == SC_SpinWidgetUp);
              if (spin->buttonSymbols() == TQSpinWidget::PlusMinus)
                  element = PE_SpinWidgetPlus;
              else
                  element = PE_SpinWidgetUp;

              drawPrimitive(element, painter, ceData, elementFlags, subrect, group, flags
                            | ((active == SC_SpinWidgetUp)
                               ? Style_On | Style_Sunken : Style_Raised));
          }

          // draw down button
          if (controls & SC_SpinWidgetDown) {
              subrect = spin->downRect();

              sunken = (active == SC_SpinWidgetDown);
              if (spin->buttonSymbols() == TQSpinWidget::PlusMinus)
                  element = PE_SpinWidgetMinus;
              else
                  element = PE_SpinWidgetDown;

              drawPrimitive(element, painter, ceData, elementFlags, subrect, group, flags
                            | ((active == SC_SpinWidgetDown)
                               ? Style_On | Style_Sunken : Style_Raised));
          }
          break;
      }

      case CC_ToolButton: {
          const TQToolButton *btn = ::tqt_cast<const TQToolButton*>(widget);

          TQToolBar *toolbar;
          bool horiz = true;
          bool normal = !(down || on || raised); // normal button state

          x2 = rect.right();
          y2 = rect.bottom();

          // check for TQToolBar parent
          if (ceData.parentWidgetData.widgetObjectTypes.contains("TQToolBar")) {
              toolbar = (btn)?::tqt_cast<TQToolBar*>(btn->parent()):NULL;
              horiz = (ceData.toolBarData.orientation == TQt::Horizontal);
              if (normal) { // draw background
                  if (toolbar && flatToolbar(ceData, elementFlags, toolbar)) {
                      // toolbar not floating or in a TQMainWindow
                      painter->fillRect(rect, group.background());
                  } else {
                      drawPhaseGradient(painter, rect, group.background(),
                                        !horiz, 0, 0,
                                        ceData.parentWidgetData.rect.width()-3,
                                        ceData.parentWidgetData.rect.height()-3, true);
                      painter->setPen(group.mid());
                      if (horiz) {
                          painter->drawLine(x, y2, x2, y2);
                      } else {
                          painter->drawLine(x2, y, x2, y2);
                      }
                  }
              }
          }
          // check for TQToolBarExtensionWidget parent
          else if (btn && ceData.parentWidgetData.widgetObjectTypes.contains(TQTOOLBAREXTENSION)) {
              TQWidget *extension;
              if ((extension = ::tqt_cast<TQWidget*>(btn->parent()))) {
                  toolbar = ::tqt_cast<TQToolBar*>(extension->parent());
                  if (toolbar) {
                      horiz = (toolbar->orientation() == TQt::Horizontal);
                      if (normal) { // draw background
                          drawPhaseGradient(painter, rect, group.background(),
                                            !horiz, 0, 0, toolbar->width()-3,
                                            toolbar->height()-3, true);
                      }
                  }
              }
          }
          // check for background pixmap
          else if (normal &&
                   !ceData.parentWidgetData.bgPixmap.isNull()) {
              TQPixmap pixmap = ceData.parentWidgetData.bgPixmap;
              painter->drawTiledPixmap(rect, pixmap, ceData.pos);
          }
          // everything else
          else if (normal) {
              // toolbutton not on a toolbar
              painter->fillRect(rect, group.background());
          }

          // now draw active buttons
          if (down || on) {
              drawPhasePanel(painter, x, y, w, h, group, true,
                             &group.brush(TQColorGroup::Button));
          } else if (raised) {
              drawPhaseBevel(painter, x, y, w, h, group, group.button(),
                             false, !horiz, true);
          }
          painter->setPen(group.text());
          break;
      }

      default:
          TDEStyle::drawComplexControl(control, painter, ceData, elementFlags, rect, group,
                                     flags, controls, active, option, widget);
          break;
    }
}

//////////////////////////////////////////////////////////////////////////////
// drawComplexControlMask()
// ------------------------
// Draw a bitmask for the control

void PhaseStyle::drawComplexControlMask(ComplexControl control,
                                        TQPainter *painter,
                                        const TQStyleControlElementData &ceData,
                                        const ControlElementFlags elementFlags,
                                        const TQRect &rect,
                                        const TQStyleOption &option,
                                        const TQWidget *widget) const
{
    switch (control) {
      case CC_ComboBox:
      case CC_ToolButton: {
          painter->fillRect(rect, TQt::color1);
          painter->setPen(TQt::color0);
          break;
      }

      default:
          TDEStyle::drawComplexControlMask(control,painter,ceData,elementFlags,rect,option,widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// pixelMetric()
// -------------
// Get the pixel metric for metric

int PhaseStyle::pixelMetric(PixelMetric metric, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, const TQWidget *widget) const
{
    // not using widget's font, so that all metrics are uniform
    int em = TQMAX(TQApplication::fontMetrics().strikeOutPos() * 3, 17);

    switch (metric) {
      case PM_DefaultFrameWidth:
          return 2;

      case PM_ButtonDefaultIndicator:   // size of default indicator
          return 2;

      case PM_ButtonMargin:             // Space betweeen frame and label
          return 3;

      case PM_TabBarTabOverlap:         // Amount of tab overlap
          return 1;

      case PM_TabBarTabHSpace:          // extra tab spacing
          return 24;

      case PM_TabBarTabVSpace:
          if (ceData.widgetObjectTypes.contains("TQTabBar")) {
              if (ceData.tabBarData.shape == TQTabBar::RoundedAbove) {
                  return 10;
              } else {
                  return 6;
              }
          }
          return 0;

      case PM_ExclusiveIndicatorWidth:  // radiobutton size
      case PM_ExclusiveIndicatorHeight:
      case PM_IndicatorWidth:           // checkbox size
      case PM_IndicatorHeight:
      case PM_CheckListButtonSize:	// checkbox size in qlistview items
      case PM_ScrollBarExtent:          // base width of a vertical scrollbar
          return em & 0xfffe;

      case PM_SplitterWidth:            // width of spitter
          return (em / 3) & 0xfffe;

      case PM_ScrollBarSliderMin:       // minimum length of slider
          return  em * 2;

      case PM_SliderThickness:          // slider thickness
      case PM_SliderControlThickness:
          return em;

      case PM_MenuIndicatorFrameHBorder:
      case PM_MenuIndicatorFrameVBorder:
      case PM_MenuIconIndicatorFrameHBorder:
      case PM_MenuIconIndicatorFrameVBorder:
          return ITEMFRAME;

      default:
          return TDEStyle::pixelMetric(metric, ceData, elementFlags, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// subRect()
// ---------
// Return subrect for the widget in logical coordinates

TQRect PhaseStyle::subRect(SubRect rect, const TQStyleControlElementData &ceData, const ControlElementFlags elementFlags, const TQWidget *widget) const
{
    switch (rect) {
      case SR_ComboBoxFocusRect: {
          TQRect r = querySubControlMetrics(CC_ComboBox, ceData, elementFlags,
                                           SC_ComboBoxEditField, TQStyleOption::Default, widget);
          r.addCoords(1, 1,-1,-1);
          return r;
      }

      default:
          return TDEStyle::subRect(rect, ceData, elementFlags, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// querySubControlMetrics()
// ------------------------
// Get metrics for subcontrols of complex controls

TQRect PhaseStyle::querySubControlMetrics(ComplexControl control,
                                         const TQStyleControlElementData &ceData,
                                         ControlElementFlags elementFlags,
                                         SubControl subcontrol,
                                         const TQStyleOption &option,
                                         const TQWidget *widget) const
{
    TQRect rect;

    const int fw = pixelMetric(PM_DefaultFrameWidth, ceData, elementFlags, widget);
    int w = ceData.rect.width(), h = ceData.rect.height();
    int xc;

    switch (control) {

      case CC_ComboBox: {
          xc = h; // position between edit and arrow

          switch (subcontrol) {
            case SC_ComboBoxFrame: // total combobox area
                rect = ceData.rect;
                break;

            case SC_ComboBoxArrow: // the right side
                rect.setRect(w-xc, fw, xc-fw, h-(fw*2));
                break;

            case SC_ComboBoxEditField: // the left side
                rect.setRect(fw, fw, w-xc-fw-1, h-(fw*2));
                break;

            case SC_ComboBoxListBoxPopup: // the list popup box
                rect = option.rect();
                break;

            default:
                break;
          }
          break;
      }

      case CC_ScrollBar: {
          bool horizontal = (ceData.orientation == TQt::Horizontal);
          rect = TDEStyle::querySubControlMetrics(control, ceData, elementFlags,
                                                subcontrol, option, widget);

          // adjust the standard metrics so controls can "overlap"
          if (subcontrol == SC_ScrollBarGroove) {
              if (horizontal) rect.addCoords(-1, 0, 1, 0);
              else            rect.addCoords(0, -1, 0, 1);
          }
          break;
      }

      case CC_SpinWidget: {
          bool odd = ceData.rect.height() % 2;
          xc = (h * 3 / 4) + odd; // position between edit and arrows

          switch (subcontrol) {
            case SC_SpinWidgetButtonField:
                rect.setRect(w-xc, 1, xc-1, h-2);
                break;

            case SC_SpinWidgetEditField:
                rect.setRect(fw, fw, w-xc-fw, h-(fw*2));
                break;

            case SC_SpinWidgetFrame:
                rect = ceData.rect;
                break;

            case SC_SpinWidgetUp:
                rect.setRect(w-xc, (h/2)-(odd ? 6 : 7), xc-1, 6);
                break;

            case SC_SpinWidgetDown:
                rect.setRect(w-xc, (h/2)+1, xc-1, odd ? 7 : 6);
                break;

            default:
                break;
          }
          break;
      }

      default:
          rect = TDEStyle::querySubControlMetrics(control, ceData, elementFlags, subcontrol,
                                                option, widget);
    }

    return rect;
}

//////////////////////////////////////////////////////////////////////////////
// sizeFromContents()
// ------------------
// Returns the size of widget based on the contentsize

TQSize PhaseStyle::sizeFromContents(ContentsType contents,
                                   const TQStyleControlElementData &ceData,
                                   ControlElementFlags elementFlags,
                                   const TQSize &contentsize,
                                   const TQStyleOption &option,
                                   const TQWidget* widget ) const
{
    int w = contentsize.width();
    int h = contentsize.height();

    switch (contents) {
      case CT_PushButton: {
          const TQPushButton* button = ::tqt_cast<const TQPushButton*>(widget);
          if (!button) {
              return TDEStyle::sizeFromContents(contents, ceData, elementFlags, contentsize,
                                              option, widget);
          }
          int margin = pixelMetric(PM_ButtonMargin, ceData, elementFlags, widget)
              + pixelMetric(PM_DefaultFrameWidth, ceData, elementFlags, widget) + 4;

          w += margin + 6; // add room for bold font
          h += margin;

          // standard width and heights
          if (button->isDefault() || button->autoDefault()) {
              if (w < 80 && !button->pixmap()) w = 80;
          }
          if (h < 22) h = 22;
          return TQSize(w, h);
      }

      case CT_PopupMenuItem: {
          if (!widget || option.isDefault()) return contentsize;
          if (!ceData.widgetObjectTypes.contains("TQPopupMenu")) {
              return TDEStyle::sizeFromContents(contents, ceData, elementFlags, contentsize,
                                              option, widget);
          }
          TQMenuItem *item = option.menuItem();

          if (item->custom()) {
              w = item->custom()->sizeHint().width();
              h = item->custom()->sizeHint().height();
              if (!item->custom()->fullSpan())
                  h += ITEMVMARGIN*2 + ITEMFRAME*2;
          } else if (item->widget()) { // a menu item that is a widget
              w = contentsize.width();
              h = contentsize.height();
          } else if (item->isSeparator()) {
              w = h = 3;
          } else {
              if (item->pixmap()) {
                  h = TQMAX(h, item->pixmap()->height() + ITEMFRAME*2);
              } else {
                  h = TQMAX(h, MINICONSIZE + ITEMFRAME*2);
                  h = TQMAX(h, TQFontMetrics(ceData.font).height()
                           + ITEMVMARGIN*2 + ITEMFRAME*2);
              }
              if (item->iconSet())
                  h = TQMAX(h, item->iconSet()->
                           pixmap(TQIconSet::Small, TQIconSet::Normal).height()
                           + ITEMFRAME*2);
          }

          if (!item->text().isNull() && item->text().find('\t') >= 0)
              w += 12;
          else if (item->popup())
              w += 2 * ARROWMARGIN;

          if (option.maxIconWidth() || (elementFlags & CEF_IsCheckable)) {
              w += TQMAX(option.maxIconWidth(),
                        TQIconSet::iconSize(TQIconSet::Small).width())
                  + ITEMHMARGIN*2;
          }
          w += RIGHTBORDER;
          return TQSize(w, h);
      }

      default:
          return TDEStyle::sizeFromContents(contents, ceData, elementFlags, contentsize,
                                          option, widget);
    }
}

//////////////////////////////////////////////////////////////////////////////
// Miscellaneous                                                            //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// flatToolbar()
// -------------
// Is the toolbar "flat"

bool PhaseStyle::flatToolbar(const TQStyleControlElementData &ceData, const ControlElementFlags elementFlags, const TQToolBar *toolbar) const
{
    if (!toolbar) return true; // not on a toolbar
    if (!toolbar->isMovingEnabled()) return true; // immobile toolbars are flat
    if (!toolbar->area()) return true; // not docked
    if (toolbar->place() == TQDockWindow::OutsideDock) return true; // ditto
    if (!toolbar->mainWindow()) return true; // not in a main window
    return false;
}

int PhaseStyle::styleHint(StyleHint sh, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, const TQStyleOption &opt, TQStyleHintReturn *returnData, const TQWidget *w) const
{
	int ret;

	switch (sh) {
		case SH_MenuIndicatorColumnWidth:
			{
				int checkwidth = opt.maxIconWidth();
				bool checkable = (elementFlags & CEF_IsCheckable);

				if (checkable) checkwidth = TQMAX(checkwidth, 20);

				ret = checkwidth;
			}
			break;
		default:
			ret = TDEStyle::styleHint(sh, ceData, elementFlags, opt, returnData, w);
			break;
	}

	return ret;
}

//////////////////////////////////////////////////////////////////////////////
// eventFilter()
// -------------
// Grab events we are interested in. Most of this routine is to handle the
// exceptions to the normal styling rules.

bool PhaseStyle::objectEventHandler( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void* source, TQEvent *event )
{
    if (ceData.widgetObjectTypes.contains("TQObject")) {
	TQObject* object = reinterpret_cast<TQObject*>(source);

	if (TDEStyle::objectEventHandler(ceData, elementFlags, source, event)) return true;
	if (!object->isWidgetType()) return false;

	bool horiz;
	int x, y, w, h;
	TQFrame *frame;
	TQToolBar *toolbar;
	TQWidget *widget;
	
	// painting events
	if (event->type() == TQEvent::Paint) {
		// make sure we do the most specific stuff first
	
		// TDE Toolbar Widget
		// patch by Daniel Brownlees <dbrownlees@paradise.net.nz>
		if (object->parent() && !qstrcmp(object->name(), KTOOLBARWIDGET)) {
		if (0 == (widget = ::tqt_cast<TQWidget*>(object))) return false;
		TQWidget *parent = ::tqt_cast<TQWidget*>(object->parent());
		int px = ceData.rect.x(), py = ceData.rect.y();
		// find the toolbar
		while (parent && parent->parent()
			&& !::tqt_cast<TQToolBar*>(parent)) {
			px += parent->x();
			py += parent->y();
			parent = ::tqt_cast<TQWidget*>(parent->parent());
		}
		if (!parent) return false;
		ceData.rect.rect(&x, &y, &w, &h);
		TQRect prect = parent->rect();
	
		toolbar = ::tqt_cast<TQToolBar*>(parent);
		horiz = (toolbar) ? (toolbar->orientation() == TQt::Horizontal)
			: (prect.height() < prect.width());
		TQPainter painter(widget);
		if (flatToolbar(ceData, elementFlags, toolbar)) {
			painter.fillRect(ceData.rect,
					parent->colorGroup().background());
		} else {
			drawPhaseGradient(&painter, ceData.rect,
					parent->colorGroup().background(),
					!horiz, px, py,
					prect.width(), prect.height(), true);
			if (horiz && (h==prect.height()-2)) {
			painter.setPen(parent->colorGroup().mid());
			painter.drawLine(x, h-1, w-1, h-1);
			} else if (!horiz && (w==prect.width()-2)) {
			painter.setPen(parent->colorGroup().mid());
			painter.drawLine(w-1, y, w-1, h-1);
			}
		}
		}
	
		// TQToolBarExtensionWidget
		else if (object && object->isWidgetType() && object->parent() &&
			(toolbar = ::tqt_cast<TQToolBar*>(object->parent()))) {
		if (0 == (widget = ::tqt_cast<TQWidget*>(object))) return false;
		horiz = (toolbar->orientation() == TQt::Horizontal);
		TQPainter painter(widget);
		ceData.rect.rect(&x, &y, &w, &h);
		// draw the extension
		drawPhaseGradient(&painter, ceData.rect,
				toolbar->colorGroup().background(),
				!horiz, x, y, w-1, h-1, true);
		if (horiz) {
			painter.setPen(toolbar->colorGroup().dark());
			painter.drawLine(w-1, 0, w-1, h-1);
			painter.setPen(toolbar->colorGroup().mid());
			painter.drawLine(w-2, 0, w-2, h-2);
			painter.drawLine(x, h-1, w-2, h-1);
			painter.drawLine(x, y, x, h-2);
			painter.setPen(toolbar->colorGroup().midlight());
			painter.drawLine(x+1, y, x+1, h-2);
		} else {
			painter.setPen(toolbar->colorGroup().dark());
			painter.drawLine(0, h-1, w-1, h-1);
			painter.setPen(toolbar->colorGroup().mid());
			painter.drawLine(0, h-2, w-2, h-2);
			painter.drawLine(w-1, y, w-1, h-2);
			painter.drawLine(x, y, w-2, y);
			painter.setPen(toolbar->colorGroup().midlight());
			painter.drawLine(x, y+1, w-2, y+1);
		}
		}
	
		// TQFrame lines (do this guy last)
		else if (0 != (frame = ::tqt_cast<TQFrame*>(object))) {
		TQFrame::Shape shape = frame->frameShape();
		switch (shape) {
		case TQFrame::HLine:
		case TQFrame::VLine: {
			// NOTE: assuming lines have no content
			TQPainter painter(frame);
			frame->rect().rect(&x, &y, &w, &h);
			painter.setPen(frame->colorGroup().dark());
			if (shape == TQFrame::HLine) {
			painter.drawLine(0, h/2, w, h/2);
			} else if (shape == TQFrame::VLine) {
			painter.drawLine(w/2, 0, w/2, h);
			}
			return true;
		}
		default:
			break;
		}
		}
	
	}
    }

    return false;
}

//////////////////////////////////////////////////////////////////////////////
// GradientSet                                                              //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// GradientSet()
// -------------
// Constructor

GradientSet::GradientSet(const TQColor &color, int size)
    : color_(color), size_(size)
{
    for (int n=0; n<GradientTypeCount; ++n)  set[n] = 0;
}

//////////////////////////////////////////////////////////////////////////////
// ~GradientSet()
// --------------
// Destructor

GradientSet::~GradientSet()
{
    for (int n=0; n<GradientTypeCount; ++n) if (set[n]) delete set[n];
}

//////////////////////////////////////////////////////////////////////////////
// gradient()
// ----------
// Return the appropriate gradient pixmap

KPixmap* GradientSet::gradient(bool horizontal, bool reverse)
{
    GradientType type;

    if (horizontal) {
        type = (reverse) ? HorizontalReverse : Horizontal;
    } else {
        type = (reverse) ? VerticalReverse : Vertical;
    }

    // lazy allocate
    if (!set[type]) {
        set[type] = new KPixmap();
        switch (type) {
          case Horizontal:
              set[type]->resize(size_, 16);
              KPixmapEffect::gradient(*set[type],
                                      color_.light(contrast),
                                      color_.dark(contrast),
                                      KPixmapEffect::HorizontalGradient);
              break;

          case HorizontalReverse:
              set[type]->resize(size_, 16);
              KPixmapEffect::gradient(*set[type],
                                      color_.dark(contrast),
                                      color_.light(contrast),
                                      KPixmapEffect::HorizontalGradient);
              break;

          case Vertical:
              set[type]->resize(16, size_);
              KPixmapEffect::gradient(*set[type],
                                      color_.light(contrast),
                                      color_.dark(contrast),
                                      KPixmapEffect::VerticalGradient);
              break;

          case VerticalReverse:
              set[type]->resize(16, size_);
              KPixmapEffect::gradient(*set[type],
                                      color_.dark(contrast),
                                      color_.light(contrast),
                                      KPixmapEffect::VerticalGradient);
              break;

          default:
              break;
        }
    }
    return (set[type]);
}

//////////////////////////////////////////////////////////////////////////////
// Plugin Stuff                                                             //
//////////////////////////////////////////////////////////////////////////////

class PhaseStylePlugin : public TQStylePlugin
{
 public:
    PhaseStylePlugin();
    TQStringList keys() const;
    TQStyle *create(const TQString &key);
};

PhaseStylePlugin::PhaseStylePlugin() : TQStylePlugin() { ; }

TQStringList PhaseStylePlugin::keys() const
{
    return TQStringList() << "Phase";
}

TQStyle* PhaseStylePlugin::create(const TQString& key)
{
    if (key.lower() == "phase")
        return new PhaseStyle();
    return 0;
}

TDE_EXPORT_PLUGIN(PhaseStylePlugin)

#include "phasestyle.moc"
